Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NFS root using unfs3 on server #10

Draft
wants to merge 1 commit into
base: nfs
Choose a base branch
from

Conversation

skoudmar
Copy link

@skoudmar skoudmar commented Dec 28, 2021

Starts the unfsd for user on get-config request and stops it on last user logout.

Yet to be done:

  • untar received root filesystem into ~/nfsroot/$NB_USER/root
  • start unfsd in new user namespace
  • add support for --nfsroot in client (replace a variable on kernel command line with the value of this option)

Comment on lines 103 to 119
local OLD_IFS=$IFS
IFS="
="

local nfs_tcp
local mount_tcp

while read -r service port
do
if [ "$service" = "NFS_TCP" ]; then
nfs_tcp=$port
elif [ "$service" = "MOUNT_TCP" ]; then
mount_tcp=$port
fi
done < $port_file

IFS=$OLD_IFS
Copy link
Author

@skoudmar skoudmar Dec 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be replaced with . $port_file, NFS_TCP and MOUNT_TCP will then be variables containing the port number.

Copy link
Owner

@wentasah wentasah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sending few comments to the current state.

@@ -114,6 +146,11 @@ run_console() {
eval "$1"
}

# Run UNFSd service if not running for NB_USER
run_unfsd() {
systemctl --user is-active novaboot-unfsd@${NB_USER:?}.service || systemctl --user start novaboot-unfsd@${NB_USER:?}.service
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think is-active is not needed here. If the service is already started, start is a no-op.

get_nfsroot() {
run_unfsd

local nfsroot_path="$HOME/tftproot/$NB_USER/root"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason, why the nfsroot is under tftproot? This means that all files in the filesystem will be accessible via tftp without any authentication.
If not, I'd prefer to use $HOME/nfsroot/$NB_USER.

@@ -89,6 +89,38 @@ read_config() {
. "${NOVABOOT_SHELL_CONFIG:-$HOME/.novaboot-shell}"
}

get_nfsroot() {
run_unfsd
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If run_unfsd is not used elsewhere, just run systemctl start ... here.


# Use the first ip address returned by the `hostname -I` command
# TODO: change to specific ip or use better method
local nfsroot_ip=`hostname -I | cut -d' ' -f1`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use $(...) rather than `...`.

And allow the user to override the address in the configuration file. This might be necessary due to NATs etc.

# TODO: change to specific ip or use better method
local nfsroot_ip=`hostname -I | cut -d' ' -f1`

local port_file="$HOME/.unfsd/$NB_USER.ports"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use $HOME/.cache/unfsd/...

mkdir -p "$HOME/tftproot"
cd "$HOME/tftproot"
mkdir -p "$HOME/tftproot/${NB_USER:?}"
cd "$HOME/tftproot/${NB_USER:?}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid that this will break my existing setups.

@@ -0,0 +1,25 @@
#!/bin/sh
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, I'd prefer not having this file at all and do all things in the .service file.


# get network from config file
. "${NOVABOOT_SHELL_CONFIG:-$HOME/.novaboot-shell}"
NETWORK=${nfs_network:?}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this script is implemented in the .service, this would have to be configured differently. Perhaps via Environment= in the .service file. User will be able to change the value via systemctl --user edit.

Or it could be configured via EnvironmentFile= and the same file would be used as ConditionPathExists=. This would be nice because no service would be started automatically before the administrator configures it.

NETWORK=${nfs_network:?}

# Generate exports file
cat > $EXPORTS_FILE <<EOF
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In .service, this would be ExecStartPre=sh -c "echo xxx > .../%i.exports"

@@ -188,7 +225,7 @@ main() {
# Commands allowed at any time
"") locked $0 default;;
"console") locked $0 console;;
"get-config") read_config && echo -n "${target_config}"; exit;;
"get-config") read_config && get_nfsroot && echo "--nfsroot=$NB_NFSROOT" && echo -n "${target_config}"; exit;;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this code to a new function get_config.

If the administrator disables the unfsd service somehow, the --nfsroot options should not be sent to the client at all.

Copy link
Owner

@wentasah wentasah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the comments below, add some short text to the documentation (novaboot-shell.pod).


if is_nfs_enabled; then
get_nfsroot
echo "--nfsroot=$NB_NFSROOT"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
echo "--nfsroot=$NB_NFSROOT"
echo "--nfsroot=$(get_nfsroot)"


local port_file="$HOME/.cache/unfsd/$NB_USER.ports"

local nfs_tcp
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's not necessary to declare it here, it can be defined local in the case, cannot it?

# TODO: change to specific ip or use better method
local nfsroot_ip=${nfs_ip:-$(hostname -I | cut -d' ' -f1)}

local port_file="$HOME/.cache/unfsd/$NB_USER.ports"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to unfsd_port_file.

esac
done < $port_file

NB_NFSROOT="$nfsroot_ip:$nfsroot_path,v3,tcp,port=${nfs_tcp:?},mountport=${mount_tcp:?}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

echo ...

fi
mkdir -p "$HOME/nfsroot/${NB_USER:?}"
cd "$HOME/nfsroot/${NB_USER:?}"
exec "$@";;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chceck that rsync cannot overwrite files in subdirectories of $HOME/nfsroot/${NB_USER:?}.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it cannot.

# Start unfsd
# -p: do not register with portmapper
# -u: use random ports
ExecStart=sh -c 'unfsd -p -u -P $NB_UNFSD_PORT_FILE -e $NB_UNFSD_EXPORT_FILE'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use sh, use variable substitution supported by systemd.

@wentasah
Copy link
Owner

Can you retarget the PR against the nfs branch (instead of master) and rebase? nfs is where I work on integrating the changes from here. If you're not experienced with rebasing and conflict resolution, we can make it together.

@skoudmar skoudmar changed the base branch from master to nfs April 27, 2022 13:12
@skoudmar skoudmar force-pushed the master branch 2 times, most recently from 15c554e to fdbfccb Compare April 28, 2022 09:01
@wentasah
Copy link
Owner

I've integrated the latest commits to the nfs branch. I still plan to work on the "untar" commit (at least add tests).

I've added support for --nfsroot and --nfsopts switches into the novaboot client (note that I've made some small changes, such as renaming .novaboot-nfsroot to .novaboot-nfs). Can you please test that version with your setup and raspberry pi?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants