xref: /illumos-gate/usr/src/tools/scripts/onu.sh.in (revision 9e7f7d5d77f695e9980dbb0f9fb1b969272eb207)
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)
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
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)
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
182
183while getopts :c:d:Ors:t:U:u:vZ i ; do
184	case $i in
185	c)
186		consolidation=$OPTARG
187		;;
188	d)
189		repodir=$OPTARG
190		;;
191	O)			# no-op, compatibility with recommended use
192		;;
193	r)
194		reposonly=1
195		;;
196	s)
197		sourcebe=$OPTARG
198		;;
199	t)
200		targetbe=$OPTARG
201		;;
202	U)
203		redistpub=$OPTARG
204		;;
205	u)
206		uri=$OPTARG
207		;;
208	v)
209		verbose=1
210		;;
211	Z)
212		no_zones=1
213		;;
214	*)
215		usage
216	esac
217done
218shift `expr $OPTIND - 1`
219
220[ -n "$1" ] && usage
221
222if [ "$reposonly" -eq 1 ]; then
223	[ -n "$sourcebe" ] && usage
224	[ -n "$targetbe" ] && usage
225	[ "$no_zones" -eq 1 ] && usage
226else
227	[ -z "$targetbe" ] && usage
228fi
229[ -z "$uri" ] && uri=$ONURI
230[ -z "$uri" ] && uri=$DEFAULTONURI
231[ -z "$redistpub" ] && redistpub=$ONPUB
232[ -z "$redistpub" ] && redistpub=$DEFAULTONPUB
233
234if [ -n "$repodir" ]; then
235	redistdir=$repodir/repo.redist
236	[ -d $redistdir ] || exit_error "$redistdir not found"
237	typeset cfgfile=$redistdir/cfg_cache
238	[[ ! -e $cfgfile ]] && cfgfile=$redistdir/pkg5.repository
239	# need an absolute path
240	[[ $redistdir == /* ]] || redistdir=$PWD/$redistdir
241	redistpub=$(python@PYTHON_VERSION@ <<# EOF
242		try:	# python3
243			import configparser
244			p = configparser.ConfigParser()
245		except:	# python2
246			import ConfigParser
247			p = ConfigParser.SafeConfigParser()
248		p.read("$cfgfile")
249		pp = p.get("publisher", "prefix")
250		print("{}".format(pp))
251		EOF) || exit_error "Cannot determine publisher prefix"
252	[[ -n "$redistpub" ]] || exit_error "Repository has no publisher prefix"
253	uri="file://$redistdir"
254fi
255
256if [ "$reposonly" -eq 1 ]; then
257	configure_publishers /
258	exit 0
259fi
260
261createargs=""
262[ -n "$sourcebe" ] && createargs="-e $sourcebe"
263
264# ksh seems to have its own mktemp with slightly different semantics
265tmpdir=`/usr/bin/mktemp -d /tmp/onu.XXXXXX`
266[ -z "$tmpdir" ] && exit_error "mktemp failed"
267
268do_cmd beadm create $createargs $targetbe
269do_cmd beadm mount $targetbe $tmpdir
270update $tmpdir
271do_cmd beadm activate $targetbe
272
273if [ "$no_zones" != 1 ]; then
274	for zone in `do_cmd zoneadm -R $tmpdir list -cip`; do
275		update_zone $zone
276	done
277fi
278
279exit 0
280