#!/bin/bash # Rebuild upstream pre-built tinyipa it to be usable with ansible-deploy. # # Downloads the pre-built tinyipa ramdisk from tarballs.openstack.org or # rebuilds a ramdisk under path set as TINYIPA_RAMDISK_FILE shell var. # During rebuild this script installs and configures OpenSSH server if needed # and makes required changes for Ansible + Python to work in compiled/optimized # Python environment. # # By default, id_rsa or id_dsa keys of the user performing the build # are baked into the image as authorized_keys for 'tc' user. # To supply different public ssh key, befor running this script set # SSH_PUBLIC_KEY environment variable to point to absolute path to the key. # # This script produces "ansible-" ramdisk that can serve # as ramdisk for both ansible-deploy driver and agent-based Ironic drivers, set -ex WORKDIR=$(readlink -f $0 | xargs dirname) REBUILDDIR="$WORKDIR/tinyipaaddssh" DST_DIR=$REBUILDDIR source ${WORKDIR}/common.sh TINYCORE_MIRROR_URL=${TINYCORE_MIRROR_URL:-} BRANCH_PATH=${BRANCH_PATH:-master} TINYIPA_RAMDISK_FILE=${TINYIPA_RAMDISK_FILE:-} SSH_PUBLIC_KEY=${SSH_PUBLIC_KEY:-} SSHD_CONFIG_PATH="/usr/local/etc/ssh/sshd_config" SSH_RSA_KEY_PATH="/usr/local/etc/ssh/ssh_host_rsa_key" SSH_DSA_KEY_PATH="/usr/local/etc/ssh/ssh_host_dsa_key" SSH_ED25519_KEY_PATH="/usr/local/etc/ssh/ssh_host_ed25519_key" function validate_params { echo "Validating location of public SSH key" if [ -n "$SSH_PUBLIC_KEY" ]; then if [ -r "$SSH_PUBLIC_KEY" ]; then _found_ssh_key="$SSH_PUBLIC_KEY" fi else for fmt in rsa dsa; do if [ -r "$HOME/.ssh/id_$fmt.pub" ]; then _found_ssh_key="$HOME/.ssh/id_$fmt.pub" break fi done fi if [ -z $_found_ssh_key ]; then echo "Failed to find neither provided nor default SSH key" exit 1 fi } function get_tinyipa { if [ -z $TINYIPA_RAMDISK_FILE ]; then mkdir -p $WORKDIR/build_files/cache cd $WORKDIR/build_files/cache wget -N https://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa${BRANCH_EXT}.gz TINYIPA_RAMDISK_FILE="$WORKDIR/build_files/cache/tinyipa${BRANCH_EXT}.gz" fi } function unpack_ramdisk { if [ -d "$REBUILDDIR" ]; then sudo rm -rf "$REBUILDDIR" fi mkdir -p "$REBUILDDIR" # Extract rootfs from .gz file ( cd "$REBUILDDIR" && zcat "$TINYIPA_RAMDISK_FILE" | sudo cpio -i -H newc -d ) } function install_ssh { if [ ! -f "${REBUILDDIR}${SSHD_CONFIG_PATH}" ]; then # tinyipa was built without SSH server installed # Install and configure bare minimum for SSH access $TC_CHROOT_CMD tce-load -wic openssh # Configure OpenSSH $CHROOT_CMD cp ${SSHD_CONFIG_PATH}.orig $SSHD_CONFIG_PATH echo "PasswordAuthentication no" | $CHROOT_CMD tee -a $SSHD_CONFIG_PATH # Generate and configure host keys - RSA, DSA, Ed25519 # NOTE(pas-ha) ECDSA host key will still be re-generated fresh on every image boot $CHROOT_CMD ssh-keygen -q -t rsa -N "" -f $SSH_RSA_KEY_PATH $CHROOT_CMD ssh-keygen -q -t dsa -N "" -f $SSH_DSA_KEY_PATH $CHROOT_CMD ssh-keygen -q -t ed25519 -N "" -f $SSH_ED25519_KEY_PATH echo "HostKey ${SSH_RSA_KEY_PATH}" | $CHROOT_CMD tee -a $SSHD_CONFIG_PATH echo "HostKey ${SSH_DSA_KEY_PATH}" | $CHROOT_CMD tee -a $SSHD_CONFIG_PATH echo "HostKey ${SSH_ED25519_KEY_PATH}" | $CHROOT_CMD tee -a $SSHD_CONFIG_PATH fi # setup new user SSH keys anyway $CHROOT_CMD mkdir -p /home/tc $CHROOT_CMD chown -R tc.staff /home/tc $TC_CHROOT_CMD mkdir -p /home/tc/.ssh cat $_found_ssh_key | $TC_CHROOT_CMD tee /home/tc/.ssh/authorized_keys $CHROOT_CMD chown tc.staff /home/tc/.ssh/authorized_keys $TC_CHROOT_CMD chmod 600 /home/tc/.ssh/authorized_keys } function fix_python_optimize { if grep -q "PYTHONOPTIMIZE=1" "$REBUILDDIR/opt/bootlocal.sh"; then # tinyipa was built with optimized Python environment, apply fixes echo "PYTHONOPTIMIZE=1" | $TC_CHROOT_CMD tee -a /home/tc/.ssh/environment echo "PermitUserEnvironment yes" | $CHROOT_CMD tee -a $SSHD_CONFIG_PATH echo 'Defaults env_keep += "PYTHONOPTIMIZE"' | $CHROOT_CMD tee -a /etc/sudoers fi } function rebuild_ramdisk { # Rebuild build directory into gz file ansible_basename="ansible-$(basename $TINYIPA_RAMDISK_FILE)" ( cd "$REBUILDDIR" && sudo find | sudo cpio -o -H newc | gzip -9 > "$WORKDIR/${ansible_basename}" ) # Output file created by this script and its size cd "$WORKDIR" echo "Produced files:" du -h "${ansible_basename}" } sudo -v validate_params get_tinyipa unpack_ramdisk setup_tce "$DST_DIR" # NOTE (pas-ha) default tinyipa is built without SSH access, enable it here install_ssh # NOTE(pas-ha) default tinyipa is built with PYOPTIMIZE_TINYIPA=true and # for Ansible+python to work we need to ensure that PYTHONOPTIMIZE=1 is # set for all sessions from 'tc' user including those that are escalated # with 'sudo' afterwards fix_python_optimize cleanup_tce "$DST_DIR" rebuild_ramdisk