diff --git a/common/package/base-files/files/bin/config_generate b/common/package/base-files/files/bin/config_generate old mode 100755 new mode 100644 index 1deda8e2..5f4f085d --- a/common/package/base-files/files/bin/config_generate +++ b/common/package/base-files/files/bin/config_generate @@ -7,25 +7,58 @@ CFG=/etc/board.json [ -s $CFG ] || /bin/board_detect || exit 1 [ -s /etc/config/network -a -s /etc/config/system ] && exit 0 +generate_bridge() { + local name=$1 + local macaddr=$2 + uci -q batch <<-EOF + set network.$name=device + set network.$name.name=$name + set network.$name.type=bridge + EOF + if [ -n "$macaddr" ]; then + uci -q batch <<-EOF + set network.$name.macaddr=$macaddr + EOF + fi +} + +bridge_vlan_id=0 +generate_bridge_vlan() { + local name=$1_vlan + local device=$2 + local ports="$3" + local vlan="$4" + uci -q batch <<-EOF + set network.$name=bridge-vlan + set network.$name.device='$device' + set network.$name.vlan='$vlan' + set network.$name.ports='$ports' + EOF +} + generate_static_network() { uci -q batch <<-EOF delete network.loopback set network.loopback='interface' - set network.loopback.ifname='lo' + set network.loopback.device='lo' set network.loopback.proto='static' set network.loopback.ipaddr='127.0.0.1' set network.loopback.netmask='255.0.0.0' - delete network.globals - set network.globals='globals' - set network.globals.ula_prefix='auto' EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + delete network.globals + set network.globals='globals' + set network.globals.ula_prefix='auto' + EOF + } if json_is_a dsl object; then json_select dsl if json_is_a atmbridge object; then json_select atmbridge - local vpi vci encaps payload - json_get_vars vpi vci encaps payload + local vpi vci encaps payload nameprefix + json_get_vars vpi vci encaps payload nameprefix uci -q batch <<-EOF delete network.atm set network.atm='atm-bridge' @@ -33,6 +66,7 @@ generate_static_network() { set network.atm.vci='$vci' set network.atm.encaps='$encaps' set network.atm.payload='$payload' + set network.atm.nameprefix='$nameprefix' EOF json_select .. fi @@ -57,41 +91,70 @@ generate_static_network() { addr_offset=2 generate_network() { - local ifname macaddr protocol type ipaddr netmask + local ports device macaddr protocol type ipaddr netmask vlan + local bridge=$2 json_select network json_select "$1" - json_get_vars ifname macaddr protocol ipaddr netmask + json_get_vars device macaddr metric protocol ipaddr netmask vlan + json_get_values ports ports json_select .. json_select .. - [ -n "$ifname" ] || return + [ -n "$device" -o -n "$ports" ] || return - case "$1" in - # hack (see /etc/board.d/02_network) - none) return ;; - lan*) proto=${proto:-static} ;; - wan*) proto=${proto:-dhcp} ;; - esac + # Force bridge for "lan" as it may have other devices (e.g. wireless) + # bridged + [ "$1" = "lan" -a -z "$ports" ] && { + ports="$device" + } + + [ -n "$ports" -a -z "$bridge" ] && { + uci -q batch <<-EOF + add network device + set network.@device[-1].name='br-$1' + set network.@device[-1].type='bridge' + EOF + for port in $ports; do uci add_list network.@device[-1].ports="$port"; done + [ -n "$macaddr" ] && { + for port in $ports; do + uci -q batch <<-EOF + add network device + set network.@device[-1].name='$port' + set network.@device[-1].macaddr='$macaddr' + EOF + done + } + device=br-$1 + type= + macaddr="" + } + + [ -n "$bridge" ] && { + [ -z "$ports" ] && ports="$device" + if [ -z "$vlan" ]; then + bridge_vlan_id=$((bridge_vlan_id + 1)) + vlan=$bridge_vlan_id + fi + generate_bridge_vlan $1 $bridge "$ports" $vlan + device=$bridge.$vlan + type="" + } if [ -n "$macaddr" ]; then - type=macvlan # useless, only for legacy uci -q batch <<-EOF - delete network.${1}_dev - set network.${1}_dev='device' - set network.${1}_dev.name='$1' - set network.${1}_dev.type='$type' - set network.${1}_dev.ifname='$ifname' - set network.${1}_dev.macaddr='$macaddr' + add network device + set network.@device[-1].name='$device' + set network.@device[-1].macaddr='$macaddr' EOF - ifname=$1 fi uci -q batch <<-EOF delete network.$1 set network.$1='interface' set network.$1.type='$type' - set network.$1.ifname='$ifname' + set network.$1.device='$device' + set network.$1.metric='$metric' set network.$1.proto='none' EOF @@ -109,17 +172,23 @@ generate_network() { set network.$1.proto='static' set network.$1.ipaddr='$ipad' set network.$1.netmask='$netm' - set network.$1.ip6assign='60' EOF + [ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60' ;; dhcp) # fixup IPv6 slave interface if parent is a bridge - [ "$type" = "bridge" ] && ifname="br-$1" + [ "$type" = "bridge" ] && device="br-$1" - uci -q batch <<-EOF - set network.$1.proto='dhcp' - EOF + uci set network.$1.proto='dhcp' + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + delete network.${1}6 + set network.${1}6='interface' + set network.${1}6.device='$device' + set network.${1}6.proto='dhcpv6' + EOF + } ;; pppoe) @@ -127,11 +196,24 @@ generate_network() { set network.$1.proto='pppoe' set network.$1.username='username' set network.$1.password='password' - set network.$1.ipv6='1' - delete network.${1}6 - set network.${1}6='interface' - set network.${1}6.ifname='@${1}' - set network.${1}6.proto='dhcpv6' + EOF + [ -e /proc/sys/net/ipv6 ] && { + uci -q batch <<-EOF + set network.$1.ipv6='1' + delete network.${1}6 + set network.${1}6='interface' + set network.${1}6.device='@${1}' + set network.${1}6.proto='dhcpv6' + EOF + } + ;; + + ncm|\ + qmi|\ + mbim) + uci -q batch <<-EOF + set network.$1.proto='${protocol}' + set network.$1.pdptype='ipv4' EOF ;; esac @@ -206,7 +288,8 @@ generate_switch() { json_select switch json_select "$key" - json_get_vars enable reset blinkrate cpu_port + json_get_vars enable reset blinkrate cpu_port \ + ar8xxx_mib_type ar8xxx_mib_poll_interval uci -q batch <<-EOF add network switch @@ -214,6 +297,8 @@ generate_switch() { set network.@switch[-1].reset='$reset' set network.@switch[-1].enable_vlan='$enable' set network.@switch[-1].blinkrate='$blinkrate' + set network.@switch[-1].ar8xxx_mib_type='$ar8xxx_mib_type' + set network.@switch[-1].ar8xxx_mib_poll_interval='$ar8xxx_mib_poll_interval' EOF generate_switch_vlans_ports "$1" @@ -222,15 +307,15 @@ generate_switch() { json_select .. } - generate_static_system() { uci -q batch <<-EOF delete system.@system[0] add system system - set system.@system[-1].hostname='OpenMPTCProuter' - set system.@system[-1].timezone='UTC' + set system.@system[-1].hostname='OpenWrt' + set system.@system[-1].timezone='GMT0' + set system.@system[-1].zonename='UTC' set system.@system[-1].ttylogin='0' - set system.@system[-1].log_size='64' + set system.@system[-1].log_size='128' set system.@system[-1].urandom_seed='0' delete system.ntp @@ -250,6 +335,18 @@ generate_static_system() { uci -q set "system.@system[-1].hostname=$hostname" fi + local compat_version + if json_get_var compat_version compat_version; then + uci -q set "system.@system[-1].compat_version=$compat_version" + else + uci -q set "system.@system[-1].compat_version=1.0" + fi + + local timezone + if json_get_var timezone timezone; then + uci -q set "system.@system[-1].timezone=$timezone" + fi + if json_is_a ntpserver array; then local keys key json_get_keys keys ntpserver @@ -359,11 +456,12 @@ generate_led() { ;; switch) - local port_mask speed_mask - json_get_vars port_mask speed_mask + local port_mask speed_mask mode + json_get_vars port_mask speed_mask mode uci -q batch <<-EOF set system.$cfg.port_mask='$port_mask' set system.$cfg.speed_mask='$speed_mask' + set system.$cfg.mode='$mode' EOF ;; @@ -411,12 +509,24 @@ generate_gpioswitch() { json_init json_load "$(cat ${CFG})" +umask 077 + if [ ! -s /etc/config/network ]; then + bridge_name="" touch /etc/config/network generate_static_network + json_get_vars bridge + [ -n "$bridge" ] && { + json_select bridge + json_get_vars name macaddr + generate_bridge "$name" "$macaddr" + json_select .. + bridge_name=$name + } + json_get_keys keys network - for key in $keys; do generate_network $key; done + for key in $keys; do generate_network $key $bridge_name; done json_get_keys keys switch for key in $keys; do generate_switch $key; done diff --git a/common/package/base-files/files/sbin/sysupgrade b/common/package/base-files/files/sbin/sysupgrade old mode 100755 new mode 100644 index 5cf0b2bf..e51ab0b4 --- a/common/package/base-files/files/sbin/sysupgrade +++ b/common/package/base-files/files/sbin/sysupgrade @@ -4,26 +4,35 @@ . /lib/functions/system.sh . /usr/share/libubox/jshn.sh -# initialize defaults +# File-local constants +CONF_TAR=/tmp/sysupgrade.tgz +ETCBACKUP_DIR=/etc/backup +INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt +COMMAND=/lib/upgrade/do_stage2 + +# File-local globals +SAVE_OVERLAY=0 +SAVE_OVERLAY_PATH= +SAVE_PARTITIONS=1 +SAVE_INSTALLED_PKGS=0 +SKIP_UNCHANGED=0 +CONF_IMAGE= +CONF_BACKUP_LIST=0 +CONF_BACKUP= +CONF_RESTORE= +NEED_IMAGE= +HELP=0 +TEST=0 + +# Globals accessed in other files export MTD_ARGS="" export MTD_CONFIG_ARGS="" export INTERACTIVE=0 export VERBOSE=1 export SAVE_CONFIG=1 -export SAVE_OVERLAY=0 -export SAVE_OVERLAY_PATH= -export SAVE_PARTITIONS=1 -export SAVE_INSTALLED_PKGS=1 -export SKIP_UNCHANGED=0 -export CONF_IMAGE= -export CONF_BACKUP_LIST=0 -export CONF_BACKUP= -export CONF_RESTORE= -export NEED_IMAGE= -export HELP=0 +export IGNORE_MINOR_COMPAT=0 export FORCE=0 -export TEST=0 -export UMOUNT_ETCBACKUP_DIR=0 +export CONFFILES=/tmp/sysupgrade.conffiles # parse options while [ -n "$1" ]; do @@ -32,18 +41,19 @@ while [ -n "$1" ]; do -v) export VERBOSE="$(($VERBOSE + 1))";; -q) export VERBOSE="$(($VERBOSE - 1))";; -n) export SAVE_CONFIG=0;; - -c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;; - -o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;; - -p) export SAVE_PARTITIONS=0;; - -k) export SAVE_INSTALLED_PKGS=1;; - -u) export SKIP_UNCHANGED=1;; - -b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;; - -r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;; - -l|--list-backup) export CONF_BACKUP_LIST=1;; - -f) export CONF_IMAGE="$2"; shift;; + -c) SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;; + -o) SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;; + -p) SAVE_PARTITIONS=0;; + -k) SAVE_INSTALLED_PKGS=1;; + -u) SKIP_UNCHANGED=1;; + -b|--create-backup) CONF_BACKUP="$2" NEED_IMAGE=1; shift;; + -r|--restore-backup) CONF_RESTORE="$2" NEED_IMAGE=1; shift;; + -l|--list-backup) CONF_BACKUP_LIST=1;; + -f) CONF_IMAGE="$2"; shift;; -F|--force) export FORCE=1;; - -T|--test) export TEST=1;; - -h|--help) export HELP=1; break;; + -T|--test) TEST=1;; + -h|--help) HELP=1; break;; + --ignore-minor-compat-version) export IGNORE_MINOR_COMPAT=1;; -*) echo "Invalid option: $1" >&2 exit 1 @@ -53,14 +63,7 @@ while [ -n "$1" ]; do shift; done -export CONFFILES=/tmp/sysupgrade.conffiles -export CONF_TAR=/tmp/sysupgrade.tgz -export ETCBACKUP_DIR=/etc/backup -export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt - -IMAGE="$1" - -[ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && { +print_help() { cat <...] $0 [-q] [-i] [-c] [-u] [-o] [-k] @@ -80,6 +83,8 @@ upgrade-option: Verify image and config .tar.gz but do not actually flash. -F | --force Flash image even if image checks fail, this is dangerous! + --ignore-minor-compat-version + Flash image even if the minor compat version is incompatible. -q less verbose -v more verbose -h | --help display this help @@ -98,9 +103,20 @@ backup-command: sysupgrade -b. Does not create a backup file. EOF - exit 1 } +IMAGE="$1" + +if [ $HELP -gt 0 ]; then + print_help + exit 0 +fi + +if [ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 ]; then + print_help + exit 1 +fi + [ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && { cat <<-EOF -b|--create-backup and -r|--restore-backup do not perform a firmware upgrade. @@ -112,26 +128,22 @@ EOF # prevent messages from clobbering the tarball when using stdout [ "$CONF_BACKUP" = "-" ] && export VERBOSE=0 -missing_lines() { - local file1 file2 line - file1="$1" - file2="$2" - oIFS="$IFS" - IFS=":" - while read line; do - set -- $line - grep -q "^$1:" "$file2" || echo "$*" - done < "$file1" - IFS="$oIFS" -} list_conffiles() { - awk ' - BEGIN { conffiles = 0 } - /^Conffiles:/ { conffiles = 1; next } - !/^ / { conffiles = 0; next } - conffiles == 1 { print } - ' /usr/lib/opkg/status + if [ -f /usr/lib/opkg/status ]; then + awk ' + BEGIN { conffiles = 0 } + /^Conffiles:/ { conffiles = 1; next } + !/^ / { conffiles = 0; next } + conffiles == 1 { print } + ' /usr/lib/opkg/status + elif [ -d /lib/apk/packages ]; then + conffiles="" + for file in /lib/apk/packages/*.conffiles_static; do + conffiles="$(echo -e "$(cat $file)\n$conffiles")" + done + echo "$conffiles" + fi } list_changed_conffiles() { @@ -151,7 +163,7 @@ list_static_conffiles() { \( -type f -o -type l \) $filter 2>/dev/null } -add_conffiles() { +build_list_of_backup_config_files() { local file="$1" ( list_static_conffiles "$find_filter"; list_changed_conffiles ) | @@ -159,7 +171,7 @@ add_conffiles() { return 0 } -add_overlayfiles() { +build_list_of_backup_overlay_files() { local file="$1" local packagesfiles=$1.packagesfiles @@ -211,12 +223,12 @@ add_overlayfiles() { if [ $SAVE_OVERLAY = 1 ]; then [ ! -d /overlay/upper/etc ] && { - echo "Cannot find '/overlay/upper/etc', required for '-c'" >&2 + echo "Cannot find '/overlay/upper/etc', required for '-c' or '-o'" >&2 exit 1 } - sysupgrade_init_conffiles="add_overlayfiles" + sysupgrade_init_conffiles="build_list_of_backup_overlay_files" else - sysupgrade_init_conffiles="add_conffiles" + sysupgrade_init_conffiles="build_list_of_backup_config_files" fi find_filter="" @@ -230,53 +242,77 @@ fi include /lib/upgrade -do_save_conffiles() { +create_backup_archive() { local conf_tar="$1" + local disabled + local err [ "$(rootfs_type)" = "tmpfs" ] && { echo "Cannot save config while running from ramdisk." >&2 ask_bool 0 "Abort" && exit - rm -f "$conf_tar" return 0 } run_hooks "$CONFFILES" $sysupgrade_init_conffiles ask_bool 0 "Edit config file list" && vi "$CONFFILES" - if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then - echo "${INSTALLED_PACKAGES}" >> "$CONFFILES" - mkdir -p "$ETCBACKUP_DIR" - # Avoid touching filesystem on each backup - RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)" - mkdir -p "$RAMFS/upper" "$RAMFS/work" - mount -t overlay overlay -o lowerdir=$ETCBACKUP_DIR,upperdir=$RAMFS/upper,workdir=$RAMFS/work $ETCBACKUP_DIR && - UMOUNT_ETCBACKUP_DIR=1 || { - echo "Cannot mount '$ETCBACKUP_DIR' as tmpfs to avoid touching disk while saving the list of installed packages." >&2 - ask_bool 0 "Abort" && exit - } - - # Format: pkg-name{rom,overlay,unkown} - # rom is used for pkgs in /rom, even if updated later - find /usr/lib/opkg/info -name "*.control" \( \ - \( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \ - \( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \ - \( -exec echo {} unknown \; \) \ - \) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES} - fi + [ "$conf_tar" != "-" ] || conf_tar="" v "Saving config files..." [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V="" - tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null - if [ "$?" -ne 0 ]; then + sed -i -e 's,^/,,' "$CONFFILES" + set -o pipefail + { + local ret=0 + + if [ $ret -eq 0 ]; then + for service in /etc/init.d/*; do + if ! $service enabled; then + disabled="$disabled$service disable\n" + fi + done + disabled="$disabled\nexit 0" + tar_print_member "/etc/uci-defaults/10_disable_services" "$(echo -e $disabled)" || ret=1 + fi + + # Part of archive with installed packages info + if [ $ret -eq 0 ]; then + if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then + # Format: pkg-name{rom,overlay,unknown} + # rom is used for pkgs in /rom, even if updated later + if [ -d "/usr/lib/opkg/info" ]; then + tar_print_member "$INSTALLED_PACKAGES" "$(find /usr/lib/opkg/info -name "*.control" \( \ + \( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \ + \( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \ + \( -exec echo {} unknown \; \) \ + \) | sed -e 's,.*/,,;s/\.control /\t/')" || ret=1 + elif [ -d "/lib/apk/packages" ]; then + tar_print_member "$INSTALLED_PACKAGES" "$(find /lib/apk/packages -name "*.list" \( \ + \( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \ + \( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \ + \( -exec echo {} unknown \; \) \ + \) | sed -e 's,.*/,,;s/\.list /\t/')" || ret=1 + fi + fi + fi + + # Rest of archive with config files and ending padding + if [ $ret -eq 0 ]; then + tar c${TAR_V} -C / -T "$CONFFILES" || ret=1 + fi + + [ $ret -eq 0 ] + } | gzip > "${conf_tar:-/proc/self/fd/1}" + err=$? + set +o pipefail + + if [ "$err" -ne 0 ]; then echo "Failed to create the configuration backup." - rm -f "$conf_tar" - exit 1 + [ -f "$conf_tar" ] && rm -f "$conf_tar" fi - [ "$UMOUNT_ETCBACKUP_DIR" -eq 1 ] && { - umount "$ETCBACKUP_DIR" - rm -rf "$RAMFS" - } rm -f "$CONFFILES" + + return "$err" } if [ $CONF_BACKUP_LIST -eq 1 ]; then @@ -288,8 +324,8 @@ if [ $CONF_BACKUP_LIST -eq 1 ]; then fi if [ -n "$CONF_BACKUP" ]; then - do_save_conffiles "$CONF_BACKUP" - exit $? + create_backup_archive "$CONF_BACKUP" + exit fi if [ -n "$CONF_RESTORE" ]; then @@ -299,13 +335,12 @@ if [ -n "$CONF_RESTORE" ]; then fi [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V="" - cp /etc/passwd /etc/group /etc/shadow /tmp - tar -C / -x${TAR_V}zf "$CONF_RESTORE" - missing_lines /tmp/passwd /etc/passwd >> /etc/passwd - missing_lines /tmp/group /etc/group >> /etc/group - missing_lines /tmp/shadow /etc/shadow >> /etc/shadow - rm /tmp/passwd /tmp/group /tmp/shadow - + v "Restoring config files..." + if [ "$(type -t platform_restore_backup)" == 'platform_restore_backup' ]; then + platform_restore_backup "$TAR_V" + else + tar -C / -x${TAR_V}zf "$CONF_RESTORE" + fi exit $? fi @@ -363,7 +398,7 @@ if [ -n "$CONF_IMAGE" ]; then get_image "$CONF_IMAGE" "cat" > "$CONF_TAR" export SAVE_CONFIG=1 elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then - [ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR" + [ $TEST -eq 1 ] || create_backup_archive "$CONF_TAR" || exit export SAVE_CONFIG=1 else [ $TEST -eq 1 ] || rm -f "$CONF_TAR" @@ -377,8 +412,6 @@ fi install_bin /sbin/upgraded v "Commencing upgrade. Closing all shell sessions." -COMMAND='/lib/upgrade/do_stage2' - if [ -n "$FAILSAFE" ]; then printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade lock -u /tmp/.failsafe