#!/bin/bash # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # # Copyright 2019 Joyent, Inc. # # # A prepare-image script for `imgadm create -s prepare-image-script ...` # for a Linux guest of a SmartOS hypervisor. See the "PREPARE IMAGE SCRIPTS" # section of `man imgadm` and Joyent's OS-2550 for details. # # Intended supported distros: CentOS (not yet tested), Debian (not yet tested), # and Ubuntu. # set -o errexit set -o pipefail # Trace logging to /tmp/prepare-image-trace.log to be partially passed back # as prepare-image:error. Note that I would have used 'prepare-image:trace' # but deployed `imgadm` is already looking for the former. TRACELOG=/tmp/prepare-image-trace.log touch $TRACELOG exec 4<> $TRACELOG export PS4='[\D{%FT%TZ}] :${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' export BASH_XTRACEFD=4 set -o xtrace export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games #---- error handling trap 'errexit $?' EXIT function fatal { echo "linux-prepare-image: fatal error: $*" exit 1 } function errexit { set +o xtrace set +o errexit set +o pipefail if [[ $1 -eq 0 ]]; then exit 0 fi echo "error exit status $1" cat $TRACELOG | tail -n50 | /usr/sbin/mdata-put prepare-image:error /usr/sbin/mdata-put prepare-image:state error fatal "error exit status $1" } #---- support routines # A wrapper around mdata-get to get values from the prepare-image namespace. function mdata_get_pi() { typeset key=$1 mdata-get "prepare-image:$key" 2>/dev/null || true } function cleanup_logs() { # This ensures we don't delete the following # /var/log/wtmp - syslog won't start if this is missin # /var/log/lastlog - sshd errors and prevents lastlog from working find /var/log -type f -exec sh -c '>{}' \; } function cleanup_homedir() { local dir=$1 if [[ ! -d $dir ]]; then return fi (cd "$dir" && rm -f \ .bash_history \ .lesshst \ .viminfo \ .ssh/authorized_keys \ .ssh/known_hosts \ .ssh/id_* \ .ssh/ssh_config ) } function cleanup_root() { # Cleaning up root account history -c history -w || true # Set or remove the root password. prepare-image:root-password-hash is only # supported on those distros that support "usermod -p ". local pw="$(mdata_get_pi root-password-hash)" if [[ -n "$pw" ]]; then usermod -p "$pw" root else passwd -d root fi # Clean up history, ssh keys, etc. cleanup_homedir /root } function cleanup_ssh() { find /etc/ssh -type f -name "ssh_host_*" | xargs rm -f } function cleanup_disks() { echo "removing /dev/vdb and cloud-init entries from fstab" sed -i -e '/^\/dev\/vdb/d' -e '/[\t|,]comment=cloudconfig[,|\t]/d' \ /etc/fstab } function cleanup_metadata() { # These files are in the centos 2.6.0 image. Not in the ubuntu or # ubuntu-certified images. rm -f /var/run/smartdc/user-script rm -f /var/lock/smartdc/user-script.lock # Per IMAGE-771: Cleanup user-data and user-script on lx-brand if [[ -f /var/db/mdata-user-data ]] ; then rm -f /var/db/mdata-user-data fi if [[ -f /var/svc/mdata-user-script ]] ; then rm -f /var/svc/mdata-user-script fi } function cleanup_hostname() { rm -f /etc/hostname touch /etc/hostname } function cleanup_machineid() { if [[ -f /etc/machine-id ]]; then cp /dev/null /etc/machine-id fi } function cleanup_network_devices() { if [[ -f /etc/udev/rules.d/70-persistent-net.rules ]] ; then rm -f /etc/udev/rules.d/70-persistent-net.rules fi if [[ -d /etc/sysconfig/network-scripts ]] ; then find /etc/sysconfig/network-scripts -name "ifcfg-eth*" | xargs rm -f fi if [[ -d /var/lib/dhcp3 ]] ; then find /var/lib/dhcp3 -type f -name "*.leases" | xargs rm -f elif [[ -d /var/lib/dhcp ]] ; then find /var/lib/dhcp -type f -name "*.leases" | xargs rm -f elif [[ -d /var/lib/dhclient ]] ; then find /var/lib/dhclient -type f -name "*.leases" | xargs rm -f fi } function cleanup_cloud_init { if [[ ! -x /usr/bin/cloud-init ]] ; then return fi # Old versions of cloud-init did not have "cloud-init clean" so this may # spit a bit of noise. if ! cloud-init clean -ls; then rm -f /var/log/cloud-init/instance rm -rf /var/log/cloud-init/instances/* fi rm -f /var/log/cloud-init* # Only clobber /etc/network/interfaces if cloud-init created it. local comment="Automatically generated by cloud-init DataSourceSmartOS" local eni=/etc/network/interfaces if [[ -f $eni ]] && grep "$comment" "$eni" >/dev/null 2>&1; then rm -f /etc/network/interfaces fi } function prepare_centos() { # Cleaning up package cache. yum clean all 2>&1 >/dev/null # TODO: Remove this? Doesn't seem necessary # Make sure locale is set to prevent error when system is SSH'ed into. localedef --no-archive -i en_US -f UTF-8 en_US.UTF-8 # Remove hostname from /etc/sysconfig/network sed -i '/^HOSTNAME=/d' /etc/sysconfig/network } function prepare_fedora() { # Cleaning up package cache dnf clean all 2>&1 >/dev/null } function prepare_ubuntu() { # Clean up package cache apt-get -y clean local fixconsole=$(mdata_get_pi fix-ubuntu-console) if [[ $fixconsole == true ]]; then cat >/etc/default/grub.d/51-smartos-serial-console.cfg <