Files
infix/src/confd/bin/bootstrap
T

267 lines
9.8 KiB
Bash
Executable File

#!/bin/sh
# Bootstrap system factory-config, failure-config and sysrepo db.
#
########################################################################
# The system factory-config and failure-config are derived from default
# settings snippets, from /usr/share/confd/factory.d, and some generated
# snippets, e.g., device unique password, hostname (based on base MAC
# address), and number of interfaces.
#
# The resulting factory-config is used to create the syrepo db (below)
# {factory} datastore. Hence, the factory-config file must match the
# the YANG models of the active image.
########################################################################
# NOTE: with the Infix defaults, a br2-external can provide a build-time
# /etc/factory-config.cfg to override the behavior of this script.
#
# This applies also for /etc/failure-config.cfg, but we recommend
# strongly that you instead provide gen-err-custom, see below.
#
# TODO: Look for statically defined factory-config, based on system's
# product ID, or just custom site-specific factory on /cfg.
########################################################################
STATUS=""
# When logging errors, generating /etc/issue* or /etc/banner (SSH)
. /etc/os-release
# /etc/confdrc controls the behavior or most of the gen-scripts,
# customize in an overlay when using Infix as an br2-external.
RC=/etc/confdrc
if [ "$1" = "-f" ] && [ -f "$2" ]; then
RC=$2
fi
if [ ! -f "$RC" ]; then
logger -sik -p user.error -t bootstrap "Missing rc file $RC" 2>/dev/null \
|| echo "Missing rc file $RC"
exit 99
fi
# shellcheck disable=SC1090
. "$RC"
# Gather all .json files in $dir, sort them numerically, and use jq
# magic to create a configuration file without duplicates. Allowing
# overrides of the Infix defaults in a br2-external.
#
# 10-foo.json -- Static Infix default
# 20-bar.json -- Generated Infix bar
# 30-config.json -- By br2-external provided gen-cfg-custom
# 30-foo.json -- Static br2-external replacing 10-foo.json
#
# Note: to override just the base hostname, used in gen-hostname, set
# BR2_TARGET_GENERIC_HOSTNAME in your br2-external's defconfig.
#
# shellcheck disable=SC2046,SC2086
collate()
{
gen=$1; shift
cfg=$1; shift
dir=$1
rm -f "$gen"
jq -s 'reduce .[] as $item ({}; . * $item)' $(find $dir -name '*.json' | sort) >"$gen"
chmod 444 "$gen"
if [ ! -f "$cfg" ]; then
cp "$gen" "$cfg"
fi
}
# Report error on console, syslog, and set login banners for getty + ssh
console_error()
{
logger -p user.crit -t bootstrap "$1"
# shellcheck disable=SC3037
/bin/echo -e "\n\n\e[31mCRITICAL BOOTSTRAP ERROR\n$1\e[0m\n" > /dev/console
[ -z "$STATUS" ] || return
STATUS="CRITICAL ERROR: $1"
printf "\n$STATUS\n" | tee -a \
/etc/banner \
/etc/issue \
/etc/issue.net \
>/dev/null
return 0
}
factory()
{
gen=$1
# Fetch defaults, simplifies sort in collate()
cp "$FACTORY_DEFAULTS_D"/* "$FACTORY_D/"
# Create an overlay for /etc/hostname to change the default in an br2-external
gen-hostname >"$FACTORY_D/20-hostname.json"
gen-motd >"$FACTORY_D/20-motd.json"
gen-hardware >"$FACTORY_D/20-hardware.json"
# shellcheck disable=SC2086
gen-interfaces $GEN_IFACE_OPTS >"$FACTORY_D/20-interfaces.json"
# Extract password for admin user from VPD
if ! gen-admin-auth infix-shell-type:bash >"$FACTORY_D/20-authentication.json"; then
console_error "Unable to create factory-config, gen-admin-auth failed"
return
fi
[ -s "$FACTORY_D/20-hostkey.json" ] || gen-hostkeys >"$FACTORY_D/20-hostkey.json"
# Optional commands (from an overlay) to run for br2-externals
[ -x "$(command -v gen-ifs-custom)" ] && gen-ifs-custom >"$FACTORY_D/20-interfaces.json"
[ -x "$(command -v gen-cfg-custom)" ] && gen-cfg-custom >"$FACTORY_D/30-config.json"
collate "$FACTORY_GEN" "$FACTORY_CFG" "$FACTORY_D"
}
failure()
{
gen=$1
# Fetch defaults, simplifies sort in collate()
cp "$FAILURE_DEFAULTS_D"/* "$FAILURE_D"
gen-hostname "$FAIL_HOSTNAME" >"$FAILURE_D/20-hostname.json"
gen-interfaces >"$FAILURE_D/20-interfaces.json"
# Same password as factory-config, but another login shell
if ! gen-admin-auth infix-shell-type:bash >"$FAILURE_D/20-authentication.json"; then
console_error "Invalid password hash in vital product data, failure-config incomplete!"
fi
[ -s "$FAILURE_D/20-hostkey.json" ] || gen-hostkeys >"$FAILURE_D/20-hostkey.json"
# Optional failure/error config to generate (or override) for br2-externals
[ -x "$(command -v gen-err-custom)" ] && gen-err-custom >"$FAILURE_D/30-error.json"
collate "$FAILURE_GEN" "$FAILURE_CFG" "$FAILURE_D"
}
factory "$FACTORY_GEN"
failure "$FAILURE_GEN"
if [ -n "$TESTING" ]; then
echo "Done."
exit 0
fi
# Drop all pre-initialized data from netopeer2 install, then re-create
# with required netopeer2 models, sysrepo implicitly installs its own,
# and then we initialize it all with our factory defaults.
rm -rf /etc/sysrepo/* /dev/shm/sr_*
mkdir -p /etc/sysrepo/
if [ -f "$FACTORY_CFG" ]; then
cp "$FACTORY_CFG" "$INIT_DATA"
else
cp "$FAILURE_CFG" "$INIT_DATA"
fi
sysrepoctl -s $SEARCH \
-i ietf-system@2014-08-06.yang -g wheel -p 0660 \
-e authentication \
-e local-users \
-e ntp \
-e ntp-udp-port \
-e timezone-name \
-i iana-timezones@2013-11-19.yang -g wheel -p 0660 \
-i nc-notifications@2008-07-14.yang -g wheel -p 0660 \
-i notifications@2008-07-14.yang -g wheel -p 0660 \
-i ietf-keystore@2019-07-02.yang -g wheel -p 0660 \
-e keystore-supported \
-e local-definitions-supported \
-e key-generation \
-i ietf-truststore@2019-07-02.yang -g wheel -p 0660 \
-e truststore-supported \
-e x509-certificates \
-i ietf-tcp-common@2019-07-02.yang -g wheel -p 0660 \
-e keepalives-supported \
-i ietf-ssh-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-tls-server@2019-07-02.yang -g wheel -p 0660 \
-e local-client-auth-supported \
-i ietf-netconf-server@2019-07-02.yang -g wheel -p 0660 \
-e ssh-listen \
-e tls-listen \
-e ssh-call-home \
-e tls-call-home \
-i ietf-interfaces@2018-02-20.yang -g wheel -p 0660 \
-e if-mib \
-i ietf-ip@2018-02-22.yang -g wheel -p 0660 \
-e ipv6-privacy-autoconf \
-i ietf-network-instance@2019-01-21.yang -g wheel -p 0660 \
-i ietf-netconf-monitoring@2010-10-04.yang -g wheel -p 0660 \
-i ietf-netconf-nmda@2019-01-07.yang -g wheel -p 0660 \
-e origin \
-e with-defaults \
-i ietf-subscribed-notifications@2019-09-09.yang \
-g wheel -p 0660 \
-e encode-xml \
-e replay \
-e subtree \
-e xpath \
-i ietf-yang-push@2019-09-09.yang -g wheel -p 0660 \
-e on-change \
-i ietf-routing@2018-03-13.yang -g wheel -p 0660 \
-i ietf-ipv6-unicast-routing@2018-03-13.yang -g wheel -p 0660 \
-i ietf-ipv4-unicast-routing@2018-03-13.yang -g wheel -p 0660 \
-i ietf-ospf@2022-10-19.yang -g wheel -p 0660 \
-e bfd \
-e explicit-router-id \
-i iana-if-type@2023-01-26.yang -g wheel -p 0660 \
-i iana-hardware@2018-03-13.yang -g wheel -p 0660 \
-i ietf-hardware@2018-03-13.yang -g wheel -p 0660 \
-e hardware-state \
-i infix-hardware@2024-04-25.yang -g wheel -p 0660 \
-i ieee802-dot1q-types@2022-10-29.yang -g wheel -p 0660 \
-i infix-ip@2023-09-14.yang -g wheel -p 0660 \
-i infix-if-type@2024-01-29.yang -g wheel -p 0660 \
-i infix-routing@2024-03-06.yang -g wheel -p 0660 \
-i infix-interfaces@2024-01-15.yang -g wheel -p 0660 \
-e vlan-filtering \
-i ieee802-dot1ab-lldp@2022-03-15.yang -g wheel -p 0660 \
-i infix-lldp@2023-08-23.yang -g wheel -p 0660 \
-i infix-dhcp-client@2024-04-12.yang -g wheel -p 0660 \
-i infix-shell-type@2023-08-21.yang -g wheel -p 0660 \
-i infix-system@2024-04-12.yang -g wheel -p 0660 \
-i infix-services@2024-04-08.yang -g wheel -p 0660 \
-i ieee802-ethernet-interface@2019-06-21.yang -g wheel -p 0660 \
-i infix-ethernet-interface@2024-02-27.yang -g wheel -p 0660 \
-I "${INIT_DATA}"
rc=$?
# Unlike `sysrepoctl -i` the `-c` command requires separate invocations.
# NOTE: we ignore any errors from these at bootstrap since sysrepo may
# already enable some of these feature, resulting in error here.
# Enable features required by netopeer2
sysrepoctl -c ietf-netconf -g wheel -p 0660 \
-e writable-running \
-e candidate \
-e rollback-on-error \
-e validate \
-e startup \
-e url \
-e xpath \
-e confirmed-commit
# Allow wheel group users (admin) to modify NACM and do factory reset
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660
sysrepoctl -c ietf-factory-default -g wheel -p 0660
sysrepoctl -c sysrepo-plugind -g wheel -p 0660
# On first boot, install factory-config as startup-config. Due to a
# limitation in sysrepo we cannot initialize ietf-netconf-acm, so we
# cheat, see sysrepo#3079
chgrp wheel /cfg
chmod g+w /cfg
if [ ! -f "$STARTUP_CFG" ]; then
sysrepocfg -f json -X"$STARTUP_CFG"
fi
# Clear running-config so we can load startup in the next step
echo "{}" > "$INIT_DATA"
sysrepocfg -f json -I"$INIT_DATA" -d running
exit $rc