1#!/bin/ksh93 -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 25# Copyright 2010, Richard Lowe 26# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. 27# Copyright 2024 Bill Sommerfeld <sommerfeld@hamachi.org> 28 29PATH=/usr/bin:/usr/sbin 30export PATH 31 32DEFAULTONPUB="on-nightly" 33 34usage() 35{ 36 echo "usage: $0 [opts] [-s beName] -t beName" 37 echo "usage: $0 [opts] -r" 38 echo 39 echo "\t-c consolidation : consolidation being upgraded" 40 echo "\t-d repodir : directory for repositories" 41 echo "\t-r : configure publisher only" 42 echo "\t-s : source BE to clone" 43 echo "\t-t : new BE name" 44 echo "\t-u uri : origin URI for redist repository" 45 echo "\t-U prefix: prefix for redist repository" 46 echo "\t-v : verbose" 47 echo "\t-Z : skip updating zones" 48 echo 49 echo "Update to an ON build:" 50 echo "\tonu -t newbe -d /path/to/my/ws/packages/\`uname -p\`/nightly" 51 echo 52 echo "Re-enable the publishers in the current BE:" 53 echo "\tonu -r -d /path/to/my/ws/packages/\`uname -p\`/nightly" 54 exit 1 55} 56 57srcusage() 58{ 59 cat 1>&2 <<EOF 60No package source specified; use -d or -u or set ONURI in environment 61 62EOF 63 usage 64} 65 66exit_error() 67{ 68 echo $* 69 exit 2 70} 71 72do_cmd() 73{ 74 [ $verbose -gt 0 ] && echo $* 75 $* 76 exit_code=$? 77 [ $exit_code -eq 0 ] && return 78 # pkg(1) returns 4 if "nothing to do", which is safe to ignore 79 [ $1 = "pkg" -a $exit_code -eq 4 ] && return 80 exit_error "$*" failed: exit code $exit_code 81} 82 83configure_publishers() 84{ 85 root=$1 86 87 # 88 # Get the publisher name from the 'list -v' output. It may seem we 89 # could do this more tidily using 'info', but that is 90 # internationalized. 91 # 92 typeset on_publisher=$(pkg -R $root list -Hv \ 93 "${consolidation}-incorporation" | cut -d/ -f3) 94 95 if [[ "$on_publisher" != "$redistpub" ]]; then 96 do_cmd pkg -R $root set-publisher -r --no-refresh \ 97 --set-property signature-policy=verify \ 98 --non-sticky $on_publisher 99 fi 100 101 do_cmd pkg -R $root set-publisher -r -e --no-refresh -P \ 102 --set-property signature-policy=verify -O $uri $redistpub 103 104 do_cmd pkg -R $root refresh --full 105} 106 107prepare_image() 108{ 109 print "**\n** Preparing for ONU from $distribution\n**" 110 111 case $distribution in 112 omnios|helios) 113 # This removes files from the image that cause conflicts with 114 # stock illumos-gate, and removes omnios-only kernel drivers 115 # etc. 116 do_cmd pkg -R $root change-facet -r onu.ooceonly=false 117 ;; 118 esac 119} 120 121update() 122{ 123 root=$1 124 125 pkg -R $root list -q entire && do_cmd pkg -R $root uninstall entire 126 127 configure_publishers $root 128 129 prepare_image 130 131 do_cmd pkg -R $root image-update $update_args 132} 133 134update_zone() 135{ 136 OIFS="$IFS" 137 IFS=":" 138 set -- $1 139 zone=$2; state=$3; path=$4; brand=$6 140 IFS="$OIFS" 141 142 [[ "$zone" == "global" ]] && return 143 [[ "$state" == "incomplete" ]] && return 144 [[ "$state" == "configured" ]] && return 145 [[ "$brand" == "$nlbrand" ]] || return 146 147 if [ "$zone_warned" = 0 ]; then 148 echo "WARNING: Use of onu(1) will prevent use of zone attach in the new BE" >&2 149 echo "See onu(1)" >&2 150 zone_warned=1 151 fi 152 153 print "**\n** Updating zone $zone (brand $brand)\n**" 154 update "$path/root" 155} 156 157typeset -l distribution 158if [[ -r /etc/os-release ]]; then 159 distribution=$(awk -F= '$1 == "ID" { print $2 }' /etc/os-release) 160elif [[ -r /etc/release ]]; then 161 distribution=$(awk 'NR == 1 { print $1 }' /etc/release) 162else 163 distribution=unknown 164fi 165 166case $distribution in 167 openindiana) 168 nlbrand=nlipkg 169 ;; 170 omnios|helios) 171 nlbrand=ipkg 172 ;; 173 *) 174 nlbrand=unknown 175 ;; 176esac 177 178sourcebe="" 179targetbe="" 180uri="" 181repodir="" 182consolidation="osnet" 183verbose=0 184no_zones=0 185zone_warned=0 186reposonly=0 187update_args="" 188 189while getopts :c:d:Ors:t:U:u:vZ i ; do 190 case $i in 191 c) 192 consolidation=$OPTARG 193 ;; 194 d) 195 repodir=$OPTARG 196 ;; 197 O) # no-op, compatibility with recommended use 198 ;; 199 r) 200 reposonly=1 201 ;; 202 s) 203 sourcebe=$OPTARG 204 ;; 205 t) 206 targetbe=$OPTARG 207 ;; 208 U) 209 redistpub=$OPTARG 210 ;; 211 u) 212 uri=$OPTARG 213 ;; 214 v) 215 verbose=1 216 ;; 217 Z) 218 no_zones=1 219 ;; 220 *) 221 usage 222 esac 223done 224shift `expr $OPTIND - 1` 225 226# Pass remaining arguments to pkg update. 227if [ -n "$1" ]; then 228 update_args="$*" 229fi 230 231if [ "$reposonly" -eq 1 ]; then 232 [ -n "$sourcebe" ] && usage 233 [ -n "$targetbe" ] && usage 234 [ "$no_zones" -eq 1 ] && usage 235else 236 [ -z "$targetbe" ] && usage 237fi 238[ -z "$uri" ] && uri=$ONURI 239[ -z "$redistpub" ] && redistpub=$ONPUB 240[ -z "$redistpub" ] && redistpub=$DEFAULTONPUB 241 242if [ -n "$repodir" ]; then 243 redistdir=$repodir/repo.redist 244 [ -d $redistdir ] || exit_error "$redistdir not found" 245 typeset cfgfile=$redistdir/cfg_cache 246 [[ ! -e $cfgfile ]] && cfgfile=$redistdir/pkg5.repository 247 # need an absolute path 248 [[ $redistdir == /* ]] || redistdir=$PWD/$redistdir 249 redistpub=$(python@PYTHON_VERSION@ <<# EOF 250 try: # python3 251 import configparser 252 p = configparser.ConfigParser() 253 except: # python2 254 import ConfigParser 255 p = ConfigParser.SafeConfigParser() 256 p.read("$cfgfile") 257 pp = p.get("publisher", "prefix") 258 print("{}".format(pp)) 259 EOF) || exit_error "Cannot determine publisher prefix" 260 [[ -n "$redistpub" ]] || exit_error "Repository has no publisher prefix" 261 uri="file://$redistdir" 262fi 263 264[ -z "$uri" ] && srcusage 265 266if [ "$reposonly" -eq 1 ]; then 267 configure_publishers / 268 exit 0 269fi 270 271createargs="" 272[ -n "$sourcebe" ] && createargs="-e $sourcebe" 273 274# ksh seems to have its own mktemp with slightly different semantics 275tmpdir=`/usr/bin/mktemp -d /tmp/onu.XXXXXX` 276[ -z "$tmpdir" ] && exit_error "mktemp failed" 277 278do_cmd beadm create $createargs $targetbe 279do_cmd beadm mount $targetbe $tmpdir 280update $tmpdir 281do_cmd beadm activate $targetbe 282 283if [ "$no_zones" != 1 ]; then 284 for zone in `do_cmd zoneadm -R $tmpdir list -cip`; do 285 update_zone $zone 286 done 287fi 288 289exit 0 290