{"id":135,"date":"2015-01-07T17:04:25","date_gmt":"2015-01-07T22:04:25","guid":{"rendered":"http:\/\/provideotech.org\/?p=135"},"modified":"2017-11-06T12:51:11","modified_gmt":"2017-11-06T17:51:11","slug":"automatically-backing-up-p5-indexes","status":"publish","type":"post","link":"https:\/\/provideotech.org\/?p=135","title":{"rendered":"Automatically backing up P5 indexes"},"content":{"rendered":"<p>Much of the truly important index data in Archiware P5 is indeed stored on tape with the data itself. \u00a0That said, ancillary information like system licensing, custom metadata and proxies, and configuration settings are often not saved. \u00a0While all of this is recoverable in the case of a true disaster, sometimes it is easier to backup the backup software itself to a different location for fast stand up in the case of a true catastrophe.<\/p>\n<p>Using python (2.6 for this script), here is a\u00a0basic script that automates this process for Mac and Linux P5 servers.<\/p>\n<p><!--more--><\/p>\n<p>Let&#8217;s break it down:<\/p>\n<p>This first section simply imports the libraries we are going to use in python and allows us to set a few simple variables, namely where P5 is installed and where we want our backups to go<\/p>\n<pre lang=\"python\" line=\"1\">\r\n#!\/usr\/bin\/env \/usr\/bin\/python\r\n\r\nimport sys\r\nimport os\r\nimport commands\r\nimport subprocess\r\nimport sys\r\nimport shutil\r\nimport time\r\n\r\n#\r\n# where does your archiware install live (no trailing slash)\r\naw_path = \"\/usr\/local\/aw\"\r\n# where do you want to backup index and log files to?\r\nbackup_path = \"\/Users\/szumlins\/Desktop\/backup\"\r\n<\/pre>\n<p>Next, we want to see if nsd (the P5 server process is running). We do this using the *nix pgrep command and looking for output. If no output is returned, we know it isn&#8217;t running and we tell variable &#8220;nr&#8221; that the software isn&#8217;t running.<\/p>\n<pre lang=\"python\" line=\"16\">\r\n# check to see if nsd is already running, if it is lets throw a flag\r\nnr = 0 \r\n# our flag\r\nif(commands.getoutput('pgrep nsd') == \"\"):\r\n\tprint \"P5 is not running\"\r\n\tnr = 1\r\n<\/pre>\n<p>Now that we know if P5 is running, we want to make sure that no jobs are active. It would be a bad idea to shut down the service in the middle of a large backup or archive!<\/p>\n<p>The first line checks if we should even do this step. If P5 isn&#8217;t running, then no jobs are running.<br \/>\nAfter this, we use the subprocess class to run a CLI call to nsdchat, P5&#8217;s CLI API asking for the name of all the jobs.<br \/>\nFollowing lines just clean up spaces and put all the jobs into an array so we can iterate against them in our next block.<\/p>\n<pre lang=\"python\" line=\"22\">\r\n# if P5 is running, lets check and make sure no jobs are running\r\nif(nr != 1):\r\n# get all the running jobs\r\n\tjobs_str = subprocess.check_output([aw_path + \"\/bin\/nsdchat\",\"-c\",\"Job\",\"names\"])\r\n\tjobs_str.rstrip()\r\n\tjobs = jobs_str.split()\r\n<\/pre>\n<p>Now that we know all the jobs, we only care about jobs that are actually running. Scheduled jobs in the future are registered as jobs even if they aren&#8217;t running.<\/p>\n<p>First, we create an iterator so we can get some metrics when we are done with our loop (i).<br \/>\nNext we enter a loop for all of the job numbers in the array we created above.<br \/>\nUsing the Job class in the P5 API, we run the status method against our job number. If that job returns &#8220;running&#8221;, we increment our iterator (i) by one.<\/p>\n<pre lang=\"python\" line=\"29\">\r\n# figure out which are running and which are stopped. We only care about running jobs\r\ni = 0\r\nfor job in jobs:\r\n\tstatus = subprocess.check_output([aw_path + \"\/bin\/nsdchat\",\"-c\",\"Job\",job,\"status\"]).rstrip()\r\n\tif status == \"running\":\r\n\t\ti = i +1\r\n<\/pre>\n<p>Now that we&#8217;ve looked at all the jobs, if all is working our (i) should be zero if it is safe to restart and should be larger if there are running jobs. We simply say that if (i) is greater than 1, send some info to the console and don&#8217;t run the shutdown process or backup process.<\/p>\n<pre lang=\"python\" line=\"36\">\r\n# if there is a running job, don't stop the service\r\nif i < 0:\r\n\tprint \"There are \" + str(i) + \" job(s) running, can't shut down service!\"\r\n\texit()\r\n<\/pre>\n<p>If P5 is running AND there are no jobs running, we can safely stop the service. We run the stop-server command and print what it is doing to the console.<\/p>\n<pre lang=\"python\" line=\"40\">\r\n#if we can shut down P5, lets do it\r\nprint \"Shutting down P5\"\r\noutput = subprocess.check_output([aw_path + \"\/stop-server\"])\r\nprint output\r\n<\/pre>\n<p>If we have gotten this far, we now know that our P5 service isn't running and it is safe to make copies of the online indexes.<\/p>\n<p>First things first, we timestamp the start process so we know how long all of this is going to take.<\/p>\n<pre lang=\"python\" line=\"44\">\r\n# Lets make a backup of the files now, first we make a stamp so we know how long it took\r\ntime_start = time.time()\r\n<\/pre>\n<p>Safety says always make a backup of your backup, so first we check to see if there is a safe previous one. If that backup directory is found, move it to a backup backup. Backup backup backup backup backup.<\/p>\n<pre lang=\"python\" line=\"46\">\r\n# Next we check to see if there is already a valid previous backup. If there is, move it to keep it safe\r\nprint \"Checking if there is existing backup\"\r\nif(os.path.isdir(backup_path + \"\/aw\")):\r\n\tprint \"Existing backup found, moving old backup\"\r\nif(os.path.isdir(backup_path + \"\/aw-old\")):\r\n\tshutil.rmtree(backup_path + \"\/aw-old\")\r\n\tshutil.move(backup_path + \"\/aw\",backup_path + \"\/aw-old\")\r\n<\/pre>\n<p>Now that we are certain that we have someplace safe to make a copy to, lets get to copying. We are copying three directories that are useful in case of a full recovery: indexes, customerconfig (server configuration), and logs.<\/p>\n<pre lang=\"python\" line=\"53\">\r\n# After we make sure we can make a new copy, we copy the proper files\r\nprint \"Making backup copy\"\r\nshutil.copytree(aw_path + \"\/config\/index\",backup_path + \"\/aw\/config\/index\",symlinks=True)\r\nshutil.copytree(aw_path + \"\/config\/customerconfig\",backup_path + \"\/aw\/config\/customerconfig\",symlinks=True)\r\nshutil.copytree(aw_path + \"\/log\",backup_path + \"\/aw\/log\",symlinks=True)\r\ntime_stop = time.time()\r\n<\/pre>\n<p>Last but not least, we calculate how long it took and start P5 back up so it can continue on its merry way.<\/p>\n<pre lang=\"python\" line=\"59\">\r\n# Then we let you know how long it took\r\nprint \"Backup took \" + str(time_stop - time_start) + \" seconds\"<\/code>\r\n\r\n# Last, we start up the server\r\noutput = subprocess.check_output([aw_path + \"\/start-server\"])\r\nprint output\r\n<\/pre>\n<p>This script does need to be run as a root user as it starts\/stops the P5 service. Permissions on the folders it creates are default to root ownership, so you may want to noodle with the script to change permissions on your backups to make them more accessible.<\/p>\n<p>Best bet would be to schedule this script to run in off hours with cron or launchd as the root user.<\/p>\n<p><b>Update 11\/6\/2017<\/b><\/p>\n<p>I've updated the script to support Python 2.6 and 2.7 as well as to provide logging.  A lot of the same methods are still in place, but the updated script is now available at <a href=\"https:\/\/github.com\/szumlins\/p5_self_backup\">https:\/\/github.com\/szumlins\/p5_self_backup<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Much of the truly important index data in Archiware P5 is indeed stored on tape with the data itself. \u00a0That said, ancillary information like system licensing, custom metadata and proxies, and configuration settings are often not saved. \u00a0While all of this is recoverable in the case of a true disaster, sometimes it is easier to &hellip; <a href=\"https:\/\/provideotech.org\/?p=135\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Automatically backing up P5 indexes&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[8,3],"tags":[],"class_list":["post-135","post","type-post","status-publish","format-standard","hentry","category-archiware-p5","category-general-info"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2bwLw-2b","_links":{"self":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts\/135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=135"}],"version-history":[{"count":0,"href":"https:\/\/provideotech.org\/index.php?rest_route=\/wp\/v2\/posts\/135\/revisions"}],"wp:attachment":[{"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/provideotech.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}