gitbls / sdm

Raspberry Pi SD Card Image Manager
MIT License
437 stars 47 forks source link

Steps to install zerotier using sdm #252

Closed rvaneerd closed 4 weeks ago

rvaneerd commented 1 month ago

Hi,

After successfully adding syncthing to my Pi image, I'd like to take it a step further and install zerotier: This actually takes two steps (taken from [https://www.zerotier.com/download/#entry-5]):

  1. Download / install using: curl -s https://install.zerotier.com | sudo bash or when GPG is already installed curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/main/doc/contact%40zerotier.com.gpg' | gpg --import && \ if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | sudo bash; fi
  2. Joining a predefined network (using a parameter): zerotier-cli join ################

Does one have to create a plugin for that?

Or is there a way to add these commands in appropriate steps to be included in the image?

Regards, Rob.

gitbls commented 1 month ago

The easiest way for you to accomplish this is:

The code above defers the zerotier-cli join command until the first boot of the system.

After you have your plugin edits complete, you can test it with --plugin /path/to/somewhere/myzt-plugin. Once you have it all working as you'd like, sudo copy the plugin to the /usr/local/sdm/local-plugins directory, and then you can use --plugin myzt-plugin, since sdm always looks for plugins in the local-plugins directory as well.

If you have any questions or issues on this, just post further questions on this issue. We can close thhis when you've got it rolling.

Oh, and if you do need further assistance on this, the /etc/sdm/history file will likely be invaluable in sorting things out. If everything works except for the zerotier-cli join, you'll have to look at the system journal for the first system boot.

# To see what the first boot is. Typically it will be -1 and the current boot will be 0 after the system
# finishes the first boot process
sudo journalctl --list-boots  
# Review the journal from the first boot, look for the log entries following the zerotier-cli join log entry
sudo journalctl -b -1 
rvaneerd commented 1 month ago

Ok, I (think I) understand your suggested approach. One thing that is not (yet) clear to me is how to use the variables (valid and / or required): Do I need to enclose them at both ends using the |? Am I right that for using them, I need to use two underscores for each occurrence where I use one? So if my vldargs="|zeroTier_Network|" is defined, I need to use zerotier-cli join "$zeroTier__Network" in the EOF section creating the /etc/sdm/0piboot/066-zerotier-join.sh?

gitbls commented 1 month ago

An underscore in the name should work just fine with only a single underscore in the code. The double underscores are used in sdm to replace hyphens, since hyphen is not a valid character in a bash symbol.

So:

vldargs="|xyzzy_foo|"
plugin_getargs ...
echo $xyzzy_foo  #Single underscore to reference it

vldargs="|xyzzy-foo|"
plugin_getargs ...
echo $xyzzy__foo   #Double underscore since hyphen was replaced by double underscores

And yes, enclose the vldargs list with vbars at both ends. Take a look at some of the other built-in sdm plugins. Good example: copydir, which uses both vldargs and rqdargs

rvaneerd commented 1 month ago

Ok, will experiment further and keep you posted.

rvaneerd commented 1 month ago

Just an update: After fiddling around in phase 1 as well as post-install phase, I came to the conclusion that the linked installscript for zerotier will try to start the service which didn't work.

*** Enabling and starting ZeroTier service...
Synchronizing state of zerotier-one.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable zerotier-one
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

*** Package installed but cannot start service! You may be in a Docker
*** container or using a non-standard init service.

I now managed to create the install script to run as part of the firstboot (/etc/sdm/0piboot/066-zerotier-install+join.sh) but I'm trying to get / log some output while it runs.

The other thing I've not yet completed is the joining to the network. I can after loggin in but not as part of the initial installation (during firstboot).

gitbls commented 1 month ago

Just an update: After fiddling around in phase 1 as well as post-install phase, I came to the conclusion that the linked installscript for zerotier will try to start the service which didn't work.

*** Enabling and starting ZeroTier service...
Synchronizing state of zerotier-one.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable zerotier-one
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

*** Package installed but cannot start service! You may be in a Docker
*** container or using a non-standard init service.

I now managed to create the install script to run as part of the firstboot (/etc/sdm/0piboot/066-zerotier-install+join.sh) but I'm trying to get / log some output while it runs.

The other thing I've not yet completed is the joining to the network. I can after loggin in but not as part of the initial installation (during firstboot).

Yea, some installers think they're running on a live system and try to start the service. That shouldn't be a problem unless their installer does more useful configuration before completing everything.

I just took a look at the zerotier installer code. Indeed, after the code

echo '*** Enabling and starting ZeroTier service...'

it actually enables and then starts the service. Since that's the last thing it does before exiting, you can certainly ignore the start failure.

Here are two other approaches you could consider:

Separate question: Do a lot of RasPiOS users use zerotier? If there's a sufficiently large audience (I know there is with syncthing), adding the plugin to sdm gets more interesting.

rvaneerd commented 1 month ago

I just booted my RPiZero with the image created using my personal configuration for ZeroTier(-One). I didn't have to do anything, besides authorizing the new add request from this RPi 👍 After accepting this request, I could SSH into my RPiZero (over the ZeroTier network / VPN). So the Installation went well as well as:

After fumbling with the contents of the original install script, I decided to take the approach of creating three 0piboot scripts:

  1. Installation
  2. Service related
  3. Network Join I do realize, these could have been put in a single one but this way I could manage the logging better (although........)

The only thing that I still need to accomplish is the notifications of what is going on through FirstBoot. It's an awful long time quiet as there is no sign of progress.

I noticed some use of:

gitbls commented 1 month ago

I just booted my RPiZero with the image created using my personal configuration for ZeroTier(-One). I didn't have to do anything, besides authorizing the new add request from this RPi 👍 After accepting this request, I could SSH into my RPiZero (over the ZeroTier network / VPN). So the Installation went well as well as:

  • Enabling / Starting the Service
  • Joining my ZeroTier network (Network ID provided with the build)

After fumbling with the contents of the original install script, I decided to take the approach of creating three 0piboot scripts:

  1. Installation
  2. Service related
  3. Network Join I do realize, these could have been put in a single one but this way I could manage the logging better (although........)

Why are you doing the installation at boot time when you could more easily do it at either customize or burn time? That seems strange to me, especially since it will boot faster if it does less work at boot time.

Don't know what the other two items are, but if you put them in separate scripts you'll need to name them so that the one that needs to happen first actually happens first. The scripts are run synchronously so each script should complete before the next one is started. However, if you do something asynchronously in your script (using '&') all bets are off.

The only thing that I still need to accomplish is the notifications of what is going on through FirstBoot. It's an awful long time quiet as there is no sign of progress.

What do you mean by "there is no sign of progress"? Are you saying that it hangs? If so, you'll need to figure out what is hanging it up. Best to use more logging, and also review the system journal for clues.

I noticed some use of:

  • write_console
  • bootlog Is that the approach to monitor what is going on during Firstboot?

That's what I do. Usse lots of logging. You can always remove it once you have it working.

These functions can be found in sdm-cparse, near the top of the file, if you need to review them. They're pretty simple...

gitbls commented 4 weeks ago

Closing due to lack of activity. @rvaneerd please feel free to re-open if required.