diff options
Diffstat (limited to 'src/init')
| -rwxr-xr-x | src/init/vyconfd.sh | 11 | ||||
| -rwxr-xr-x | src/init/vyos-router | 203 |
2 files changed, 179 insertions, 35 deletions
diff --git a/src/init/vyconfd.sh b/src/init/vyconfd.sh new file mode 100755 index 000000000..670651f57 --- /dev/null +++ b/src/init/vyconfd.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# +# Check if state file exists to determine if restart +if [ -f /var/run/vyconfd.state ]; then + echo "Restarting vyconfd from active config" + /usr/libexec/vyos/vyconf/vyconfd --log-file /var/run/log/vyconfd.log --reload-active-config --legacy-config-path +else + echo "Starting vyconfd from saved config" + touch /var/run/vyconfd.state + /usr/libexec/vyos/vyconf/vyconfd --log-file /var/run/log/vyconfd.log --legacy-config-path +fi diff --git a/src/init/vyos-router b/src/init/vyos-router index 081adf214..982126637 100755 --- a/src/init/vyos-router +++ b/src/init/vyos-router @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (C) 2021-2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -67,45 +67,65 @@ disabled () { grep -q -w no-vyos-$1 /proc/cmdline } +motd_helper() { + MOTD_DIR="/run/motd.d" + MOTD_FILE="${MOTD_DIR}/99-vyos-update-failed" + + if [[ ! -d ${MOTD_DIR} ]]; then + mkdir -p ${MOTD_DIR} + fi + + echo "" > ${MOTD_FILE} + echo "WARNING: Image update to \"$1\" failed." >> ${MOTD_FILE} + echo "Please check the logs:" >> ${MOTD_FILE} + echo "/usr/lib/live/mount/persistence/boot/$1/rw/var/log" >> ${MOTD_FILE} + echo "Message is cleared on next reboot!" >> ${MOTD_FILE} + echo "" >> ${MOTD_FILE} +} + # Load encrypted config volume mount_encrypted_config() { persist_path=$(/opt/vyatta/sbin/vyos-persistpath) if [ $? == 0 ]; then if [ -e $persist_path/boot ]; then image_name=$(cat /proc/cmdline | sed -e s+^.*vyos-union=/boot/++ | sed -e 's/ .*$//') - if [ -z "$image_name" ]; then - return + return 0 fi if [ ! -f $persist_path/luks/$image_name ]; then - return + return 0 fi - vyos_tpm_key=$(python3 -c 'from vyos.tpm import read_tpm_key; print(read_tpm_key().decode())' 2>/dev/null) + if [ ! -e /sys/class/tpm/tpm0 ]; then + echo "WARN: TPM device not found, encrypted config volume will not be automatically mounted" + echo "Use 'encryption load' to load volume manually with a key" + echo "or 'encryption disable' to decrypt volume with a key" + return 1 + fi + vyos_tpm_key=$(python3 -c 'from vyos.tpm import read_tpm_key; print(read_tpm_key().decode())' 2>/dev/null) if [ $? -ne 0 ]; then echo "ERROR: Failed to fetch encryption key from TPM. Encrypted config volume has not been mounted" echo "Use 'encryption load' to load volume with recovery key" echo "or 'encryption disable' to decrypt volume with recovery key" - return + return 1 fi echo $vyos_tpm_key | tr -d '\r\n' | cryptsetup open $persist_path/luks/$image_name vyos_config --key-file=- - if [ $? -ne 0 ]; then echo "ERROR: Failed to decrypt config volume. Encrypted config volume has not been mounted" echo "Use 'encryption load' to load volume with recovery key" echo "or 'encryption disable' to decrypt volume with recovery key" - return + return 1 fi - mount /dev/mapper/vyos_config /config mount /dev/mapper/vyos_config $vyatta_sysconfdir/config echo "Mounted encrypted config volume" fi fi + return 0 } unmount_encrypted_config() { @@ -122,7 +142,6 @@ unmount_encrypted_config() { return fi - umount /config umount $vyatta_sysconfdir/config cryptsetup close vyos_config @@ -145,6 +164,8 @@ init_bootfile () { else $vyos_libexec_dir/add-system-version.py > $BOOTFILE fi + fi + if [ -f $BOOTFILE ] ; then chgrp ${GROUP} $BOOTFILE chmod 660 $BOOTFILE fi @@ -160,20 +181,30 @@ migrate_bootfile () if [ -x $vyos_libexec_dir/run-config-migration.py ]; then log_progress_msg migrate sg ${GROUP} -c "$vyos_libexec_dir/run-config-migration.py $BOOTFILE" + STATUS=$? + if [[ "$STATUS" != "0" ]]; then + return 1 + fi # update vyconf copy after migration if [ -d $VYCONF_CONFIG_DIR ] ; then cp -f $BOOTFILE $VYCONF_CONFIG_DIR/config.boot fi fi + return 0 } # configure system-specific settings -system_config () +system_activate () { if [ -x $vyos_libexec_dir/run-config-activation.py ]; then - log_progress_msg system + log_progress_msg activate sg ${GROUP} -c "$vyos_libexec_dir/run-config-activation.py $BOOTFILE" + STATUS=$? + if [[ "$STATUS" != "0" ]]; then + return 1 + fi fi + return 0 } # load the initial config @@ -187,8 +218,13 @@ load_bootfile () fi if [ -x $vyos_libexec_dir/vyos-boot-config-loader.py ]; then sg ${GROUP} -c "$vyos_libexec_dir/vyos-boot-config-loader.py $BOOTFILE" + STATUS=$? + if [[ "$STATUS" != "0" ]]; then + return 1 + fi fi ) + return 0 } # restore if missing pre-config script @@ -283,16 +319,44 @@ bind_mount_boot () fi } +# this is called before migration and bind_mount_slash_config to check for +# upgrade data installed by legacy image update tools +copy_legacy_config_path () +{ + if [ -d /config ] ; then + if [ -f /config/.upgraded ] ; then + rm -f /config/.upgraded + cp -a /config /opt/vyatta/etc + chgrp -R vyattacfg /opt/vyatta/etc/config + chmod -R 775 /opt/vyatta/etc/config + chmod 660 /opt/vyatta/etc/config/config.boot + touch /opt/vyatta/etc/config/.vyatta_config + rm -rf /config + fi + fi +} + +bind_mount_slash_config () +{ + if [ -d /opt/vyatta/etc/config ] + then + if [ ! -d /config ] ; then + mkdir /config + fi + mount --bind /opt/vyatta/etc/config /config + fi +} + clear_or_override_config_files () { for conf in snmp/snmpd.conf snmp/snmptrapd.conf snmp/snmp.conf \ keepalived/keepalived.conf cron.d/vyos-crontab \ ipvsadm.rules default/ipvsadm resolv.conf do - if [ -s /etc/$conf ] ; then - empty /etc/$conf - chmod 0644 /etc/$conf - fi + if [ -s /etc/$conf ] ; then + empty /etc/$conf + chmod 0644 /etc/$conf + fi done } @@ -396,7 +460,10 @@ gen_duid () UUID=$(cat ${UUID_FILE} | tr -d -) fi if [ -z ${UUID} ]; then - UUID=$(uuidgen --sha1 --namespace @dns --name $(cat ${UUID_FILE_ALT}) | tr -d -) + file_alt="$(cat ${UUID_FILE_ALT})" + if [ -n "${file_alt}" ]; then + UUID=$(uuidgen --sha1 --namespace @dns --name ${file_alt} | tr -d -) + fi fi # Add DUID type4 (UUID) information DUID_TYPE="0004" @@ -417,7 +484,8 @@ gen_duid () start () { - echo -e "Initializing VyOS router\033[0m" + log_success_msg "Starting VyOS router" + # reset and clean config files security_reset || log_failure_msg "security reset failed" @@ -427,7 +495,7 @@ start () chmod 775 /var/run/vyatta /var/log/vyatta log_daemon_msg "Waiting for NICs to settle down" - # On boot time udev migth take a long time to reorder nic's, this will ensure that + # On boot time udev might take a long time to reorder nic's, this will ensure that # all udev activity is completed and all nics presented at boot-time will have their # final name before continuing with vyos-router initialization. SECONDS=0 @@ -460,6 +528,26 @@ start () nfct helper add tns inet6 tcp nft --file /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules" + # Create needed kea directories + mkdir -p /var/run/kea /run/lock/kea + chmod 750 /var/run/kea /run/lock/kea + chown _kea:_kea /var/run/kea /run/lock/kea + if [ -d /opt/vyatta/etc/config ]; then + if [ ! -d /opt/vyatta/etc/config/dhcp ]; then + mkdir /opt/vyatta/etc/config/dhcp + chmod 750 /opt/vyatta/etc/config/dhcp + chown _kea:vyattacfg /opt/vyatta/etc/config/dhcp + fi + fi + + # Ensure rsyslog is the default syslog daemon + SYSTEMD_SYSLOG="/etc/systemd/system/syslog.service" + SYSTEMD_RSYSLOG="/lib/systemd/system/rsyslog.service" + if [ ! -L ${SYSTEMD_SYSLOG} ] || [ "$(readlink -f ${SYSTEMD_SYSLOG})" != "${SYSTEMD_RSYSLOG}" ]; then + ln -sf ${SYSTEMD_RSYSLOG} ${SYSTEMD_SYSLOG} + systemctl daemon-reload + fi + # As VyOS does not execute commands that are not present in the CLI we call # the script by hand to have a single source for the login banner and MOTD ${vyos_conf_scripts_dir}/system_syslog.py || log_failure_msg "could not reset syslog" @@ -475,7 +563,7 @@ start () # enable some debugging before loading the configuration if grep -q vyos-debug /proc/cmdline; then - log_action_begin_msg "Enable runtime debugging options" + log_success_msg "Enable runtime debugging options" FRR_DEBUG=$(python3 -c "from vyos.defaults import frr_debug_enable; print(frr_debug_enable)") touch $FRR_DEBUG touch /tmp/vyos.container.debug @@ -502,7 +590,7 @@ start () && chgrp ${GROUP} ${vyatta_configdir} log_action_end_msg $? - mount_encrypted_config + mount_encrypted_config || overall_status=1 # T5239: early read of system hostname as this value is read-only once during # FRR initialisation @@ -514,11 +602,13 @@ start () # This is a safety net! systemctl start frr.service + disabled copy_legacy_config_path || copy_legacy_config_path + disabled bootfile || init_bootfile cleanup_post_commit_hooks - disabled migrate || migrate_bootfile + disabled migrate || migrate_bootfile || overall_status=1 restore_if_missing_preconfig_script @@ -526,27 +616,66 @@ start () run_postupgrade_script - update_interface_config - - disabled system_config || system_config + update_interface_config || overall_status=1 - systemctl start vyconfd.service + disabled system_activate || system_activate || overall_status=1 for s in ${subinit[@]} ; do - if ! disabled $s; then - log_progress_msg $s - if ! ${vyatta_sbindir}/${s}.init start - then log_failure_msg - exit 1 + if ! disabled $s; then + log_progress_msg $s + if ! ${vyatta_sbindir}/${s}.init start + then log_failure_msg + exit 1 + fi fi - fi done bind_mount_boot - disabled configure || load_bootfile + disabled bind_mount_slash_config || bind_mount_slash_config + + disabled configure || load_bootfile || overall_status=1 log_end_msg $? + FIRST_BOOT_FILE="/config/first_boot" + UPDATE_FAILED_BOOT_FILE="/config/update_failed" + AUTOMATIC_REBOOT_TMO=$(${vyos_libexec_dir}/read-saved-value.py --path "system option reboot-on-upgrade-failure") + # Image upgrade failed - get previous image name, re-set it as default image + # and perform an automatic reboot. Automatic reboot timeout can be set via CLI + if [[ -n $AUTOMATIC_REBOOT_TMO ]] && [[ -f ${FIRST_BOOT_FILE} ]] && [[ ${overall_status} -ne 0 ]]; then + previous_image=$(jq -r '.previous_image' ${FIRST_BOOT_FILE}) + + # If the image update failed, we need to inform the image we will revert + # to about this + running_image=$(${vyos_op_scripts_dir}/image_info.py show_images_current --raw | jq -r '.image_running') + echo "{\"failed_image_update\": \"${running_image}\"}" \ + > /usr/lib/live/mount/persistence/boot/${previous_image}/rw/${UPDATE_FAILED_BOOT_FILE} + + ${vyos_op_scripts_dir}/image_manager.py --action set --image-name "${previous_image}" >/dev/null 2>&1 + motd_helper "${running_image}" + + log_daemon_msg "Booting failed, reverting to previous image" + log_progress_msg ${previous_image} + log_end_msg 0 + log_daemon_msg "Automatic reboot in ${AUTOMATIC_REBOOT_TMO} minutes" + sync ; shutdown --reboot --no-wall ${AUTOMATIC_REBOOT_TMO} >/dev/null 2>&1 + log_progress_msg "Use \"reboot cancel\" to cancel" + log_end_msg 0 + fi + # After image upgrade failure and once booted into the previous working + # image, inform the user via MOTD about the failure + if [[ -n $AUTOMATIC_REBOOT_TMO ]] && [[ -f ${UPDATE_FAILED_BOOT_FILE} ]] ; then + failed_image_update=$(jq -r '.failed_image_update' ${UPDATE_FAILED_BOOT_FILE}) + motd_helper "${failed_image_update}" + fi + # Clear marker files used by automatic reboot on image upgrade mechanism + if [[ -f ${FIRST_BOOT_FILE} ]]; then + rm -f ${FIRST_BOOT_FILE} + fi + if [[ -f ${UPDATE_FAILED_BOOT_FILE} ]] ; then + rm -f ${UPDATE_FAILED_BOOT_FILE} + fi + telinit q chmod g-w,o-w / @@ -559,13 +688,18 @@ start () fi # Start netplug daemon - systemctl start netplug.service + systemctl start vyos-netlinkd.service } stop() { local -i status=0 log_daemon_msg "Stopping VyOS router" + + # As vyos-netlinkd consumes a configuration, we need to stop it prior + # unmounting /config + systemctl stop vyos-netlinkd.service + for ((i=${#sub_inits[@]} - 1; i >= 0; i--)) ; do s=${subinit[$i]} log_progress_msg $s @@ -577,7 +711,6 @@ stop() umount ${vyatta_configdir} log_action_end_msg $? - systemctl stop netplug.service systemctl stop vyconfd.service systemctl stop frr.service |
