{"id":2002,"date":"2019-03-06T13:00:33","date_gmt":"2019-03-06T13:00:33","guid":{"rendered":"https:\/\/chewett.co.uk\/blog\/?p=2002"},"modified":"2020-09-26T22:28:01","modified_gmt":"2020-09-26T21:28:01","slug":"raspberry-pi-cluster-node-12-automatic-start-with-rc-local","status":"publish","type":"post","link":"https:\/\/chewett.co.uk\/blog\/2002\/raspberry-pi-cluster-node-12-automatic-start-with-rc-local\/","title":{"rendered":"Raspberry Pi Cluster Node \u2013 12 Automatic Start with rc.local"},"content":{"rendered":"\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"678\" height=\"254\" data-attachment-id=\"2003\" data-permalink=\"https:\/\/chewett.co.uk\/blog\/2002\/raspberry-pi-cluster-node-12-automatic-start-with-rc-local\/raspi_cluster_12_automatic_start\/\" data-orig-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?fit=800%2C300&amp;ssl=1\" data-orig-size=\"800,300\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"raspi_cluster_12_automatic_start\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?fit=300%2C113&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?fit=678%2C254&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?resize=678%2C254&#038;ssl=1\" alt=\"\" class=\"wp-image-2003\" srcset=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?w=800&amp;ssl=1 800w, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?resize=300%2C113&amp;ssl=1 300w, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?resize=768%2C288&amp;ssl=1 768w, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/raspi_cluster_12_automatic_start.jpg?resize=50%2C19&amp;ssl=1 50w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/figure>\n\n\n\n<p> This post builds on&nbsp;<a href=\"https:\/\/chewett.co.uk\/blog\/1964\/raspberry-pi-cluster-node-11-automatic-slave-reconnection\/\">my previous posts in the Raspberry Pi Cluster series<\/a> by creating a script which automatically starts the slave and master with rc.local.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">What is the rc.local file?<\/h2>\n\n\n\n<p>The rc.local file is used on many Linux operating systems to schedule operations to run after services are started on the machine.<\/p>\n\n\n\n<p>On all supported operating systems the rc.local file will be run as the root user. This means that all commands in the file will be run as the root user.<\/p>\n\n\n\n<p>Typically as stated above this will be run once other services on the machine are started. However this is open to the operating system implementation. You may need to check your operating system for specifics.<\/p>\n\n\n\n<p>The Raspberry Pi default Raspbian distribution will run this once the standard system services are started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Making our python scripts runnable from the shell<\/h2>\n\n\n\n<p>Currently we have been running our python scripts by running <code>python &lt;scriptname&gt;<\/code>. This works well but to run it easier we want to launch it without running stating what python to run.<\/p>\n\n\n\n<p>First to be able to launch the script immediately from the command line is to make it executable. This can be done on Linux with the following command line:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\nchmod u+x &lt;script name&gt;\n<\/pre><\/div>\n\n\n<p>Once this is done you are able to launch the script by running <code>.\/&lt;script name&gt;<\/code>.<\/p>\n\n\n\n<p>However this will only work if the shell can detect what executable it should run it with. A hint can be given to the shell by using a shebang.<\/p>\n\n\n\n<p>This is a hint in the first line of a script to tell it which executable to run. For python files you can place the following in the top line of the file.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/env python\n<\/pre><\/div>\n\n\n<p>This tells the shell to run this file with the script <code>\/usr\/bin\/env python<\/code>.  This finds the location of python by searching the environment variables.<\/p>\n\n\n\n<p>With these two changes we will be able to launch both slave and master using the following commands.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n.\/basic_slave.py\n.\/basic_master.py\n<\/pre><\/div>\n\n\n<p>To run these scripts from the startup rc.local script we will want to change some relative references.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Changing relative file references<\/h2>\n\n\n\n<p>Currently the scripts assume that all files are located in the current working directory. When the scripts are launched under <code>rc.local<\/code> this will not be the case.<\/p>\n\n\n\n<p>One way to resolve this is to change the current working directory, to the location of the scripts before running. However a more versatile method is to load files relative to the scripts.<\/p>\n\n\n\n<p> To do this I am going to be referencing the directory of the scripts using the following code.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\nos.path.dirname(os.path.realpath(__file__))\n<\/pre><\/div>\n\n\n<p>This gets the directory that the current file is located within. Using this and <code>os.path.join()<\/code> I can reference the configuration files relative to the script directory.<\/p>\n\n\n\n<p>This then changes our config loading line, to the following:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\nconfig.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), &#039;rpicluster.cfg&#039;))\n<\/pre><\/div>\n\n\n<p>In addition to this, we want to make sure the log files are written to the correct directory. So the code to save the log files is changed too.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\nfileHandler = logging.FileHandler(os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), &quot;..&quot;, filename)))\n<\/pre><\/div>\n\n\n<p>In this case, we reference the directory above the one that the file lives in. To do this <code>..<\/code> is used to reference the directory above, and <code>os.path.abspath()<\/code> is used to simplify the path.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Adding our scripts to rc.local<\/h2>\n\n\n\n<p>Now the scripts have been changed to properly be ran from <code>rc.local<\/code> we can add the entry. To edit the rc.local I am going to use nano with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/rc.local<\/pre>\n\n\n\n<p>If you are unsure how to use nano, I suggest you read <a href=\"https:\/\/chewett.co.uk\/blog\/1933\/using-the-nano-editor-with-a-raspberry-pi\/\">my full blog post on using nano<\/a>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/home\/chewett\/pg\/RaspberryPiCluster\/12_automatic_start_rclocal\/basic_master.py 2&amp;amp;&gt;1 &gt; \/dev\/null &amp;amp;\n<\/pre><\/div>\n\n\n<p>Here we launch the basic_master.py file on startup. We redirect all standard output and error to <code>\/dev\/null<\/code> to surpress any output. Finally <code>&amp;<\/code> is added to the end of the line to launch it in the background.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Now we have our slaves running their scripts when they are booted up. This allows them to automatically join the cluster without further intervention.<\/p>\n\n\n\n<p>The full code is\u00a0<a href=\"https:\/\/github.com\/chewett\/RaspberryPiCluster\/releases\/tag\/v12.0\" target=\"_blank\" rel=\"noreferrer noopener\">available on Github<\/a>, any comments or questions can be raised there as issues or posted below.<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post builds on&nbsp;my previous posts in the Raspberry Pi Cluster series by creating a script which automatically starts the slave and master with rc.local.<\/p>\n","protected":false},"author":1,"featured_media":2005,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"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":"Today in the #RaspberryPi #Cluster series I talk about making our scripts automatically start with rc.local #DistributedComputing","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":[122],"tags":[102,184,185,37],"class_list":["post-2002","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-cluster","tag-distributed-computing","tag-python","tag-rasbian","tag-raspberry-pi"],"wppr_data":{"cwp_meta_box_check":"No"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/rpi_cluster_12_automatic_start.jpg?fit=800%2C800&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p2toWX-wi","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1964,"url":"https:\/\/chewett.co.uk\/blog\/1964\/raspberry-pi-cluster-node-11-automatic-slave-reconnection\/","url_meta":{"origin":2002,"position":0},"title":"Raspberry Pi Cluster Node \u2013 11 Automatic Slave Reconnection","author":"Chewett","date":"January 30, 2019","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by modifying the slave to automatically reconnect to the master when the connection is lost. Making the Slave automatically rejoin the master There are a lot of situations where the slave may fail to communicate with the master. These\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_11_automaic_slave_reconnection.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_11_automaic_slave_reconnection.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_11_automaic_slave_reconnection.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/01\/rpi_cluster_11_automaic_slave_reconnection.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":569,"url":"https:\/\/chewett.co.uk\/blog\/569\/creating-raspberry-pi-backup-script-scp-bash-windows\/","url_meta":{"origin":2002,"position":1},"title":"Creating a Raspberry Pi backup script with scp and Bash on Windows","author":"Chewett","date":"August 30, 2017","format":false,"excerpt":"This post describes a simple way to keep backups of a Raspberry Pi or any other Linux computer. Why do I need backups of my Raspberry Pi? Some of the nodes in my cluster are going to be compute only, meaning that they will just run what is asked of\u2026","rel":"","context":"In &quot;Informational&quot;","block_context":{"text":"Informational","link":"https:\/\/chewett.co.uk\/blog\/category\/informational\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/08\/backing_up_a_rasperry_pi.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/08\/backing_up_a_rasperry_pi.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/08\/backing_up_a_rasperry_pi.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/08\/backing_up_a_rasperry_pi.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2952,"url":"https:\/\/chewett.co.uk\/blog\/2952\/running-a-python-script-on-boot-with-systemd\/","url_meta":{"origin":2002,"position":2},"title":"Running a Python Script on Boot with Systemd","author":"Chewett","date":"August 7, 2021","format":false,"excerpt":"This short blog post details how you can run a python script on boot using systemd. Using Systemd to manage the python script Systemd is a daemon that is used to control various aspects of services and initialization scripts that run on and after boot. It is used by a\u2026","rel":"","context":"In &quot;Informational&quot;","block_context":{"text":"Informational","link":"https:\/\/chewett.co.uk\/blog\/category\/informational\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":448,"url":"https:\/\/chewett.co.uk\/blog\/448\/testing-performance-raspberry-pi\/","url_meta":{"origin":2002,"position":3},"title":"Testing the performance of a Raspberry Pi","author":"Chewett","date":"July 12, 2017","format":false,"excerpt":"I will be testing the performance of each Raspberry Pi version in my cluster. This is to determine what each one is best suited to running. To do this I need a similar set of tests to run for each and compare them. Ideally the tests will also be runnable\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":382,"url":"https:\/\/chewett.co.uk\/blog\/382\/encryption-using-veracrypt-raspberry-pi-cluster\/","url_meta":{"origin":2002,"position":4},"title":"Encryption using Veracrypt on the Raspberry Pi Cluster","author":"Chewett","date":"June 7, 2017","format":false,"excerpt":"One of the \u00a0objectives for the Raspberry Pi cluster is to manage a number of\u00a0servers including syncing their contents and backing up databases. The data included may contain personal information so they are always backed up to an encrypted drive. This means I need to be able to access the\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2739,"url":"https:\/\/chewett.co.uk\/blog\/2739\/installing-influxdb-on-a-raspberry-pi\/","url_meta":{"origin":2002,"position":5},"title":"Installing InfluxDB on a Raspberry Pi","author":"Chewett","date":"December 5, 2020","format":false,"excerpt":"Today I am writing a quick describing how you can install InfluxDB on a Raspberry Pi What is InfluxDB? InfluxDB is a relatively popular time series database that allows storing metrics and data. It is specifically designed to store and operate on data that is bound by a time component.\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/11\/raspberrypi_influxdb_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/11\/raspberrypi_influxdb_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/11\/raspberrypi_influxdb_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/11\/raspberrypi_influxdb_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/11\/raspberrypi_influxdb_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/2002","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=2002"}],"version-history":[{"count":7,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/2002\/revisions"}],"predecessor-version":[{"id":2661,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/2002\/revisions\/2661"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media\/2005"}],"wp:attachment":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=2002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=2002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=2002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}