|
1 | 1 | ---
|
2 |
| -title: Add Custom Boot Hook to /mnt/jrc-comms/hooks/boot.d |
| 2 | +title: Create A Custom Boot Hook |
3 | 3 | ---
|
4 | 4 |
|
5 |
| -This guide explains how to add a custom boot hook to `/mnt/jrc-comms/hooks/boot.d/` in applications that execute scripts in numerical order. Follow these steps to ensure proper execution order and functionality. |
| 5 | +If you ever need to run custom tasks during the boot process of your instances, AutoPilot provides a flexible system for adding custom boot hook scripts. |
| 6 | +These scripts allow you to execute specific commands or tasks at boot time, ensuring that your environment is configured exactly as needed. |
| 7 | + |
| 8 | +In this article, we will walk through the process of creating such scripts and explain how they integrate with the existing boot sequence. |
| 9 | +Along the way, we will cover best practices, troubleshooting tips, and an example of how to implement a custom boot hook script. |
6 | 10 |
|
7 | 11 | !!! Assumption:
|
8 |
| -We assume you have root access to modify files in `/mnt/jrc-comms/hooks/boot.d/`. |
| 12 | +You have root access and you have a shell open on your jump instance as the root user. |
9 | 13 | !!!
|
10 | 14 |
|
11 |
| -## Create Custom Boot Hook |
12 |
| - |
13 |
| -##### 1. Create Your Script |
14 |
| - |
15 |
| -Create a new shell script with a filename starting with `99-` (to ensure it runs last). For example: |
16 |
| - |
17 |
| -```bash |
18 |
| -#!/bin/bash |
19 |
| -/mnt/jrc-comms/hooks/boot.d/99-custom-task |
20 |
| - |
21 |
| -echo "Running custom boot task..." |
22 |
| -``` |
23 |
| - |
24 |
| -##### 2. Set Permissions and Ownership |
| 15 | +## Underlying Mechanism |
25 | 16 |
|
26 |
| -Make the script executable and ensure it’s owned by `root`: |
27 |
| - |
28 |
| -```bash |
29 |
| -sudo chown root:root /mnt/jrc-comms/hooks/boot.d/99-custom-task |
30 |
| -sudo chmod +x /mnt/jrc-comms/hooks/boot.d/99-custom-task |
31 |
| -``` |
| 17 | +Our platform executes a series of scripts on boot. |
| 18 | +These scripts mostly reside in `/opt/jrc/hooks/boot.d/` and are executed in numerical order based on their filenames. |
| 19 | +Before executing these scripts, the system checks for additional scripts in `/mnt/jrc-comms/hooks/boot.d/` and injects them into the execution order. |
| 20 | +If you create a script with the same filename as an existing script in `/opt/jrc/hooks/boot.d/`, it will override the original script. |
| 21 | +This allows you to extend or modify the boot process without altering the original scripts, ensuring your custom logic runs seamlessly alongside the default behavior. |
32 | 22 |
|
33 |
| -##### 3. Verify Execution Order |
34 |
| - |
35 |
| -The application runs scripts in ascending order based on their numeric prefixes. Scripts added to `/mnt/jrc-comms/hooks/boot.d` will be injected into `/opt/jrc/hooks/boot.d` based on script prefix automatically. For example: |
| 23 | +The application runs scripts in ascending order based on their numeric prefixes. Scripts added to `/mnt/jrc-comms/hooks/boot.d` will be injected into `/opt/jrc/hooks/boot.d` based on script prefix automatically. For example: |
36 | 24 |
|
37 | 25 | - `05-mount-recovery-mount` runs first (found in `/opt/jrc/hooks/boot.d`)
|
38 | 26 | - `10-cluster-clean` runs next (found in `/opt/jrc/hooks/boot.d`)
|
39 | 27 | - `99-custom-task` runs last (added to `/mnt/jrc-comms/hooks/boot.d`)
|
40 | 28 |
|
41 |
| -**Key rules:** |
42 |
| -- Prefixes determine execution order (e.g., `00-` to `99-`) |
43 |
| -- Use two-digit numbering for clarity (e.g., `05-`, `10-`, `99-`) |
44 |
| -- Scripts with the same prefix may execute in lexicographical order, but avoid ambiguity by using unique prefixes |
| 29 | +**Key guidelines:** |
| 30 | + |
| 31 | +- Prefixes determine execution order (e.g., `00-` to `99-`) |
| 32 | +- Use two-digit numbering for clarity (e.g., `05-`, `10-`, `99-`) |
| 33 | +- Scripts with the same prefix may execute in lexicographical order, but avoid ambiguity by using unique prefixes |
45 | 34 | - Scripts added to `/mnt/jrc-comms/hooks/boot.d` will persist AMI upgrades, stack clones, etc.
|
46 | 35 |
|
47 | 36 | By following this structure, you can extend the boot process with custom logic while maintaining predictable execution order.
|
| 37 | +Adding scripts to persistent storage also prevents the need to reimage instances and replace them with new AMIs. |
48 | 38 |
|
49 |
| ---- |
| 39 | +## Example: Hello World |
50 | 40 |
|
51 |
| -## Example Walkthrough |
52 |
| -To log system time at the end of the boot process: |
| 41 | +In this example, we will simply create a custom boot hook script that will log a message to the screen. |
| 42 | +First we will need to create a new file located at `/mnt/jrc-comms/hooks/boot.d/99-custom-task` with the following contents: |
53 | 43 |
|
54 | 44 | ```bash
|
55 | 45 | #!/bin/bash
|
56 |
| -/mnt/jrc-comms/hooks/boot.d/99-custom-task |
57 | 46 |
|
58 |
| -LOGFILE="/var/log/custom-boot.log" |
59 |
| -echo "Boot completed at: $(date)" >> $LOGFILE |
60 |
| -``` |
| 47 | +set -e |
61 | 48 |
|
62 |
| ---- |
| 49 | +# Import helper functions |
63 | 50 |
|
64 |
| -## Troubleshooting Tips |
| 51 | +. /opt/jrc/lib/helpers |
65 | 52 |
|
66 |
| -##### 1. **Test your script manually** before relying on the boot process: |
| 53 | +# Preform task |
| 54 | + |
| 55 | +debug "Hello World!" |
67 | 56 |
|
68 |
| -```bash |
69 |
| -sudo /mnt/jrc-comms/hooks/boot.d/99-custom-task |
70 | 57 | ```
|
71 | 58 |
|
72 |
| -##### 2. **Check logs** for errors (e.g., `/var/log/syslog` or `journalctl`) |
| 59 | +Observe the following: |
| 60 | + |
| 61 | +- The script has the prefix `99-`, which ensures it runs last in the boot sequence. |
| 62 | +- It uses `set -e` to exit immediately if any command fails, preventing further execution in case of errors. |
| 63 | +- It sources the helper functions from `/opt/jrc/lib/helpers` to utilize common utility functions like `debug`. |
| 64 | + |
| 65 | +In order for the script to execute correctly, it must have the right permissions and ownership. |
| 66 | +Each script must have the ownership of `root:root` and be executable. This is crucial for security and functionality and if not set correctly, then we refuse to run the script during the boot process. |
| 67 | + |
| 68 | +You can run the following commands to set the correct permissions and ownership to our example script: |
| 69 | + |
| 70 | +```shell |
| 71 | +chown root:root /mnt/jrc-comms/hooks/boot.d/99-custom-task |
| 72 | +chmod +x /mnt/jrc-comms/hooks/boot.d/99-custom-task |
| 73 | +``` |
73 | 74 |
|
74 |
| -##### 3. **Validate script syntax** using: |
| 75 | +You can now test that your script is running by executing it manually: |
75 | 76 |
|
76 | 77 | ```bash
|
77 |
| -bash -n /mnt/jrc-comms/hooks/boot.d/99-custom-task |
| 78 | +$ /mnt/jrc-comms/hooks/boot.d/99-custom-task |
| 79 | +DEBUG [06/06/25 16:39:27] [/mnt/jrc-comms/hooks/boot.d/99-custom-task]: Hello World! |
78 | 80 | ```
|
79 | 81 |
|
80 |
| ---- |
| 82 | +You can also test how it runs during along side the existing boot scripts by running the following command: |
81 | 83 |
|
82 |
| -## Alternative to fstab Mounting Using Boot Hook Script |
| 84 | +```bash |
| 85 | +$ run-hooks boot |
| 86 | +``` |
83 | 87 |
|
84 |
| -AutoPilot's boot hook system provides a more reliable alternative to `/etc/fstab` for bind mounts within dynamic environments, particularly when dealing with paths that might not be available during early boot stages. |
| 88 | +If all goes well, you should see your debug message printed to the console, alongside the other boot messages. |
85 | 89 |
|
86 |
| -The following is an example of how you would implement a boot hook script to create hard links. Typically this would be accomplished within `/etc/fstab`. |
| 90 | +## Example: Fstab Alternative |
87 | 91 |
|
88 |
| -### Boot Hook Script Implementation |
| 92 | +AutoPilot's boot hook system provides a more reliable alternative to `/etc/fstab` for bind mounts within dynamic environments, particularly when dealing with paths that might not be available during early boot stages. |
89 | 93 |
|
90 |
| -##### 1. Create `/mnt/jrc-comms/hooks/boot.d/99-links` Script |
| 94 | +The following is an example of how you would implement a boot hook script to create bind mounts. |
| 95 | +Typically this would be accomplished within `/etc/fstab`. |
91 | 96 |
|
92 |
| -Creates bind mounts after filesystems are available |
| 97 | +First, we will want to create the script in `/mnt/jrc-comms/hooks/boot.d/99-links` with the following contents: |
93 | 98 |
|
94 | 99 | ```bash
|
95 | 100 | #!/bin/bash
|
96 |
| -/mnt/jrc-comms/hooks/boot.d/99-links |
97 | 101 |
|
98 |
| -echo "Creating bind mounts..." |
| 102 | +set -e |
| 103 | + |
| 104 | +# Import helper functions |
| 105 | + |
| 106 | +. /opt/jrc/lib/helpers |
| 107 | + |
| 108 | +# Create bind mounts for shared directories |
| 109 | + |
| 110 | +debug "creating bind mounts..." |
99 | 111 | mount --bind /var/www/domain.com/shared/var/salesexport /home/user/salesexport
|
100 | 112 | mount --bind /var/www/domain.com/shared/media/importexport /home/user/importexport
|
101 | 113 | ```
|
102 | 114 |
|
103 |
| -##### 2. Set Permissions |
| 115 | +This script will create bind mounts on boot on all instances, alternatively you can only create these mounts on specific instances by checking the instance's roles: |
104 | 116 |
|
105 | 117 | ```bash
|
106 |
| -sudo chmod +x /mnt/jrc-comms/hooks/boot.d/99-links |
107 |
| -sudo chown root:root /mnt/jrc-comms/hooks/boot.d/99-links |
| 118 | +#!/bin/bash |
| 119 | + |
| 120 | +set -e |
| 121 | + |
| 122 | +# Import helper functions |
| 123 | + |
| 124 | +. /opt/jrc/lib/helpers |
| 125 | + |
| 126 | +# Create bind mounts for shared directories only on web and jump instances |
| 127 | + |
| 128 | +if has_roles jump || has_roles web; then |
| 129 | + debug "creating bind mounts..." |
| 130 | + mount --bind /var/www/domain.com/shared/var/salesexport /home/user/salesexport |
| 131 | + mount --bind /var/www/domain.com/shared/media/importexport /home/user/importexport |
| 132 | +else |
| 133 | + debug "skipping bind mounts for non-web/jump instance" |
| 134 | +fi |
108 | 135 | ```
|
109 | 136 |
|
110 |
| -### Verification |
| 137 | +After creating the script, ensure it has the correct permissions and ownership: |
111 | 138 |
|
112 |
| -##### 1. **Validate script syntax**: |
| 139 | +```bash |
| 140 | +chmod +x /mnt/jrc-comms/hooks/boot.d/99-links |
| 141 | +chown root:root /mnt/jrc-comms/hooks/boot.d/99-links |
| 142 | +``` |
| 143 | + |
| 144 | +You can now test the script's functionality by triggering it manually or rebooting the instance. |
| 145 | + |
| 146 | +## Troubleshooting Tips |
| 147 | + |
| 148 | +If you want to troubleshoot the boot process, you can look at the instance's logs: |
113 | 149 |
|
114 | 150 | ```bash
|
115 |
| -bash -n /mnt/jrc-comms/hooks/boot.d/99-custom-task |
| 151 | +less /var/log/cloud-init-output.log |
116 | 152 | ```
|
117 | 153 |
|
118 |
| -##### 2. **Check active mounts**: |
| 154 | +Alternatively, you can use the `cluster` command to view the boot logs for all the instances and even follow the logs in real-time: |
119 | 155 |
|
120 | 156 | ```bash
|
121 |
| -mount | grep bind |
| 157 | +cluster logs -f |
122 | 158 | ```
|
123 | 159 |
|
| 160 | +Filtering based on role is also possible, for example, to view only the logs for the `web` role: |
| 161 | + |
| 162 | +```bash |
| 163 | +cluster logs -f --role web |
| 164 | +``` |
0 commit comments