ayufan-rock64 / linux-build

Rock64 Linux build scripts, tools and instructions
MIT License
561 stars 98 forks source link

Feature request: Planning to customize image at first boot with cloud-init datasource=nocloud #311

Open deminngi opened 5 years ago

deminngi commented 5 years ago

@ayufan I am looking for a way to automatically configure a bunch of rockpro64 bionic-container images running with K8s, I want customize user (with docker group, password, network, ssh-keys, add additional packages, ... at first boot.

After reading the cloud-init doc I found nocloud as a datasource for local images. Now if I expand the kernel parameter in /boot/extlinux/extlinux.conf with:

timeout 10 menu title select kernel

label kernel-4.4.132-powder-rockchip-ayufan kernel /boot/vmlinuz-4.4.132-powder-rockchip-ayufan initrd /boot/initrd.img-4.4.132-powder-rockchip-ayufan fdt /boot/dtb-4.4.132-powder-rockchip-ayufan append rw panic=10 init=/sbin/init coherent_pool=1M ethaddr=${ethaddr} eth1addr=${eth1addr} serial=${serial#} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 root=LABEL=linux-root rootwait rootfstype=ext4 ds=nocloud;seedfrom=file:///boot/nocloud-init.cfg

set variables in nocloud-vars.cfg

#!/bin/bash

# Set cloud metadata variables
NOCLOUD_INST="rocksvrp01"
NOCLOUD_NAME="rocksvrp01"
NOCLOUD_DOMAIN="kube.local"

# Set user variables
USER_NAME="rockadmin"
USER_GROUP="rockadmin"
USER_PASS="rockadmin"
USER_HOME="/home/${USER_NAME}}"
USER_RSA_PUB="ssh-rsa AAAA......== ${USER_NAME} insecure public key"
USER_RSA_PRIV="-----BEGIN RSA PRIVATE KEY----- \
.... \
-----END RSA PRIVATE KEY-----"

# Set cloud network variables
# TODO

# Set cloud app packages
# TODO

and create nocloud-init.cfg like:

disable_ec2_metadata: True
datasource_list: [ "ConfigDrive", "None"]
datasource:
  None:
    userdata_raw: |
      #!/bin/bash

      # Execute only once
      if [ -e /boot/nocloud-init.done ]; then exit; fi

      # Exit if variables are not found
      if [ -e /boot/nocloud-vars.cfg ]; then echo "ERROR: No /boot/nocloud-vars.cfg file found! Configuration aborted."; exit 1; fi

      # Set variables in /boot/nocloud-vars.cfg
      source /boot/nocloud-vars.cfg

      groupadd "${USER_GROUP}"
      useradd -d "${USER_HOME}" -s /bin/bash -m -g "${USER_GROUP}" -G wheel,docker "${USER_NAME}"

      echo "root:root" | chpasswd
      echo "${USER_NAME}":"${USER_GROUP}" | chpasswd

      echo "${USER_NAME}        ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers.d/"${USER_NAME}"
      chmod 0440 /etc/sudoers.d/"${USER_NAME}"

      mkdir -p "${USER_HOME}"/.ssh
      echo "${USER_RSA_PUB}" > "${USER_HOME}"/.ssh/authorized_keys
      echo "${USER_RSA_PUB}" > "${USER_HOME}"/.ssh/id_rsa.pub
      echo "${USER_RSA_PRIV}" > "${USER_HOME}"/.ssh/id_rsa

      chown -R "${USER_NAME}" "${USER_HOME}"/.ssh
      chmod -R go-rwsx "${USER_HOME}"/.ssh
      chmod 600 "${USER_HOME}"/.ssh/id_rsa

      touch /boot/nocloud-init.done
    metadata:
       instance-id: "${NOCLOUD_INST}"
       local-hostname: "${NOCLOUD_INST}"."${NOCLOUD_DOMAIN}"

First start behavior is controlled by the existence of /boot/nocloud-init.done flag file

This are the packages I found on arm64

cloud-init - Init scripts for cloud instances cloud-initramfs-copymods - copy initramfs modules into root filesystem for later use cloud-initramfs-dyn-netconf - write a network interface file in /run for BOOTIF cloud-initramfs-growroot - automatically resize the root partition on first boot cloud-initramfs-rescuevol - boot off a rescue volume rather than root filesystem cloud-initramfs-rooturl - use a tarball or squashfs image in a url as the root filesystem cloud-initramfs-updateroot - extract a tarball over root filesystem before pivot

Can we use this even for customizing the image and replacing /usr/local/sbin/rock64_first_boot.sh ? Cloud-init is supported on all major distros, in our case Debian and Ubuntu is supported.

I would start to implement this feature, what do you think?

andrei-dascalu commented 4 years ago

is there anything on this? I would love to be able to provide a cloud-init user-data file to have things setup at boot but I have no idea how/if to help.