Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
docs:guide-developer:procd-init-script-example [2019/03/10 16:58] – created bobafetthotmaildocs:guide-developer:procd-init-script-example [2024/02/10 17:38] (current) – [Enabling the service] systemcrash
Line 1: Line 1:
-====== Service configuration with procd======+====== Create a sample procd init script======
 <WRAP center round info 80%> <WRAP center round info 80%>
-This article is a verbatim copy of https://joostoostdijk.com/posts/service-configuration-with-procd/ any credit goes to the original author, **Joost Oostdijk** \\+This article is a mostly verbatim copy of [[https://web.archive.org/web/20220518121856/https://joostoostdijk.com/posts/service-configuration-with-procd|this archived article]], all credit goes to the original author, **Joost Oostdijk** \\ 
 +It was adapted to use an equivalent shell script instead of NodeJS JavaScript, because it's lighter and better for a simple testing setup on most OpenWrt devices.
 </WRAP> </WRAP>
  
Line 9: Line 10:
 =====Setting up===== =====Setting up=====
  
-As example, lets say we’d want to create a Node.js app as a service and that this service can be configured with a message and a timeout in order for us to be reminded to get up from ur desks once in a while. Our service name will be mynodeservice and it depends on the following script +As example, lets say we’d want to create shell script as a service and that this service can be configured with a message and a timeout in order for us to be reminded to get up from ur desks once in a while. Our service name will be myservice and it depends on the following script 
-<code javascript+<code bash
-/** +#!/bin/sh 
- /var/mynodeservice.js + 
- */ +#these if statements will check input and place default values if no input is given 
-const name = process.argv[2] |'You'; +#they will also check if input is a number so you can call  
-const every = process.argv[3|| 5000;+#this script with just a time and it will still work correctly 
 + 
 +if [ "$1" = '' ]; then 
 +    name="You" 
 +else 
 +    if echo "$1" | egrep -q '^[0-9]+$'; then 
 +        name="You" 
 +    else 
 +        name="$1" 
 +    fi 
 +fi 
 + 
 +if [ "$2" = '' ]; then 
 +    every="5" 
 +else 
 +    every="$2" 
 +fi 
 + 
 +if echo "$1" egrep -q '^[0-9]+$'; then 
 +    every="$1" 
 +fi 
 + 
 +#endless loop, will print the message every X seconds as indicated in the $every variable 
 + 
 +while ]; do  
 +    echo "Hey, $name, it's time to get up" 
 +    sleep $every 
 +done 
 + 
 +exit 0 
  
-setInterval(function(){ 
-  console.log(`Hey, ${name}, it's time to get up`); 
-}, every); 
-view raw 
 </code> </code>
  
-Place it in **/var/mynodeservice** and test it by running on OpenWrt+Place it in **/var/myscript.sh** and test it by running on OpenWrt
  
-<code>node /var/mynodeservice.js <your-name></code>+<code>/bin/sh /var/myscript.sh "Name Surname"</code>
  
 =====Creating a basic procd script===== =====Creating a basic procd script=====
  
-Now that we have a working script, we can make a service out of it. Create a file in /etc/init.d/mynodeservice with the following content+Now that we have a working script, we can make a service out of it. Create a file in /etc/init.d/myservice with the following content
 <code bash> <code bash>
 #!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
Line 37: Line 64:
 start_service() { start_service() {
     procd_open_instance     procd_open_instance
-    procd_set_param command /usr/bin/node "/var/mynodeservice.js"+    procd_set_param command /bin/sh "/var/myscript.sh"
     procd_close_instance     procd_close_instance
 } }
Line 44: Line 71:
 First, it includes the common ‘run commands’ file /etc/rc.common needed for a service. This file defines several functions that can be used to manage the service lifecycle, it supports old style init scripts as well as procd scripts. In order to tell that we want to use the new style we then set the USE_PROCD flag. First, it includes the common ‘run commands’ file /etc/rc.common needed for a service. This file defines several functions that can be used to manage the service lifecycle, it supports old style init scripts as well as procd scripts. In order to tell that we want to use the new style we then set the USE_PROCD flag.
  
-The START option basically tell the system when the service should start and stop during startup and shutdown of OpenWRT.+The START option basically tell the system when the service should start and stop during startup and shutdown of OpenWrt.
  
 This init script isn’t very useful at the moment but it shows the basic building blocks on which we will develop the script further. This init script isn’t very useful at the moment but it shows the basic building blocks on which we will develop the script further.
Line 50: Line 77:
 =====Enabling the service===== =====Enabling the service=====
  
-To tell OpenWRT that we have a new service we would need to run+To tell OpenWrt that we have a new service we would need to run
  
-<code> /etc/init.d/mynodeservice enable</code>+<code> /etc/init.d/myservice enable</code>
  
-This will install a symlink for us in directory /etc/rc.d/ called S90mynodeservice which point to our respective service script in /etc/init.d/OpenWRT will start the services according the the order of S* scripts in /etc/rc.d/. To see the order you could simply run+This will install a symlink for us in directory /etc/rc.d/ called S95myservice (because ''START=95''which points to our respective service script in /etc/init.d/OpenWrt will start the services according the the order of S* scripts in /etc/rc.d/. To see the order you could simply run
  
 <code>$ ls -la /etc/rc.d/S*</code> <code>$ ls -la /etc/rc.d/S*</code>
Line 71: Line 98:
 Testing the service Testing the service
  
-Finally, lets just test our service. Open a second shell to the OpenWRT device and run+Finally, lets just test our service. Open a second shell to the OpenWrt device and run
  
 <code>$ logread -f</code> <code>$ logread -f</code>
Line 78: Line 105:
 then enable (if you havent done that yet), and start the service. then enable (if you havent done that yet), and start the service.
  
-<code>$ /etc/init.d/mynodeservice enable +<code>$ /etc/init.d/myservice enable 
-$ /etc/init.d/mynodeservice start</code>+$ /etc/init.d/myservice start</code>
  
 After about 5 seconds we should see the message repeat itself in the log, but we didn’t… After about 5 seconds we should see the message repeat itself in the log, but we didn’t…
Line 92: Line 119:
 start_service() { start_service() {
     procd_open_instance     procd_open_instance
-    procd_set_param command /usr/bin/node "/var/mynodeservice.js"+    procd_set_param command /bin/sh "/var/myscript.sh"
     procd_set_param stdout 1     procd_set_param stdout 1
     procd_set_param stderr 1     procd_set_param stderr 1
Line 101: Line 128:
 Now, when we restart we should see something like Now, when we restart we should see something like
  
-<code bash>$ logread -f +<code>$ logread -f 
-... ommitted ... node[20136]: Hey, You, it's time to get up +... ommitted ... Hey, You, it's time to get up 
-... ommitted ... node[20136]: Hey, You, it's time to get up +... ommitted ... Hey, You, it's time to get up 
-... ommitted ... node[20136]: Hey, You, it's time to get up +... ommitted ... Hey, You, it's time to get up 
-... ommitted ... node[20136]: Hey, You, it's time to get up +... ommitted ... Hey, You, it's time to get up 
-... ommitted ... node[20136]: Hey, You, it's time to get up +... ommitted ... Hey, You, it's time to get up 
-... ommitted ... node[20136]: Hey, You, it's time to get up+... ommitted ... Hey, You, it's time to get up
 ... ...
 </code> </code>
 +
 Setting up a service simple script like above with procd already gives us some advantages Setting up a service simple script like above with procd already gives us some advantages
  
Line 117: Line 145:
 =====Service configuration===== =====Service configuration=====
  
-It’s time to get more personal, and to that we will use OpenWRTs UCI configuration interface. Create a configuration file /etc/config/mynodeservice with the following content +It’s time to get more personal, and to that we will use OpenWrts UCI configuration interface. Create a configuration file /etc/config/myservice with the following content 
-<code>config mynodeservice 'hello'+<code>config myservice 'hello'
  option name 'Joost'  option name 'Joost'
-  option every '5000'+  option every '5'
 </code> </code>
  
 UCI will immediately pick this up and the config for our service can be inspected like UCI will immediately pick this up and the config for our service can be inspected like
  
-<code>$ uci show mynodeservice +<code>$ uci show myservice 
-mynodeservice.hello=mynodeservice +myservice.hello=myservice 
-mynodeservice.hello.name=Ninja +myservice.hello.name=Joost 
-mynodeservice.hello.every='5000'+myservice.hello.every='5'
 </code> </code>
 Also single options can be requested Also single options can be requested
  
-<code>$ uci get mynodeservice.hello.name</code>+<code>$ uci get myservice.hello.name</code>
  
 and we can also change specific configuration with UCI and we can also change specific configuration with UCI
  
-<code>$ uci set mynodeservice.hello.name=Knight+<code>$ uci set myservice.hello.name=Knight
 $ uci commit</code> $ uci commit</code>
  
Line 152: Line 180:
 STOP=01 STOP=01
  
-CONFIGURATION=mynodeservice+CONFIGURATION=myservice
  
 start_service() { start_service() {
Line 166: Line 194:
  
     # pass config to script on start     # pass config to script on start
-    procd_set_param command /usr/bin/node "/var/mynodeservice.js" "$name" "$every" +    procd_set_param command /bin/sh "/var/myscript.sh" "$name" "$every" 
-    procd_set_param file /etc/config/mynodeservice+    procd_set_param file /etc/config/myservice
     procd_set_param stdout 1     procd_set_param stdout 1
     procd_set_param stderr 1     procd_set_param stderr 1
Line 176: Line 204:
 We can pass new configuration by running We can pass new configuration by running
  
-<code>$ uci set mynodeservice.hello.name=Woodrow Wilson Smith+<code>$ uci set myservice.hello.name=Woodrow Wilson Smith
 $ uci commit $ uci commit
 </code> </code>
Line 185: Line 213:
  
 <code>... <code>...
-procd_set_param file /etc/config/mynodeservice+procd_set_param file /etc/config/myservice
 ...</code> ...</code>
  
-With that line in place we are able to only restart the service whenever our configuration has changed.+With that line in place we are able to restart the service whenever only our configuration has changed.
  
-<code>$ /etc/init.d/mynodeservice reload+<code>$ /etc/init.d/myservice reload
 </code> </code>
  
Line 198: Line 226:
 I’ll list a few here, but this is by no means covering everything. I’ll list a few here, but this is by no means covering everything.
  
-  * **respawn**\\ respawn your service automatically when it died for some reason.\\ <code bash>procd_set_param respawn \+  * **respawn**\\ respawn your service automatically when it terminates for some reason.\\ <code bash>procd_set_param respawn \
       ${respawn_threshold:-3600} \       ${respawn_threshold:-3600} \
-      ${respawn_timeout:-5} ${respawn_retry:-5}</code> \\ In this example we respawn if process dies sooner than respawn_threshold, it is considered crashed and after 5 retries the service is stopped+      ${respawn_timeout:-5} ${respawn_retry:-5}</code> \\ In this example we respawn if process terminates sooner than respawn_threshold, it is considered crashed and after 5 retries the service is stopped. However, if it terminates later than respawn_threshold, it would be respawned indefinitely.
  
   * **pidfile**\\ Configure where to store the pid file \\ <code bash>procd_set_param pidfile $PIDFILE</code>   * **pidfile**\\ Configure where to store the pid file \\ <code bash>procd_set_param pidfile $PIDFILE</code>
Line 206: Line 234:
   * **env vars** \\ Pass environment variables to your process with \\ <code bash>procd_set_param env A_VAR=avalue</code>   * **env vars** \\ Pass environment variables to your process with \\ <code bash>procd_set_param env A_VAR=avalue</code>
  
-  * **ulimit** \\ If you need to set resource limits for your process you can use \\ <code bash>procd_set_param limits core="unlimited"</code> \\ To see the system wide settings for ulimt on an OpenWRT device you can run \\ <code>$ ulimit -a+  * **ulimit** \\ If you need to set resource limits for your process you can use \\ <code bash>procd_set_param limits core="unlimited"</code> \\ To see the system wide settings for ulimt on an OpenWrt device you can run \\ <code>$ ulimit -a
 -f: file size (blocks)             unlimited -f: file size (blocks)             unlimited
 -t: cpu time (seconds)             unlimited -t: cpu time (seconds)             unlimited
  • Last modified: 2019/03/10 16:58
  • by bobafetthotmail