xref: /illumos-gate/usr/src/tools/scripts/onu.sh.in (revision 5c4a5fe16715fb423db76577a6883b5bbecdbe45)
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