diff --git a/lib/tiny-cloud/user-data/alpine-config b/lib/tiny-cloud/user-data/alpine-config index a54171a..d9913c7 100644 --- a/lib/tiny-cloud/user-data/alpine-config +++ b/lib/tiny-cloud/user-data/alpine-config @@ -6,6 +6,7 @@ INIT_ACTIONS_MAIN="$(insert_before create_default_user userdata_user $INIT_ACTIO INIT_ACTIONS_MAIN="$(insert_after set_hostname \ "userdata_bootcmd userdata_write_files userdata_ntp userdata_apk_cache userdata_apk_repositories userdata_package_update userdata_package_upgrade userdata_packages" \ $INIT_ACTIONS_MAIN)" +INIT_ACTIONS_MAIN="$(insert_after set_ssh_keys ssh_authorized_keys $INIT_ACTIONS_MAIN)" INIT_ACTIONS_FINAL="$INIT_ACTIONS_FINAL userdata_runcmd" get_userdata() { @@ -26,6 +27,38 @@ init__userdata_user() { CLOUD_USER="${name:-$CLOUD_USER}" } +init__ssh_authorized_keys() { + local sshkeys="$(get_userdata ssh_authorized_keys)" + if [ -z "$sshkeys" ]; then + return + fi + local user="$CLOUD_USER" + local pwent="$(getent passwd "$user")" + if [ -z "$pwent" ]; then + log -i -t "$phase" err "$ACTION: failed to find user $user" + return 1 + fi + local group=$(echo "$pwent" | cut -d: -f4) + local ssh_dir="${ROOT}$(echo "$pwent" | cut -d: -f6)/.ssh" + local keys_file="$ssh_dir/authorized_keys" + + if [ ! -d "$ssh_dir" ]; then + mkdir -p "$ssh_dir" + chmod 700 "$ssh_dir" + fi + + touch "$keys_file" + chmod 600 "$keys_file" + $MOCK chown -R "$user:$group" "$ssh_dir" + for i in $sshkeys; do + local key="$(get_userdata ssh_authorized_keys/$i)" + if [ -n "$key" ]; then + echo "$key" >> "$keys_file" + fi + done +} + + init__userdata_bootcmd() { # run bootcmd local bootcmds="$(get_userdata bootcmd)" diff --git a/tests/test_env.sh b/tests/test_env.sh index 04d3444..e274bbb 100644 --- a/tests/test_env.sh +++ b/tests/test_env.sh @@ -41,15 +41,15 @@ fake_umount() { fake_data_nocloud() { local datafile="$1" - local file="$(mktemp -p "$PWD")" - cat > "$file" + mkdir -p tmp/fake-data + cat > tmp/fake-data/"$datafile" fake_bin mount <<-EOF #!/bin/sh # find last arg which is the mount dir while ! [ -d "\$1" ]; do shift done - cp "$file" "\$1"/$datafile + cp tmp/fake-data/* "\$1"/ EOF mkdir -p mnt fake_umount diff --git a/tests/tiny-cloud-alpine.test b/tests/tiny-cloud-alpine.test index 2a0ab9c..1bf2339 100755 --- a/tests/tiny-cloud-alpine.test +++ b/tests/tiny-cloud-alpine.test @@ -15,6 +15,7 @@ init_tests \ userdata_user_name \ userdata_user_missing_name \ userdata_create_default_user \ + userdata_ssh_authorized_keys \ userdata_bootcmd \ userdata_write_files \ userdata_ntp \ @@ -122,6 +123,35 @@ userdata_create_default_user_body() { tiny-cloud main } +userdata_ssh_authorized_keys_body() { + fake_bin getent <<-EOF + #!/bin/sh + echo "alpine:x:1000:1000:Linux User,,,:/home/alpine:/bin/sh" + EOF + fake_metadata_nocloud <<-EOF + public-keys: + - openssh-key: ssh-ed25519 keydata + - openssh-key: ssh-rsa foobar + EOF + fake_userdata_nocloud <<-EOF + #alpine-config + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOIiHcbg/7ytfLFHUNLRgEAubFz/13SwXBOM/05GNZe4 user@example.com + - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA609xjvHkN8mTBiyYF6pZxMJAdy+aNZzpv+gP2dpWivJwxO7Zb9yRX6s9OKmKEj3kKRg5KQHwknSncDQ3eCljzyyer2m7ewnrAY0BrNs10o+vJfq3tsb5kZN6rZzisneHEzi5aZhmjwTItX827OaVXmIWkVHpfEVf4hVn9PuIl4AS/xtPogA/4IJrHo+DshKMaqEgII9t+/zeOEuzrSDPXDRvht768iEzGov+T4xj2LGMas9Edm/Ka4xVb5nSDZKDtXaXwshGrOxctjLZCMhT15Jdww6btrl9VltF6BLy/AJ+F1MVBjBiCjyTqaHLkuHjVQpFq2osWlDr1FrSe/S2kw== joeuser@something + EOF + atf_check -e ignore -o ignore tiny-cloud early + atf_check \ + -o ignore \ + -e match:"ssh_authorized_keys: done" \ + tiny-cloud main + atf_check -o match:"ssh-ed25519 keydata" \ + grep keydata home/alpine/.ssh/authorized_keys + atf_check -o match:"ssh-ed25519.*user@example.com" \ + grep ssh-ed25519 home/alpine/.ssh/authorized_keys + atf_check -o match:"ssh-rsa.*joeuser@something" \ + grep ssh-rsa home/alpine/.ssh/authorized_keys +} + userdata_bootcmd_body() { fake_userdata_nocloud <<-EOF #alpine-config