diff --git a/LICENSE b/LICENSE index 5d6e4b6..ba9fe31 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013 Joyent, Inc. All rights reserved. +Copyright (c) 2017 Joyent, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/includes/00-mdata.sh b/includes/00-mdata.sh index 19c14c0..667c16c 100644 --- a/includes/00-mdata.sh +++ b/includes/00-mdata.sh @@ -1,17 +1,5 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -if [ -x /usr/sbin/mdata-get ]; then - HAS_METADATA=yes - - log "waiting for metadata to show up" - - until [ -e /.zonecontrol/metadata.sock ] ||\ - [ -e /var/run/smartdc/metadata.sock ] ||\ - [ $((MCOUNT++)) -gt 30 ]; do - sleep 1 - done - - [ -e /.zonecontrol/metadata.sock ] ||\ - [ -e /var/run/smartdc/metadata.sock ] ||\ - log "metadata failed to show up" -fi +log 'waiting for metadata to show up' +/usr/vm/sbin/filewait /.zonecontrol/metadata.sock diff --git a/includes/01-reboot-file.sh b/includes/01-reboot-file.sh index 6bcd6dd..b22b1e4 100644 --- a/includes/01-reboot-file.sh +++ b/includes/01-reboot-file.sh @@ -1,4 +1,15 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -# create a temporary file that disappears on the first reboot -touch /tmp/.FIRST_REBOOT_NOT_YET_COMPLETE +# A zone should reboot if features.reboot is true, or if the call to json +# fails. This way, we are backwards-compatible with versions of zoneinit that +# do not have zoneinit.json +shouldreboot=$(json -f "$ZONEINIT_DIR/zoneinit.json" features.reboot) +if (($? != 0)) || [[ $shouldreboot == true ]]; then + ZONE_SHOULD_REBOOT=true + + # create a temporary file that disappears on the first reboot + touch /tmp/.FIRST_REBOOT_NOT_YET_COMPLETE +else + ZONE_SHOULD_REBOOT=false +fi diff --git a/includes/02-config.sh b/includes/02-config.sh index 1ca907e..e283500 100644 --- a/includes/02-config.sh +++ b/includes/02-config.sh @@ -1,114 +1,69 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -log "determine machine parameters and configuration" +log 'determine machine parameters and configuration' # Little helper to overcome the problem that mdata-get doesn't use stderr mdata() { - set -o pipefail - output=$(mdata-get $1 2>/dev/null) && echo -e "${output}" || return 1 + local output + output=$(mdata-get "$1" 2>/dev/null) + if (($? == 0)); then + echo "$output" + else + return 1 + fi } -log "checking for duplicate IPs" +# List nics +mdata-nics() { + mdata sdc:nics \ + | json -d '|' -e 'this.ips = this.ips && this.ips.join(",")' \ + -a interface ip ips nic_tag +} +log 'checking for duplicate IPs' if ifconfig -a | grep DUP >/dev/null ; then - log "provisioned with IP already in use, shutting down." - halt -fi - -( [ ${HAS_METADATA} ] && mdata sdc:uuid >/dev/null ) || USE_ZONECONFIG=yes - -if [ ! ${USE_ZONECONFIG} ]; then - - # This is a recent enough platform to use metadata to retrieve all - # information we need for provisioning - - ZONENAME=$(mdata sdc:zonename) - HOSTNAME=$(mdata sdc:hostname || echo "${ZONENAME}") - DOMAINNAME=$(mdata sdc:dns_domain || echo "local") - - unset i - while : ${i:=-1}; ((i++)); SERVER=$(mdata sdc:resolvers.${i}); [ ${SERVER} ]; do - RESOLVERS=(${RESOLVERS[@]} ${SERVER}) - done - - RAM_IN_BYTES=$(echo "$(mdata sdc:max_physical_memory)*1024^2" | bc 2>/dev/null) - SWAP_IN_BYTES=$(echo "$(mdata sdc:max_swap)*1024^2" | bc 2>/dev/null) - TMPFS=$(mdata sdc:tmpfs || echo "$((RAM_IN_BYTES/1024/1024))")m - - # We want to fail if anything in the pipe fails during this step - set -o pipefail - /usr/sbin/mdata-get sdc:nics \ - | /usr/bin/json -d '|' -e 'this.ips = this.ips && this.ips.join(",")' \ - -a interface ip ips nic_tag \ - | while IFS='|' read IFACE IP IPS NIC_TAG; do - NET_INTERFACES=(${NET_INTERFACES[@]} ${IFACE}) - - [[ -z $IPS ]] && IPS=$IP - - OLDIFS=$IFS - IFS=',' - for THIS_IP in $IPS; do - # strip prefix length and only use valid IPv4 addresses - [[ "${THIS_IP%/*}." =~ ^(([01]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){4}$ ]] || continue - eval "${IFACE}_IP=${THIS_IP}" - case $NIC_TAG in - external) - PUBLIC_IPS=(${PUBLIC_IPS[@]} ${THIS_IP}) - ;; - *) - PRIVATE_IPS=(${PRIVATE_IPS[@]} ${THIS_IP}) - ;; - esac - done - IFS=$OLDIFS - done - set +o pipefail - - # Pick a valid IP for either of the public/private vars, fall back to localhost - PUBLIC_IP="${PUBLIC_IPS[0]}" - PRIVATE_IP="${PRIVATE_IPS[0]}" - LOCAL_IP="$(ifconfig lo0 | awk '{if ($1=="inet") print $2}')" - -else - - # This seems to be an older release of SmartOS, or SDC 6.5.x - # We cannot source the information we need from metadata, so - # need the 'zoneconfig' file passed with some information. - - if [ -f "${ZONECONFIG}" ]; then - source ${ZONECONFIG} - fi - - : ${ZONENAME:=$(zonename)} - : ${HOSTNAME:=${ZONENAME}} - : ${DOMAINNAME:=local} - - [ ${RAM_IN_BYTES} ] || RAM_IN_BYTES=$( kstat -p -c zone_memory_cap -s physcap | awk '{print $2}' ) - [ ${RAM_IN_BYTES} -gt 0 2>/dev/null ] || RAM_IN_BYTES=134217728 - log "zone physical memory cap determined as $((RAM_IN_BYTES/1024/1024)) MiB" - - [ ${SWAP_IN_BYTES} ] || SWAP_IN_BYTES=$( kstat -p -c zone_memory_cap -s swapcap | awk '{print $2}' ) - [ ${SWAP_IN_BYTES} -gt 0 2>/dev/null ] || SWAP_IN_BYTES=$((RAM_IN_BYTES*2)) - log "zone virtual memory cap determined as $((SWAP_IN_BYTES/1024/1024)) MiB" - - [ ${TMPFS} ] || TMPFS=$((RAM_IN_BYTES/1024/1024))m - - unset i - while : ${i:=-1}; ((i++)); IFACE=NET${i}_INTERFACE; [ ${!IFACE} ]; do - NET_INTERFACES=(${NET_INTERFACES[@]} ${!IFACE}) - eval "${!IFACE}_IP=\${NET${i}_IP}" - done - - # We should already have PUBLIC_IP & PRIVATE_IP set via zoneconfig - - PUBLIC_IPS=(${PUBLIC_IP}) - PRIVATE_IPS=(${PRIVATE_IP}) - RESOLVERS=(${RESOLVERS}) - + log 'provisioned with IP already in use, shutting down.' + halt fi -# Make sure *some* resolvers are used -[ ${#RESOLVERS[@]} -gt 0 ] || RESOLVERS=(8.8.8.8 8.8.4.4) +declare -A INTERFACE_IPS +PUBLIC_IPS=() +PRIVATE_IPS=() + +ZONENAME=$(mdata sdc:zonename || zonename) +HOSTNAME=$(mdata sdc:hostname || echo "$ZONENAME") +DOMAINNAME=$(mdata sdc:dns_domain || echo 'local') + +RAM_IN_BYTES=$(($(mdata sdc:max_physical_memory) * 1024 * 1024)) +SWAP_IN_BYTES=$(($(mdata sdc:max_swap) * 1024 * 1024)) +TMPFS=$(mdata sdc:tmpfs || echo "$((RAM_IN_BYTES/1024/1024))")m + +while IFS='|' read -r iface ip ips nic_tag; do + [[ -z $ips ]] && ips=$ip + + OLDIFS=$IFS + IFS=',' + for this_ip in $ips; do + # strip prefix length and only use valid IPv4 addresses + [[ "${this_ip%/*}." =~ ^(([01]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){4}$ ]] || continue + INTERFACE_IPS[$iface]=$this_ip + case "$nic_tag" in + external) + PUBLIC_IPS+=("$this_ip") + ;; + *) + PRIVATE_IPS+=("$this_ip") + ;; + esac + done + IFS=$OLDIFS +done < <(mdata-nics) + +# Pick a valid IP for either of the public/private vars, fall back to localhost +PUBLIC_IP=${PUBLIC_IPS[0]} +PRIVATE_IP=${PRIVATE_IPS[0]} +LOCAL_IP=$(ifconfig lo0 | awk '{if ($1=="inet") print $2}') # Use mdata-get to retrieve passwords for users needed by the image # put them in respective variables (e.g. for 'admin' use $ADMIN_PW) @@ -117,17 +72,16 @@ fi : ${USERS=admin root} USERS=(${USERS}) -for USER in ${USERS[@]}; do - PASS_VAR_LOWER=${USER}_pw - PASS_VAR_UPPER=$(echo ${PASS_VAR_LOWER} | tr '[a-z]' '[A-Z]') - - if [ ${HAS_METADATA} ]; then - USER_PW="$(mdata ${PASS_VAR_LOWER})" || unset USER_PW - if [ -n "${USER_PW}" ]; then - eval "${PASS_VAR_UPPER}='${USER_PW}'" - else - unset ${PASS_VAR_UPPER} - fi - fi +declare -A PASSWORDS + +for user in "${USERS[@]}"; do + PASS_VAR_LOWER=${user}_pw + PASS_VAR_UPPER=$(echo "$PASS_VAR_LOWER" | tr '[[:lower:]]' '[[:upper:]]') + + user_pw=$(mdata "$PASS_VAR_LOWER" || true) + if [[ -n $user_pw ]]; then + PASSWORDS[$PASS_VAR_UPPER]=$user_pw + fi done +true diff --git a/includes/04-mdata.sh b/includes/04-mdata.sh index b56ca3f..e131af5 100644 --- a/includes/04-mdata.sh +++ b/includes/04-mdata.sh @@ -1,9 +1,13 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -if [ ${HAS_METADATA} ]; then - - # Enable the mdata service that fetches the metadata user-script on each boot - log "enabling metadata agent" - svcadm enable mdata:fetch +# Enable the mdata service that fetches the metadata user-script on each boot +log 'enabling metadata agent' +if [[ $ZONE_SHOULD_REBOOT == 'true' ]]; then + # This service will not start if there is a reboot pending, so we + # enable the service and move on immediately. + svcadm enable mdata:fetch +else + svcadm enable -s mdata:fetch fi diff --git a/includes/11-files.sh b/includes/11-files.sh index 51b6917..d064429 100644 --- a/includes/11-files.sh +++ b/includes/11-files.sh @@ -1,32 +1,35 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -log "cleaning files" +log 'cleaning files' -if [ -e /var/log/auth.log ]; then - cp /dev/null /var/log/auth.log >/dev/null +if [[ -e /var/log/auth.log ]]; then + cp /dev/null /var/log/auth.log >/dev/null else - cp /dev/null /var/log/authlog >/dev/null + cp /dev/null /var/log/authlog >/dev/null fi -log "substituting placeholders for real data in config files" +log 'substituting placeholders for real data in config files' substitute_files=($(find /etc /opt/local/etc -type f | sort | xargs \ - /usr/bin/egrep -l '@(PUBLIC_IP|PRIVATE_IP|LOCAL_IP|DOMAINNAME|HOSTNAME|ZONENAME)@' || true)) + egrep -l '@(PUBLIC_IP|PRIVATE_IP|LOCAL_IP|DOMAINNAME|HOSTNAME|ZONENAME)@' || true)) -for file in ${substitute_files[@]}; do - if sed -e "s/@PUBLIC_IP@/${PUBLIC_IP}/g" \ - -e "s/@PRIVATE_IP@/${PRIVATE_IP}/g" \ - -e "s/@LOCAL_IP@/${LOCAL_IP}/g" \ - -e "s/@HOSTNAME@/${HOSTNAME}/g" \ - -e "s/@ZONENAME@/${ZONENAME}/g" \ - -e "s/@DOMAINNAME@/${DOMAINNAME}/g" \ - ${file} > ${file}.tmp; then - mv ${file}{.tmp,} - fi - rm -f ${file}.tmp +for file in "${substitute_files[@]}"; do + if sed -e "s/@PUBLIC_IP@/$PUBLIC_IP/g" \ + -e "s/@PRIVATE_IP@/$PRIVATE_IP/g" \ + -e "s/@LOCAL_IP@/$LOCAL_IP/g" \ + -e "s/@HOSTNAME@/$HOSTNAME/g" \ + -e "s/@ZONENAME@/$ZONENAME/g" \ + -e "s/@DOMAINNAME@/$DOMAINNAME/g" \ + "$file" > "$file.tmp"; then + + log "rewritting $file" + mv "$file.tmp" "$file" + fi + rm -f "$file.tmp" done -if sed -e "/tmpfs/s/-$/size=${TMPFS}/" /etc/vfstab > /etc/vfstab.tmp 2>/dev/null; then - mv /etc/vfstab{.tmp,} +if sed -e "/tmpfs/s/-$/size=$TMPFS/" /etc/vfstab > /etc/vfstab.tmp 2>/dev/null; then + mv /etc/vfstab{.tmp,} fi rm -f /etc/vfstab.tmp diff --git a/includes/12-network.sh b/includes/12-network.sh index c27a529..1829d8a 100644 --- a/includes/12-network.sh +++ b/includes/12-network.sh @@ -1,17 +1,10 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -log "setting hostname, IPs and resolvers" +log 'setting hostname, IPs and resolvers' -echo "${HOSTNAME}" > /etc/nodename -/bin/hostname ${HOSTNAME} - -( -/bin/sed '/nameserver/d' /etc/resolv.conf 2>/dev/null -for HOST in ${RESOLVERS[@]}; do - echo "nameserver ${HOST}" -done -) > /etc/resolv.conf.tmp -mv /etc/resolv.conf{.tmp,} +echo "$HOSTNAME" > /etc/nodename +/bin/hostname "$HOSTNAME" sed '/^127\.0\.0\.1/s/$/ '${HOSTNAME}'/' /etc/inet/hosts > /etc/inet/hosts.tmp mv /etc/inet/hosts{.tmp,} diff --git a/includes/91-passwords.sh b/includes/91-passwords.sh index 86a0758..51d444d 100644 --- a/includes/91-passwords.sh +++ b/includes/91-passwords.sh @@ -1,38 +1,37 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. -for _HASHTOOL in /usr/lib/cryptpass $(type -p genbfpw); do - if [ -x ${_HASHTOOL} ]; then - HASHTOOL=${_HASHTOOL/genbfpw/genbfpw -p} - break - fi +for _hashtool in /usr/lib/cryptpass $(type -p genbfpw); do + if [[ -x $_hashtool ]]; then + hashtool=${_hashtool/genbfpw/genbfpw -p} + break + fi done -for _PASSTOOL in $(type -p changepass); do - if [ -x ${_PASSTOOL} ]; then - PASSTOOL=${_PASSTOOL} - break - fi +for passtool in $(type -p changepass); do + if [[ -x $passtool ]]; then + passtool=$passtool + break + fi done -for USER in ${USERS[@]}; do +for user in "${USERS[@]}"; do + log "setting system password for user '$user'" + pass_var_lower=${user}_pw + pass_var_upper=$(echo "$pass_var_lower" | tr '[[:lower:]]' '[[:upper:]]') + user_pw=${PASSWORDS[$pass_var_upper]} - log "setting system password for user '${USER}'" - PASS_VAR_LOWER=${USER}_pw - PASS_VAR_UPPER=$(echo ${PASS_VAR_LOWER} | tr '[a-z]' '[A-Z]') - USER_PW="${!PASS_VAR_UPPER}" + if [[ -n $user_pw && -n $hashtool && -n $passtool ]]; then + # Make sure it's blowfish-hashed + [[ "$user_pw" =~ ^\$2a\$ ]] || user_pw=$("$hashtool" "$user_pw") - if [ "${USER_PW}" ] && [ "${HASHTOOL}" ] && [ "${PASSTOOL}" ]; then - - # Make sure it's blowfish-hashed - [[ "${USER_PW}" =~ ^\$2a\$ ]] || USER_PW=$(${HASHTOOL} "${USER_PW}") - - if echo "${USER}:${USER_PW}" | changepass -e > /dev/null 2>&1; then - SSH_ALLOW_PASSWORDS=true - else - log "system password change for '${USER}' failed" - passwd -N ${USER} >/dev/null - fi - else - passwd -N ${USER} >/dev/null - fi + if echo "$user:$user_pw" | changepass -e &>/dev/null; then + SSH_ALLOW_PASSWORDS=true + else + log "system password change for '$user' failed" + passwd -N "$user" >/dev/null + fi + else + passwd -N "$user" >/dev/null + fi done diff --git a/includes/92-sshd.sh b/includes/92-sshd.sh index bc5abd9..471ece0 100644 --- a/includes/92-sshd.sh +++ b/includes/92-sshd.sh @@ -1,4 +1,5 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent, Inc. # Old style SSH host keys were stored under /etc/ssh and needed to be # recreated using /lib/svc/method/sshd -c. @@ -10,15 +11,16 @@ # (e.g. by sm-prepare-image). if awk '/^HostKey/ {print $2}' /etc/ssh/sshd_config | grep '/etc/ssh' > /dev/null; then - log "generating a new pair of SSH keys" - /lib/svc/method/sshd -c >/dev/null + log 'generating a new pair of SSH keys' + /lib/svc/method/sshd -c >/dev/null fi if [ ${SSH_ALLOW_PASSWORDS} ]; then - log "enabling password authentication in SSH" - if sed '/^PasswordAuthentication/s/[nN][oO]$/yes/' \ - /etc/ssh/sshd_config > /etc/ssh/sshd_config.tmp; then - mv /etc/ssh/sshd_config{.tmp,} - fi - rm -f /etc/ssh/sshd_config.tmp + log 'enabling password authentication in SSH' + if sed '/^PasswordAuthentication/s/[nN][oO]$/yes/' \ + /etc/ssh/sshd_config > /etc/ssh/sshd_config.tmp; then + + mv /etc/ssh/sshd_config{.tmp,} + fi + rm -f /etc/ssh/sshd_config.tmp fi diff --git a/includes/999-cleanup.sh b/includes/999-cleanup.sh index 935e58a..af1099d 100644 --- a/includes/999-cleanup.sh +++ b/includes/999-cleanup.sh @@ -1,10 +1,13 @@ -# Copyright 2013, Joyent. Inc. All rights reserved. +#!/usr/bin/env bash +# Copyright (c) 2017, Joyent. Inc. -log "cleaning up" +log 'cleaning up' svccfg -s zoneinit 'setprop application/done = true' svcadm refresh zoneinit -rm -f ${ZONECONFIG} +rm -f "$ZONECONFIG" -log "scheduling an immediate reboot" -echo "reboot >/dev/null" | at now >/dev/null +if [[ $ZONE_SHOULD_REBOOT == 'true' ]]; then + log 'scheduling an immediate reboot' + echo 'reboot >/dev/null' | at now >/dev/null +fi diff --git a/zoneinit b/zoneinit index a5f0642..b0db03e 100755 --- a/zoneinit +++ b/zoneinit @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash -# Copyright 2013, Joyent. Inc. All rights reserved. +# Copyright 2017, Joyent. Inc. PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin export PATH @@ -12,7 +12,8 @@ set -o xtrace smf_is_globalzone && exit ${SMF_EXIT_OK} # Set basedir and default config file -ZONEINIT_INCLUDES=@ZONEINIT_DIR@/includes +ZONEINIT_DIR=@ZONEINIT_DIR@ +ZONEINIT_INCLUDES=$ZONEINIT_DIR/includes ZONECONFIG=/root/zoneconfig # This script should only continue if @@ -25,58 +26,63 @@ ZONECONFIG=/root/zoneconfig # Pre-create /var/svc/provisioning if /root/zoneconfig exists # to stay backwards compatible. - -[ -e ${ZONECONFIG} ] && touch /var/svc/provisioning +if [[ -e $ZONECONFIG ]]; then + touch /var/svc/provisioning +fi # Do nothing if not under SMF, not provisioning, or already done. -if [[ ! "${SMF_METHOD}" == "start" ]] || \ - [[ ! -e /var/svc/provisioning ]] || \ - [[ $(svcprop -p application/done zoneinit) =~ true ]]; then - exit ${SMF_EXIT_OK} +if [[ $SMF_METHOD != 'start' || \ + ! -e /var/svc/provisioning || \ + "$(svcprop -p application/done zoneinit)" =~ true ]]; then + + exit "$SMF_EXIT_OK" fi function log { - local WHERE=$(basename ${INC-zoneinit}) - echo "${WHERE}: $1" + local WHERE=$(basename "${INC-zoneinit}") + echo "${WHERE}: $1" } function exit_handler { - local WHERE=$(basename ${INC-zoneinit}) - local EXITCODE=${2:-95} - - if [ ${EXITCODE} -gt 0 ]; then - echo "${WHERE}: $1 ${EXITCODE}" - - # Renaming 'provisioning' to 'provision_failure' tells the provisioner - # that we failed and the machine is no good - - [ -e /var/svc/provisioning ] && mv /var/svc/provision{ing,_failure} - - # Status 95 tells the SMF restarter to fail fatally (not try again) - exit ${SMF_EXIT_ERR_FATAL} - fi + local WHERE=$(basename "${INC-zoneinit}") + local EXITCODE=${2:-95} + + if ((EXITCODE != 0)); then + echo "$WHERE: $1 $EXITCODE" + + # Renaming 'provisioning' to 'provision_failure' tells the + # provisioner that we failed and the machine is no good + if [[ -e /var/svc/provisioning ]]; then + mv /var/svc/provision{ing,_failure} + fi + + # Status 95 tells the SMF restarter to fail fatally (not try + # again) + exit "$SMF_EXIT_ERR_FATAL" + fi } trap 'exit_handler "received exit status" $?' EXIT -START_TIME=$(date +%s) +START_TIME=$(($(date +%s%N) / 1000 / 1000)) log "(start)" # Pull in and execute all operations from the 'includes' directory -for INC in ${ZONEINIT_INCLUDES}/*.sh -do - log "(start)" - source ${INC} +for INC in "$ZONEINIT_INCLUDES"/*.sh; do + log "(start) $INC" + thentime=$(($(date +%s%N) / 1000 / 1000)) + source "$INC" + nowtime=$(($(date +%s%N) / 1000 / 1000)) + ms=$((nowtime - thentime)) + log "(finish) $INC - took ${ms}ms" done unset INC -END_TIME=$(date +%s) -RUN_TIME=$((END_TIME-START_TIME)) -if [ ${RUN_TIME} -gt 0 ]; then - log "total runtime ${RUN_TIME} seconds" -fi +END_TIME=$(($(date +%s%N) / 1000 / 1000)) +RUN_TIME=$((END_TIME - START_TIME)) +log "total runtime ${RUN_TIME}ms" # provisioner takes over log "(finish)" -exit ${SMF_EXIT_OK} +exit "$SMF_EXIT_OK" diff --git a/zoneinit.json b/zoneinit.json index 376b829..95af5ca 100644 --- a/zoneinit.json +++ b/zoneinit.json @@ -2,6 +2,6 @@ "version": "@PKGVERSION_NOREV@", "features": { "var_svc_provisioning": true, - "reboot": true + "reboot": false } }