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