source: src-sh/warden/scripts/backend/functions.sh

Last change on this file was fb46926, checked in by Kris Moore <kris@…>, 2 weeks ago

Finish up the fbsdupgrade option for jail upgrades, now we can
go from 10.0-RELEASE -> 10.1-RELEASE and beyond easily

  • Property mode set to 100755
File size: 46.6 KB
RevLine 
[1620346]1#!/bin/sh
2# Functions / variables for warden
3######################################################################
4# DO NOT EDIT
5
6# Source local functions
7. /usr/local/share/pcbsd/scripts/functions.sh
8
9# Installation directory
10PROGDIR="/usr/local/share/warden"
11
12# Jail location
13JDIR="$(grep ^JDIR: /usr/local/etc/warden.conf | cut -d' ' -f2)"
14export JDIR
15
16# Set arch type
17REALARCH=`uname -m`
18export REALARCH
19if [ -z "$ARCH" ] ; then
20  ARCH="$REALARCH"
21  export ARCH
22fi
23
24# Location of pcbsd.conf file
25PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
26
27# Network interface to use
[1d95ade]28NIC="$(grep ^NIC: /usr/local/etc/warden.conf | sed 's|NIC: ||g' | sed 's|NIC:||g')"
[1620346]29export NIC
30
31# Tmp directory
32WTMP="$(grep ^WTMP: /usr/local/etc/warden.conf | cut -d' ' -f2)"
33export WTMP
34
[c63ce1b]35# Default IP4 Pool of addresses
36DEFAULT_IP4POOL="$(grep ^IP4POOL: /usr/local/etc/warden.conf | cut -d' ' -f2)"
37if [ -z "$DEFAULT_IP4POOL" ] ; then
[37e71e4f]38   DEFAULT_IP4POOL="192.168.0.220"
[c63ce1b]39fi
40export DEFAULT_IP4POOL
41
[1620346]42# FreeBSD release
43FREEBSD_RELEASE="$(grep ^FREEBSD_RELEASE: /usr/local/etc/warden.conf | cut -d' ' -f2)"
44if [ -z "${FREEBSD_RELEASE}" ] ; then
45  FREEBSD_RELEASE="$(uname -r)"
46fi
47export UNAME_r="${FREEBSD_RELEASE}"
48
49# Temp file for dialog responses
50ATMP="/tmp/.wans"
51export ATMP
52
53# Warden Version
[d2b5358]54WARDENVER="1.4"
[1620346]55export WARDENVER
56
[2c39b15]57# Dirs to nullfs mount in X jail
[f4066f6]58NULLFS_MOUNTS="/tmp /media"
59X11_MOUNTS="/usr/local/lib/X11/icons /usr/local/lib/X11/fonts /usr/local/etc/fonts"
[1620346]60
61# Clone directory
62CDIR="${JDIR}/clones"
63
64downloadpluginjail() {
65  local _ver="${1}"
66
67  SYSVER=`echo "${_ver}" | sed -E 's|^FreeNAS-(([0-9]+\.){2}[0-9]+).*|\1|'`
68  SYSREL=`echo "${_ver}" | sed -E 's|^FreeNAS-([0-9]+\.){2}[0-9]+-([a-zA-Z0-9]+)-.*|\2|'`
69  SYSARCH=`echo "${_ver}" | sed -E 's#^(.*)(x86|x64)#\2#'`
70
71  SF="http://downloads.sourceforge.net/project/freenas"
72  URL="${SF}/FreeNAS-${SYSVER}/${SYSREL}/${SYSARCH}/plugins"
73
74  PJAIL="FreeNAS-${SYSVER}-${SYSREL}-${SYSARCH}.Plugins_Jail.pbi"
75  PJAILSHA256="${PJAIL}.sha256"
76
77  if [ ! -d "${JDIR}" ] ; then mkdir -p "${JDIR}" ; fi
78  cd ${JDIR}
79
80  echo "Fetching jail environment. This may take a while..."
81
82  if [ ! -e "${PJAIL}" ] ; then
83     echo "Downloading ${URL}/${PJAIL} ..."
84     get_file "${URL}/${PJAIL}" "${PJAIL}" 3
85     [ $? -ne 0 ] && printerror "Error while downloading the pluginjail."
86  fi
87
88  if [ ! -e "${PJAILSHA256}" ] ; then
89     echo "Downloading ${URL}/${PJAILSHA256} ..."
90     get_file "${URL}/${PJAILSHA256}" "${PJAILSHA256}" 3
91     [ $? -ne 0 ] && printerror "Error while downloading the pluginjail sha256."
92  fi
93
94  [ "$(sha256 -q ${PJAIL})" != "$(cat ${PJAILSHA256})" ] &&
95    printerror "Error in download data, checksum mismatch. Please try again later."
96
[698a249]97  # Get the dataset of the jails mountpoint
98  rDataSet=`mount | grep "on ${JDIR} " | awk '{print $1}'`
99  tSubDir=`basename $WORLDCHROOT`
100  nDataSet="${rDataSet}/${tSubDir}"
[1620346]101
[698a249]102  echo "Creating ZFS ${nDataSet} dataset..."
[4905ba9]103  isDirZFS "${WORLDCHROOT}" "1"
104  if [ $? -ne 0 ] ; then
[698a249]105     zfs create -p ${nDataSet}
[4905ba9]106     if [ $? -ne 0 ] ; then exit_err "Failed creating ZFS base dataset"; fi
107     mkdir -p "${WORLDCHROOT}/.plugins" >/dev/null 2>&1
[1620346]108  fi
[4905ba9]109
110  pbi_add -e --no-checksig -p ${WORLDCHROOT} ${PJAIL}
111  if [ $? -ne 0 ] ; then exit_err "Failed extracting ZFS chroot environment"; fi
112
[698a249]113  zfs snapshot ${nDataSet}@clean
[4905ba9]114  if [ $? -ne 0 ] ; then exit_err "Failed creating clean ZFS base snapshot"; fi
115  rm ${PJAIL}
[1620346]116  rm ${PJAILSHA256}
117};
118
119### Download the chroot
120downloadchroot() {
121  local CHROOT="${1}"
122
123  # XXX If this is PCBSD, pbreg get /PC-BSD/Version
124  SYSVER="$(echo "$(uname -r)" | cut -f1 -d'-')"
125  FBSD_TARBALL="fbsd-release.txz"
126  FBSD_TARBALL_CKSUM="${FBSD_TARBALL}.md5"
127
128  # Set the mirror URL, may be overridden by setting MIRRORURL environment variable
129  if [ -z "${MIRRORURL}" ]; then
130    get_mirror
131    MIRRORURL="$VAL"
132  fi
133
134  if [ ! -d "${JDIR}" ] ; then mkdir -p "${JDIR}" ; fi
135  cd ${JDIR}
136
137  echo "Fetching jail environment. This may take a while..."
138  echo "Downloading ${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/${FBSD_TARBALL} ..."
139
140  if [ ! -e "$FBSD_TARBALL" ] ; then
141     get_file "${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/${FBSD_TARBALL}" "$FBSD_TARBALL" 3
142     [ $? -ne 0 ] && printerror "Error while downloading the portsjail."
143  fi
144
145  if [ ! -e "$FBSD_TARBALL_CKSUM" ] ; then
146     get_file "${MIRRORURL}/${SYSVER}/${ARCH}/netinstall/${FBSD_TARBALL_CKSUM}" "$FBSD_TARBALL_CKSUM" 3
147     [ $? -ne 0 ] && printerror "Error while downloading the portsjail."
148  fi
149
150  [ "$(md5 -q ${FBSD_TARBALL})" != "$(cat ${FBSD_TARBALL_CKSUM})" ] &&
151    printerror "Error in download data, checksum mismatch. Please try again later."
152
[698a249]153  # Get the dataset of the jails mountpoint
154  rDataSet=`mount | grep "on ${JDIR} " | awk '{print $1}'`
155  tSubDir=`basename $CHROOT`
156  nDataSet="${rDataSet}/${tSubDir}"
[1620346]157
[4905ba9]158  echo "Creating ZFS ${CHROOT} dataset..."
159  isDirZFS "${CHROOT}" "1"
160  if [ $? -ne 0 ] ; then
[698a249]161     zfs create -p ${nDataSet}
[4905ba9]162     if [ $? -ne 0 ] ; then exit_err "Failed creating ZFS base dataset"; fi
[1620346]163  fi
[4905ba9]164
165  tar xvpf ${FBSD_TARBALL} -C ${CHROOT} 2>/dev/null
166  if [ $? -ne 0 ] ; then exit_err "Failed extracting ZFS chroot environment"; fi
167
[698a249]168  zfs snapshot ${nDataSet}@clean
[4905ba9]169  if [ $? -ne 0 ] ; then exit_err "Failed creating clean ZFS base snapshot"; fi
170  rm ${FBSD_TARBALL}
[1620346]171  rm ${FBSD_TARBALL_CKSUM}
172};
173
[f4066f6]174# Check if a directory is mounted
175isDirMounted() {
176  mount | grep -q "on $1 ("
177  return $?
178}
179
[2c39b15]180### Mount all needed filesystems for the jail
181mountjailxfs() {
[1620346]182
[e5240d6]183  if [ ! -d "${JDIR}/${1}/" ] ; then
184     exit_err "Invalid jail directory: ${JDIR}/${1}"
185  fi
186
[29f8f9d]187  # Update the user files on the portjail
188  ETCFILES="resolv.conf passwd master.passwd spwd.db pwd.db group localtime"
189  for file in ${ETCFILES}; do
190    rm ${JDIR}/${1}/etc/${file} >/dev/null 2>&1
191    cp /etc/${file} ${JDIR}/${1}/etc/${file}
192  done
193
[1620346]194  for nullfs_mount in ${NULLFS_MOUNTS}; do
195    if [ ! -d "${JDIR}/${1}${nullfs_mount}" ] ; then
196      mkdir -p "${JDIR}/${1}${nullfs_mount}"
197    fi
198    if is_symlinked_mountpoint ${nullfs_mount}; then
199      echo "${nullfs_mount} has symlink as parent, not mounting"
200      continue
201    fi
202
[f4066f6]203    # If this is already mounted we can skip for now
204    isDirMounted "${JDIR}/${1}${nullfs_mount}" && continue
205
[1620346]206    echo "Mounting ${JDIR}/${1}${nullfs_mount}"
207    mount_nullfs ${nullfs_mount} ${JDIR}/${1}${nullfs_mount}
208  done
209
[f4066f6]210  # Check and mount /dev
211  isDirMounted "${JDIR}/${1}/dev"
212  if [ $? -ne 0 ] ; then
213    echo "Enabling devfs"
214    mount -t devfs devfs ${JDIR}/${1}/dev
215  fi
216
[1620346]217  # Add support for linprocfs for ports that need linprocfs to build/run
218  if [  ! -d "${JDIR}/${1}/compat/linux/proc" ]; then
219    mkdir -p ${JDIR}/${1}/compat/linux/proc
220  fi
221  if is_symlinked_mountpoint ${JDIR}/${1}/compat/linux/proc; then
222    echo "${JDIR}/${1}/compat/linux/proc has symlink as parent, not mounting"
223    return
224  fi
[f4066f6]225
226  # If this is already mounted we can skip for now
227  isDirMounted "${JDIR}/${1}/compat/linux/proc"
228  if [ $? -ne 0 ] ; then
229    echo "Enabling linprocfs support."
230    mount -t linprocfs linprocfs ${JDIR}/${1}/compat/linux/proc
231  fi
232
233  # Add support for linsysfs for ports that need linprocfs to build/run
234  if [  ! -d "${JDIR}/${1}/compat/linux/sys" ]; then
235    mkdir -p ${JDIR}/${1}/compat/linux/sys
236  fi
237  if is_symlinked_mountpoint ${JDIR}/${1}/compat/linux/sys; then
238    echo "${JDIR}/${1}/compat/linux/sys has symlink as parent, not mounting"
239    return
240  fi
241
242  # If this is already mounted we can skip for now
243  isDirMounted "${JDIR}/${1}/compat/linux/sys"
244  if [ $? -ne 0 ] ; then
245    echo "Enabling linsysfs support."
246    mount -t linsysfs linsysfs ${JDIR}/${1}/compat/linux/sys
247  fi
248
249  # Lastly we need to mount /usr/home/* directories
250  for i in `ls -d /usr/home/*`
251  do
252    # If this is already mounted we can skip for now
253    isDirMounted "${JDIR}/${1}${i}" && continue
254    if [ ! -d "${JDIR}/${1}${i}" ] ; then mkdir -p ${JDIR}/${1}${i} ; fi
255    echo "Mounting home: ${i}"
256    mount_nullfs ${i} ${JDIR}/${1}${i}
257  done
258
[1620346]259}
260
261### Umount all the jail's filesystems
262umountjailxfs() {
263  status="0"
264  # Umount all filesystems that are mounted into the portsjail
265  for mountpoint in $(mount | grep ${JDIR}/${1}/ | cut -d" " -f3); do
266    if [ "$mountpoint" = "${JDIR}/${1}/dev" ] ; then continue ; fi
267    if [ "$mountpoint" = "${JDIR}/${1}/" ] ; then continue ; fi
268    if [ "$mountpoint" = "${JDIR}/${1}" ] ; then continue ; fi
269    echo "Unmounting $mountpoint"
270    umount -f ${mountpoint}
271    if [ $? -ne 0 ] ; then status="1" ; fi
272  done
273  # Now try to umount /dev
274  umount -f ${JDIR}/${1}/dev 2>/dev/null >/dev/null
275  return $status
276}
277
278# Check if PBI scripts are loaded in jail
279checkpbiscripts() {
280  if [ -z "${1}" ] ; then return ; fi
281  if [ ! -e "${1}/usr/local/sbin/pbi_info" ] ; then
282    copypbiscripts "${1}"
283  elif [ "`ls -l /usr/local/sbin/pbi_info | awk '{print $5}'`" != "`ls -l ${1}/usr/local/sbin/pbi_info | awk '{print $5}'`" ] ; then
284    copypbiscripts "${1}"
285  fi
286}
287
288# Copy PBI scripts to jail
289copypbiscripts() {
290  if [ -z "${1}" ] ; then return ; fi
291  mkdir -p ${1}/usr/local/sbin >/dev/null 2>/dev/null
292  cp /usr/local/sbin/pbi* ${1}/usr/local/sbin/
293  chmod 755 ${1}/usr/local/sbin/pbi*
294
295  # Copy rc.d pbid script
296  mkdir -p ${1}/usr/local/etc/rc.d >/dev/null 2>/dev/null
297  cp /usr/local/etc/rc.d/pbid ${1}/usr/local/etc/rc.d/
298
299  # Copy any PBI manpages
300  for man in `find /usr/local/man | grep pbi`
301  do
302    if [ ! -d "${1}`dirname $man`" ] ; then
303      mkdir -p "${1}`dirname $man`"
304    fi
305    cp "${man}" "${1}${man}"
306  done
307}
308
309mkportjail() {
310  if [ -z "${1}" ] ; then return ; fi
311  ETCFILES="resolv.conf passwd master.passwd spwd.db pwd.db group localtime"
312  for file in ${ETCFILES}; do
313    rm ${1}/etc/${file} >/dev/null 2>&1
314    cp /etc/${file} ${1}/etc/${file}
315  done
316 
317  # Need to symlink /home
318  chroot ${1} ln -fs /usr/home /home
319
320  # Make sure we remove our cleartmp rc.d script, causes issues
321  [ -e "${1}/etc/rc.d/cleartmp" ] && rm ${1}/etc/rc.d/cleartmp
[f4066f6]322
[1620346]323  # Flag this type
324  touch ${JMETADIR}/jail-portjail
325}
326
327mkpluginjail() {
328  if [ -z "${1}" ] ; then return ; fi
329  ETCFILES="resolv.conf passwd master.passwd spwd.db pwd.db group localtime"
330  for file in ${ETCFILES}; do
331    rm ${1}/etc/${file} >/dev/null 2>&1
332    cp /etc/${file} ${1}/etc/${file}
333  done
334 
335  # Need to symlink /home
336  chroot ${1} ln -fs /usr/home /home
337
338  # Make sure we remove our cleartmp rc.d script, causes issues
339  [ -e "${1}/etc/rc.d/cleartmp" ] && rm ${1}/etc/rc.d/cleartmp
340  # Flag this type
341  touch ${JMETADIR}/jail-pluginjail
342}
343
344mkZFSSnap() {
345  isDirZFS "${1}" "1"
346  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
347  tank=`getZFSTank "$1"`
348  rp=`getZFSRelativePath "$1"`
349  zdate=`date +%Y-%m-%d-%H-%M-%S`
[bb6487e]350  snaptag="$zdate"
351  if [ -n "$3" ] ; then snaptag="$3"; fi
352
353  rc_halt "zfs snapshot $tank${rp}@${snaptag}"
354
[cca8f57]355  # Do we have a comment to set?
356  if [ -n "$2" ] ; then
[bb6487e]357      zfs set warden:comment="$2" ${tank}${rp}@${snaptag}
[cca8f57]358  fi
[1620346]359}
360
361listZFSSnap() {
362  isDirZFS "${1}" "1"
363  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
364  tank=`getZFSTank "$1"`
365  rp=`getZFSRelativePath "$1"`
[cca8f57]366
367  echo "Snapshot                                Comment"
368  echo "-----------------------------------------------"
[de73897]369  for i in `zfs list -r -t snapshot ${tank}${rp} 2>/dev/null | cut -d '@' -f 2 | awk '{print $1}'`
[cca8f57]370  do
[de73897]371     comment=`zfs get -o value warden:comment ${tank}${rp}@$i 2>/dev/null| grep -v "VALUE"`
372     lcomment=`zfs get -o value lpreserver:comment ${tank}${rp}@$i 2>/dev/null| grep -v "VALUE"`
373     if [ -z "$comment" -a -n "$lcomment" ] ; then
374       echo "$i         $lcomment"
375     else
376       echo "$i         $comment"
377     fi
[cca8f57]378  done
[1620346]379}
380
381listZFSClone() {
382  isDirZFS "${1}" "1"
383  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
384  tank=`getZFSTank "$1"`
385  cdir=`getZFSRelativePath "${CDIR}"` 
386  echo "Clone Directory: ${CDIR}"
387  echo "-----------------------------------"
388  zfs list | grep -w "^${tank}${cdir}/${2}" | awk '{print $5}' | sed "s|${CDIR}/${2}-||g"
389}
390
391rmZFSSnap() {
392  isDirZFS "${1}" "1"
393  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
[698a249]394
395  # Get the dataset of the jails mountpoint
396  rDataSet=`mount | grep "on ${1} " | awk '{print $1}'`
397  zfs destroy ${rDataSet}@$2
[1620346]398}
399
[7dd1a232]400rmZFSSnapDate() {
401  isDirZFS "${1}" "1"
402  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
403  tank=`getZFSTank "$1"`
404  rp=`getZFSRelativePath "$1"`
405
406  snap_rm_date=`echo "$2" | sed 's/-//g'`
407
[677333d]408  if [ ! `date -j "$snap_rm_date"0000 "+%Y%m%d" 2>/dev/null` ]; then
[7dd1a232]409    printerror "$2 is not a valid date."
410  fi
411
[f3c4e0b]412  echo "Removing snapshots older than $2."
[7dd1a232]413  echo "-----------------------------------"
414
415  for i in `zfs list -r -H -S creation -o name -t snapshot ${tank}${rp} 2>/dev/null`
416  do
[b71de90]417    snap_creation_date=`zfs get -H -o value creation $i 2>/dev/null`
418                # Format output to numbered month. zfs get ouput: "Wed Oct  1 17:30 2014"
419    snap_creation_date=`echo $snap_creation_date | sed 's/ Jan / 01 /;s/ Feb / 02 /;s/ Mar / 03 /;s/ Apr / 04 /;s/ May / 05 /;s/ Jun / 06 /;s/ Jul / 07 /;s/ Aug / 08 /;s/ Sep / 09 /;s/ Oct / 10 /;s/ Nov / 11 /;s/ Dec / 12 /'`
420                # Format day output to two digit number. zfs get ouput: "Wed Oct  1 17:30 2014"
421    snap_creation_date=`echo $snap_creation_date | sed 's/ 1 / 01 /;s/ 2 / 02 /;s/ 3 / 03 /;s/ 4 / 04 /;s/ 5 / 05 /;s/ 6 / 06 /;s/ 7 / 07 /;s/ 8 / 08 /;s/ 9 / 09 /' | awk '{ print $5 $2 $3 }'`
[7dd1a232]422    if [ "$snap_creation_date" -lt "$snap_rm_date" ]; then
423      snapshot=`echo $i | cut -d '@' -f 2 | awk '{ print $1 }'`
424      zfs destroy $i
425      if [ $? -ne 0 ]; then printerror "Something went wrong with removal of $snapshot. Aborting."; fi
426      echo "Removed snapshot $snapshot"
427    fi
428  done
429
430}
431
[1620346]432revertZFSSnap() {
433  isDirZFS "${1}" "1"
434  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
435  tank=`getZFSTank "$1"`
436  rp=`getZFSRelativePath "$1"`
437
438  # Make sure this is a valid snapshot
439  zfs list -t snapshot | grep -w "^${tank}${rp}" | cut -d '@' -f 2 | awk '{print $1}' | grep -q ${2}
440  if [ $? -ne 0 ] ; then printerror "Invalid ZFS snapshot!" ; fi
441
442  # Check if the jail is running first
443  ${PROGDIR}/scripts/backend/checkstatus.sh "${3}"
444  if [ "$?" = "0" ]; then
445    restartJail="YES"
446    # Make sure the jail is stopped
447    ${PROGDIR}/scripts/backend/stopjail.sh "${3}"
448    ${PROGDIR}/scripts/backend/checkstatus.sh "${3}"
449    if [ "$?" = "0" ]; then
450      printerror "Could not stop jail... Halting..."
451    fi
452  fi
453
454  # Rollback the snapshot
455  zfs rollback -R -f ${tank}${rp}@$2
456
457  # If it was started, restart the jail now
458  if [ "$restartJail" = "YES" ]; then
459    ${PROGDIR}/scripts/backend/startjail.sh "${3}"
460  fi
461 
462}
463
[d2b5358]464cloneZFSDir() {
[1620346]465  isDirZFS "${1}" "1"
466  if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${1}" ; fi
[d2b5358]467
[698a249]468  # Get the dataset of the jails mountpoint
469  rDataSet=`mount | grep "on ${JDIR} " | awk '{print $1}'`
470  oSubDir=`basename $1`
471  oDataSet="${rDataSet}/${oSubDir}"
472  nSubDir=`basename $2`
473  nDataSet="${rDataSet}/${nSubDir}"
[1620346]474
[d2b5358]475  zdate=`date +%Y-%m-%d-%H-%M-%S`
476  snapName="preClone-$zdate"
[1620346]477
[d2b5358]478  # Create a temp snapshot we can clone
[698a249]479  zfs snapshot ${oDataSet}@${snapName}
[d2b5358]480  if [ $? -ne 0 ] ; then printerror "Failed creating snapshot!" ; fi
[1620346]481
482  # Clone the snapshot
[698a249]483  zfs clone -p ${oDataSet}@${snapName} ${nDataSet}
[d2b5358]484  if [ $? -ne 0 ] ; then printerror "Failed cloning snapshot!" ; fi
[1620346]485
[d2b5358]486  return 0
[1620346]487}
488
489set_warden_metadir()
490{
491   JMETADIR="${JDIR}/.${JAILNAME}.meta"
492   export JMETADIR
493}
494
495get_ip_and_netmask()
496{
497   JIP=`echo "${1}" | cut -f1 -d'/'`
498   JMASK=`echo "${1}" | cut -f2 -d'/' -s`
499}
500
501get_interface_addresses()
502{
503   ifconfig ${1} | grep -w inet | awk '{ print $2 }'
504}
505
506get_interface_ipv4_addresses()
507{
508   ifconfig ${1} | grep -w inet | awk '{ print $2 }'
509}
510
511get_interface_ipv6_addresses()
512{
513   ifconfig ${1} | grep -w inet6 | awk '{ print $2 }'
514}
515
516get_interface_address()
517{
518   ifconfig ${1} | grep -w inet | head -1 | awk '{ print $2 }'
519}
520
521get_interface_ipv4_address()
522{
523   ifconfig ${1} | grep -w inet | head -1 | awk '{ print $2 }'
524}
525
526get_interface_ipv6_address()
527{
528   ifconfig ${1} | grep -w inet6 | head -1 | awk '{ print $2 }'
529}
530
531get_interface_aliases()
532{
533   local _count
534
535   _count=`ifconfig ${1} | grep -w inet | wc -l`
536   _count="$(echo "${_count} - 1" | bc)"
537
538   ifconfig ${1} | grep -w inet | tail -${_count} | awk '{ print $2 }'
539}
540
541get_interface_ipv4_aliases()
542{
543   local _count
544
545   _count=`ifconfig ${1} | grep -w inet | wc -l`
546   _count="$(echo "${_count} - 1" | bc)"
547
548   ifconfig ${1} | grep -w inet | tail -${_count} | awk '{ print $2 }'
549}
550
551get_interface_ipv6_aliases()
552{
553   local _count
554
555   _count=`ifconfig ${1} | grep -w inet | wc -l`
556   _count="$(echo "${_count} - 1" | bc)"
557
558   ifconfig ${1} | grep -w inet6 | tail -${_count} | awk '{ print $2 }'
559}
560
561get_default_route()
562{
563   netstat -f inet -nr | grep '^default' | awk '{ print $2 }'
564}
565
566get_default_interface()
567{
[18313bb]568   local iface
569   iface=`netstat -f inet -nrW | grep '^default' | awk '{ print $7 }'`
570   if [ -z "$iface" ] ; then
571     # For 10.1 and later
572     iface=`netstat -f inet -nrW | grep '^default' | awk '{ print $6 }'`
573   fi
574   echo $iface
[1620346]575}
576
577get_bridge_interfaces()
578{
579   ifconfig -a | grep -E '^bridge[0-9]+' | cut -f1 -d:
580}
581
582get_bridge_members()
583{
584   ifconfig ${1} | grep -w member | awk '{ print $2 }'
585}
586
587get_bridge_interface_by_ipv4_network()
588{
589   local network="${1}"
590   local bridges="$(get_bridge_interfaces)"
591
592   if [ -z "${network}" ]
593   then
594      return 1
595   fi
596
597   for _bridge in ${bridges}
598   do
599      local ips="$(get_interface_ipv4_aliases "${_bridge}")"
600      for _ip in ${ips}
601      do
602         if in_ipv4_network "${_ip}" "${network}"
603         then
604            echo "${_bridge}"
605            return 0
606         fi
607      done
608   done
609
610   return 1
611}
612
613get_bridge_interface_by_ipv6_network()
614{
615   local network="${1}"
616   local bridges="$(get_bridge_interfaces)"
617
618   if [ -z "${network}" ]
619   then
620      return 1
621   fi
622
623   for _bridge in ${bridges}
624   do
625      local ips="$(get_interface_ipv6_aliases "${_bridge}")"
626      for _ip in ${ips}
627      do
628         if in_ipv6_network "${_ip}" "${network}"
629         then
630            echo "${_bridge}"
631            return 0
632         fi
633      done
634   done
635
636   return 1
637}
638
639is_bridge_member()
640{
641   local _bridge="${1}"
642   local _iface="${2}"
643
644   for _member in `get_bridge_members ${_bridge}`
645   do
646      if [ "${_member}" = "${_iface}" ] ; then
647         return 0
648      fi
649   done
650
651   return 1
652}
653
654jail_interfaces_down()
655{
656   local _jid="${1}"
657   local _bridgeif
658   local _epaira
659   local _epairb
660
661   _epairb=`jexec ${_jid} ifconfig -a | grep '^epair' | cut -f1 -d:`
662   if [ -n "${_epairb}" ] ; then
663      _epaira=`echo ${_epairb} | sed -E 's|b$|a|'`
664      _bridgeif=
665
666      for _bridge in `ifconfig -a | grep -E '^bridge[0-9]+' | cut -f1 -d:`
667      do
668         for _member in `ifconfig ${_bridge} | grep member | awk '{ print $2 }'`
669         do
670            if [ "${_member}" = "${_epaira}" ] ; then
671               _bridgeif="${_bridge}"
672                break
673            fi
674         done
675         if [ -n "${_bridgeif}" ] ; then
676            break
677         fi
678      done
679
680      jexec ${_jid} ifconfig ${_epairb} down
681      ifconfig ${_epaira} down
682      ifconfig ${_epaira} destroy
683      _count=`ifconfig ${_bridgeif} | grep member | awk '{ print $2 }' | wc -l`
[2a7010e]684      if [ "${_count}" -lt "1" ] ; then
[1620346]685         ifconfig ${_bridgeif} destroy
686      fi
687   fi
688}
689
690enable_cron()
691{
692   cronscript="${PROGDIR}/scripts/backend/cronsnap.sh"
693   grep -q "${cronscript}" /etc/crontab
694   if [ $? -eq 0 ] ; then return 0 ; fi
695   echo "2     *        *       *       *        root    ${cronscript}" >> /etc/crontab
696   # Restart cron
697   /etc/rc.d/cron restart >/dev/null 2>/dev/null
698}
699
700fix_old_meta()
701{
702   for i in `ls -d ${JDIR}/.*.meta 2>/dev/null`
703   do
704      if [ -e "${i}/xjail" ] ; then
705         touch ${i}/jail-portjail 2>/dev/null
706      fi
707      if [ -e "${i}/linuxjail" ] ; then
708         touch ${i}/jail-linux 2>/dev/null
709      fi
710   done
711}
712
713is_ipv4()
714{
715   local addr="${1}"
716   local res=1
717
718   local ipv4="$(/usr/local/bin/sipcalc "${addr}"|head -1|cut -f2 -d'['|awk '{ print $1 }')"
719   if [ "${ipv4}" = "ipv4" ]
720   then
721      res=0
722   fi
723
724   return ${res}
725}
726
727is_ipv6()
728{
729   local addr="${1}"
730   local res=1
731
732   local ipv6="$(/usr/local/bin/sipcalc "${addr}"|head -1|cut -f2 -d'['|awk '{ print $1 }')"
733   if [ "${ipv6}" = "ipv6" ]
734   then
735      res=0
736   fi
737
738   return ${res}
739}
740
741in_ipv4_network()
742{
743   local addr="${1}"
744   local network="${2}"
745   local res=1
746
747   local start="$(/usr/local/bin/sipcalc "${network}"|awk '/^Usable/ { print $4 }')"
748   local end="$(/usr/local/bin/sipcalc "${network}"|awk '/^Usable/ { print $6 }')"
749
750   local iaddr="$(/usr/local/bin/sipcalc "${addr}"|awk '/(decimal)/ { print $5 }')"
751   local istart="$(/usr/local/bin/sipcalc "${start}"|awk '/(decimal)/ { print $5 }')"
752   local iend="$(/usr/local/bin/sipcalc "${end}"|awk '/(decimal)/ { print $5 }')"
753
754   if [ "${iaddr}" -ge "${istart}" -a "${iaddr}" -le "${iend}" ]
755   then
756      res=0
757   fi
758
759   return ${res}
760}
761
762ipv6_to_binary()
763{
764   echo ${1}|awk '{
765      split($1, octets, ":");
766      olen = length(octets);
767               
768      bnum = "";
769      for (i = 1;i <= olen;i++) {
770         tbnum = "";
771         dnum = int(sprintf("0x%s", octets[i]));
772         for (;;) {
773            rem = int(dnum % 2);
774            if (rem == 0)
775               tbnum = sprintf("0%s", tbnum);
776            else               
777               tbnum = sprintf("1%s", tbnum);
778            dnum /= 2;
779            if (dnum < 1)
780               break;
781         }
782         bnum = sprintf("%s%016s", bnum, tbnum);
783      }
784      printf("%s", bnum);
785   }'
786}
787
788in_ipv6_network()
789{
790   local addr="${1}"
791   local network="${2}"
792   local mask="$(echo "${network}"|cut -f2 -d'/' -s)"
793   local res=1
794
795   local addr="$(/usr/local/bin/sipcalc "${addr}"|awk \
796      '/^Expanded/ { print $4}')"
797   local start="$(/usr/local/bin/sipcalc "${network}"|egrep \
798      '^Network range'|awk '{ print $4 }')"
799
800   local baddr="$(ipv6_to_binary "${addr}")"
801   local bstart="$(ipv6_to_binary "${start}")"
802
803   local baddrnet="$(echo "${baddr}"|awk -v mask="${mask}" \
804      '{ s = substr($0, 1, mask); printf("%s", s); }')"
805   local bstartnet="$(echo "${bstart}"|awk -v mask="${mask}" \
806      '{ s = substr($0, 1, mask); printf("%s", s); }')"
807
808   if [ "${baddrnet}" = "${bstartnet}" ]
809   then
810      res=0
811   fi
812
813   return ${res}
814}
815
816make_bootstrap_pkgng_file_standard()
817{
818  local jaildir="${1}"
819  local outfile="${2}"
820
[c2b5aad]821  if [ ! -e "${jaildir}/bin/freebsd-version" ] ; then
822     echo "Missing /bin/freebsd-version in jail.."
823     echo "PKG bootstrap can only be done on 10.0 and higher, skipping..."
824     return 1
825  fi
826
[22bfc1e]827  # Setup the repo to use the XX.0-RELEASE pkgng branch
828  local release="`${jaildir}/bin/freebsd-version | cut -d '-' -f 1 |  cut -d '.' -f 1`.0-RELEASE"
[1620346]829  local arch="$(uname -m)"
830
831cat<<__EOF__>"${outfile}"
832#!/bin/sh
833tar xvf pkg.txz --exclude +MANIFEST --exclude +MTREE_DIRS 2>/dev/null
834pkg add pkg.txz
835rm pkg.txz
836
[d6345ef]837# Create the pkg.conf file
838echo "PKG_CACHEDIR: /usr/local/tmp
[7f6bcbe]839REPOS_DIR: [
[d6345ef]840                \"/usr/local/etc/pkg/repos\"
841           ]" > /usr/local/etc/pkg.conf
842
843# Create the repo dirs
844mkdir -p /usr/local/etc/pkg/repos 2>/dev/null
845mkdir -p /usr/local/etc/pkg/fingerprints/pcbsd/trusted 2>/dev/null
846mkdir -p /usr/local/etc/pkg/fingerprints/pcbsd/revoked 2>/dev/null
847
848# Save the repo configuration file
[22bfc1e]849echo "pcbsd-major: {
[d6345ef]850               url: \"http://pkg.cdn.pcbsd.org/${release}/${arch}\",
851               signature_type: \"fingerprints\",
852               fingerprints: \"/usr/local/etc/pkg/fingerprints/pcbsd\",
853               enabled: true
854              }" > /usr/local/etc/pkg/repos/pcbsd.conf
855
[22bfc1e]856# Create the repo.dist file
857echo "pcbsd: {
858               url: \"http://pkg.cdn.pcbsd.org/VERSION/ARCH\",
859               signature_type: \"fingerprints\",
860               fingerprints: \"/usr/local/etc/pkg/fingerprints/pcbsd\",
861               enabled: true
862              }" > /usr/local/etc/pkg/repos/pcbsd.conf.dist
863
[d6345ef]864# Save the fingerprint file
865echo "function: sha256
866fingerprint: b2b9e037f938cf20ba68aa85ac88c15889c729a7f6b70c25069774308e760a03" > /usr/local/etc/pkg/fingerprints/pcbsd/trusted/pkg.cdn.pcbsd.org.20131209
867
[21d3050]868pkg update -f
[6cf118f]869
[001f7a3]870exit 0
[1620346]871__EOF__
[d6345ef]872
[1620346]873}
874
875make_bootstrap_pkgng_file_pluginjail()
876{
877
878  local jaildir="${1}"
879  local outfile="${2}"
880
[c2b5aad]881  if [ ! -e "${jaildir}/bin/freebsd-version" ] ; then
882     echo "Missing /bin/freebsd-version in jail.."
883     echo "PKG bootstrap can only be done on 10.0 and higher, skipping..."
884     return 0
885  fi
886
[22bfc1e]887  # Setup the repo to use the XX.0-RELEASE pkgng branch
888  local release="`${jaildir}/bin/freebsd-version | cut -d '-' -f 1 |  cut -d '.' -f 1`.0-RELEASE"
[1620346]889  local arch="$(uname -m)"
890
891  get_mirror
892  local mirror="${VAL}"
893
894  cp /usr/local/share/warden/pluginjail-packages "${jaildir}/pluginjail-packages"
895
896cat<<__EOF__>"${outfile}"
897#!/bin/sh
898tar xvf pkg.txz --exclude +MANIFEST --exclude +MTREE_DIRS 2>/dev/null
899pkg add pkg.txz
900rm pkg.txz
901
902mount -t devfs devfs /dev
903
[d6345ef]904# Create the pkg.conf file
905echo "PKG_CACHEDIR: /usr/local/tmp
[7f6bcbe]906REPOS_DIR: [
[d6345ef]907                \"/usr/local/etc/pkg/repos\"
908           ]" > /usr/local/etc/pkg.conf
909
910# Create the repo dirs
911mkdir -p /usr/local/etc/pkg/repos 2>/dev/null
912mkdir -p /usr/local/etc/pkg/fingerprints/pcbsd/trusted 2>/dev/null
913mkdir -p /usr/local/etc/pkg/fingerprints/pcbsd/revoked 2>/dev/null
914
915# Save the repo configuration file
[22bfc1e]916echo "pcbsd-major: {
[d6345ef]917               url: \"http://pkg.cdn.pcbsd.org/${release}/${arch}\",
918               signature_type: \"fingerprints\",
919               fingerprints: \"/usr/local/etc/pkg/fingerprints/pcbsd\",
920               enabled: true
921              }" > /usr/local/etc/pkg/repos/pcbsd.conf
922
[13a6b08]923# Create the repo.dist file
924echo "pcbsd: {
925               url: \"http://pkg.cdn.pcbsd.org/VERSION/ARCH\",
926               signature_type: \"fingerprints\",
927               fingerprints: \"/usr/local/etc/pkg/fingerprints/pcbsd\",
928               enabled: true
929              }" > /usr/local/etc/pkg/repos/pcbsd.conf.dist
930
[d6345ef]931# Save the fingerprint file
932echo "function: sha256
933fingerprint: b2b9e037f938cf20ba68aa85ac88c15889c729a7f6b70c25069774308e760a03" > /usr/local/etc/pkg/fingerprints/pcbsd/trusted/pkg.cdn.pcbsd.org.20131209
934
[21d3050]935pkg update -f
[22bfc1e]936
[1620346]937__EOF__
938
939echo '
940i=0
941count=`wc -l /pluginjail-packages| awk "{ print $1 }"`
942for p in `cat /pluginjail-packages`
943do
944  pkg install -y ${p}
945  : $(( i += 1 ))
946done
947
948umount devfs
949exit $?
950' >> "${outfile}"
951}
952
953
954bootstrap_pkgng()
955{
956  local jaildir="${1}"
957  local jailtype="${2}"
958  if [ -z "${jailtype}" ] ; then
959    jailtype="standard"
960  fi
[c2b5aad]961
962  if [ ! -e "${jaildir}/bin/freebsd-version" ] ; then
963     echo "Missing /bin/freebsd-version in jail.."
964     echo "PKG bootstrap can only be done on 10.0 and higher, skipping..."
965     return 1
966  fi
967
[22bfc1e]968  local release="`${jaildir}/bin/freebsd-version | cut -d '-' -f 1 |  cut -d '.' -f 1`.0-RELEASE"
[1620346]969  local arch="$(uname -m)"
970
971  local ffunc="make_bootstrap_pkgng_file_standard"
972  if [ "${jailtype}" = "pluginjail" ] ; then
973    ffunc="make_bootstrap_pkgng_file_pluginjail"
974  fi
975
976  cd ${jaildir} 
977  echo "Boot-strapping pkgng"
978
979  mkdir -p ${jaildir}/usr/local/etc
980
981
982  ${ffunc} "${jaildir}" "${jaildir}/bootstrap-pkgng"
983  chmod 755 "${jaildir}/bootstrap-pkgng"
984
985  if [ -e "pkg.txz" ] ; then rm pkg.txz ; fi
[9788f38]986  get_file_from_mirrors "/${release}/${arch}/Latest/pkg.txz" "pkg.txz" "pkg"
[1620346]987  if [ $? -eq 0 ] ; then
988    chroot ${jaildir} /bootstrap-pkgng
989    if [ $? -eq 0 ] ; then
990      rm -f "${jaildir}/bootstrap-pkgng"
991      rm -f "${jaildir}/pluginjail-packages"
992      return 0
993    fi
994  fi
995
996  echo "Failed boot-strapping PKGNG, most likely cause is internet connection failure."
997  rm -f "${jaildir}/bootstrap-pkgng"
998  rm -f "${jaildir}/pluginjail-packages"
999  return 1
1000}
1001
1002ipv4_configured()
1003{
1004   local iface="${1}"
1005   local jid="${2}"
1006   local jexec=
1007
1008   if [ -n "${jid}" ] ; then
1009      jexec="jexec ${jid}"
1010   fi
1011
1012   ${jexec} ifconfig "${iface}" | grep -qw inet 2>/dev/null
1013   return $?
1014}
1015
1016ipv4_address_configured()
1017{
1018   local iface="${1}"
1019   local addr="${2}"
1020   local jid="${3}"
1021   local jexec= 
1022
1023   addr="$(echo ${addr}|cut -f1 -d'/')"
1024
1025   if [ -n "${jid}" ] ; then
1026      jexec="jexec ${jid}"
1027   fi
1028
1029   ${jexec} ifconfig "${iface}" | \
1030      grep -w inet | \
1031      awk '{ print $2 }' | \
1032      grep -Ew "^${addr}" >/dev/null 2>&1
1033   return $?
1034}
1035
1036ipv6_configured()
1037{
1038   local iface="${1}"
1039   local jid="${2}"
1040   local jexec=
1041
1042   if [ -n "${jid}" ] ; then
1043      jexec="jexec ${jid}"
1044   fi
1045
1046   ${jexec} ifconfig "${iface}" | grep -qw inet6 2>/dev/null
1047   return $?
1048}
1049
1050ipv6_address_configured()
1051{
1052   local iface="${1}"
1053   local addr="${2}"
1054   local jid="${3}"
1055   local jexec= 
1056
1057   addr="$(echo ${addr}|cut -f1 -d'/')"
1058
1059   if [ -n "${jid}" ] ; then
1060      jexec="jexec ${jid}"
1061   fi
1062
1063   ${jexec} ifconfig "${iface}" | \
1064      grep -w inet6 | \
1065      awk '{ print $2 }' | \
1066      grep -Ew "^${addr}" >/dev/null 2>&1
1067   return $?
1068}
1069
1070get_ipfw_nat_instance()
1071{
1072   local iface="${1}"
1073   local res=1
1074
1075   if [ -z "${iface}" ] ; then
1076      local instance="`ipfw list|egrep '[0-9]+ nat'|awk '{ print $3 }'|tail -1`"
1077      if [ -z "${instance}" ] ; then
1078         instance="100"
1079      else               
1080         : $(( instance += 100 )) 
1081      fi
1082      echo "${instance}"
1083      return 0
1084   fi
1085
1086   for ni in `ipfw list|egrep '[0-9]+ nat'|awk '{ print $3 }'`
1087   do
1088      ipfw nat "${ni}" show config|egrep -qw "${iface}"
1089      if [ "$?" = "0" ] ; then
1090         echo "${ni}"
1091         res=0
1092         break
1093      fi
1094   done
1095
1096   return ${res}
1097}
1098
1099get_ipfw_nat_priority()
1100{
1101   local iface="${1}"
1102   local res=1
1103
1104   if [ -z "${iface}" ] ; then
1105      local priority="`ipfw list|egrep '[0-9]+ nat'|awk '{ print $1 }'|tail -1`"
1106      if [ -z "${priority}" ] ; then
1107         priority=2000
1108      fi
1109      printf "%05d\n" "${priority}"
1110      return 0
1111   fi
1112
1113   local IFS='
1114'
1115   for rule in `ipfw list|egrep '[0-9]+ nat'`
1116   do
1117      local priority="`echo "${rule}"|awk '{ print $1 }'`"
1118      local ni="`echo "${rule}"|awk '{ print $3 }'`"
1119
1120      ipfw nat "${ni}" show config|egrep -qw "${iface}"
1121      if [ "$?" = "0" ] ; then
1122         echo "${priority}"
1123         res=0
1124         break
1125      fi
1126   done
1127
1128   return ${res}
1129}
1130
[101a6c2]1131list_templates()
1132{
1133   echo "Jail Templates:"
1134   echo "------------------------------" 
[4905ba9]1135   for i in `ls -d ${JDIR}/.warden-template* 2>/dev/null`
1136   do
1137     if [ ! -e "$i/bin/sh" ] ; then continue ; fi
1138     NICK=`echo "$i" | sed "s|${JDIR}/.warden-template-||g"`
1139     file "$i/bin/sh" 2>/dev/null | grep -q "64-bit"
1140     if [ $? -eq 0 ] ; then
1141        ARCH="amd64"
1142     else
1143        ARCH="i386"
1144     fi
1145     VER=`file "$i/bin/sh" | cut -d ',' -f 5 | awk '{print $3}'`
1146     if [ -e "$i/etc/rc.conf.pcbsd" ] ; then
1147        TYPE="TrueOS"
1148     else
1149        TYPE="FreeBSD"
1150     fi
1151     echo -e "${NICK} - $TYPE $VER ($ARCH)"
1152  done
1153  exit 0
[101a6c2]1154}
1155
1156delete_template()
1157{
[283f63e]1158   tDir="${JDIR}/.warden-template-${1}"
[4905ba9]1159   isDirZFS "${tDir}" "1"
1160   if [ $? -ne 0 ] ; then printerror "Not a ZFS volume: ${tDir}" ; fi
[698a249]1161
1162   # Get the dataset of the jails mountpoint
1163   rDataSet=`mount | grep "on ${tDir} " | awk '{print $1}'`
1164
1165   zfs destroy -r ${rDataSet}
[4905ba9]1166   if [ $? -ne 0 ] ; then
1167     exit_err "Could not remove template, perhaps you have jails still using it?"
[283f63e]1168   fi
[4905ba9]1169   rmdir ${tDir}
[f70de07]1170   echo "DONE"
[101a6c2]1171
[283f63e]1172   exit 0
[101a6c2]1173}
[d2b5358]1174
1175get_ip_host_flags()
1176{
1177         IP4="OFF"
1178         IP6="OFF"
1179         HOST="OFF"
1180         for i in "$@"
1181         do
1182           # Check if we have a new IPv4 address for this import
1183           echo "${i}" | grep '\-\-ipv4=' >/dev/null 2>/dev/null
1184           if [ "$?" = "0" ]; then
1185              tmp="`echo ${i} | cut -d '=' -f 2`"
1186              IP4="`echo ${tmp} | cut -d '/' -f 1 -s`"
1187              MASK4="`echo ${tmp} | cut -d '/' -f 2 -s`"
1188
1189              #Sanity check on the IP
1190              if ! is_ipv4 "${IP4}" ; then
1191                 exit_err "Invalid IPv4 address: $IP4"
1192              fi
1193
1194              for i in `ls -d ${JDIR}/.*.meta 2>/dev/null`
1195              do
1196                if [ "`cat ${i}/ipv4 2>/dev/null`" = "${IP4}/${MASK4}" ] ; then
1197                  exit_err "A jail with this IPv4 address already exists!"
1198                fi
1199              done
1200           fi
1201
1202           # Check if we have a new IPv6 address for this import
1203           echo "${i}" | grep '\-\-ipv6=' >/dev/null 2>/dev/null
1204           if [ "$?" = "0" ]; then
1205              tmp="`echo ${i} | cut -d '=' -f 2`"
1206              IP6="`echo ${tmp} | cut -d '/' -f 1 -s`"
1207              MASK6="`echo ${tmp} | cut -d '/' -f 2 -s`"
1208
1209              #Sanity check on the IP
1210              if ! is_ipv6 "${IP6}" ; then
1211                 exit_err "Invalid IPv6 address!"
1212              fi
1213
1214              for i in `ls -d ${JDIR}/.*.meta 2>/dev/null`
1215              do
1216                _ipv6=`cat ${i}/ipv6 2>/dev/null | tr a-z A-Z`
1217                _nipv6="`echo ${IP6}|tr a-z A-Z`/${MASK6}"
1218
1219                if [ "${_ipv6}" = "${_nipv6}" ] ; then
1220                  exit_err "A jail with this IPv6 address already exists!"
1221                fi
1222              done
1223           fi
1224
1225           # Check if we have a new hostname for this jail
1226           echo ${i} | grep '\-\-host=' >/dev/null 2>/dev/null
1227           if [ "$?" = "0" ]; then
1228              HOST="`echo ${i} | cut -d '=' -f 2`"
1229           fi
1230
1231         done
1232
1233}
[4905ba9]1234
1235zfs_prog_check() {
1236
[ccc354d]1237   local testDataSet=`mount | grep "on ${JDIR} " | awk '{print $1}'`
1238   if [ -z "$testDataSet" ] ; then
[4905ba9]1239      echo "WARNING: JDIR is NOT set to a ZFS managed dataset.."
[ccc354d]1240      echo "Please change JDIR in /usr/local/etc/warden.conf to a valid, mounted ZFS dataset!"
1241      exit 1
[4905ba9]1242   fi
1243
1244}
[bb6487e]1245
1246stop_jail_savestate()
1247{
1248  # Check if the jail is running first
1249  ${PROGDIR}/scripts/backend/checkstatus.sh "${JAILNAME}"
1250  if [ "$?" = "0" ]; then
1251    stateRestartJail="YES"
1252    # Make sure the jail is stopped
1253    ${PROGDIR}/scripts/backend/stopjail.sh "${JAILNAME}"
1254    ${PROGDIR}/scripts/backend/checkstatus.sh "${JAILNAME}"
1255    if [ "$?" = "0" ]; then
1256       exit_err "Failed to stop jail: $JAILNAME..."
1257    fi
1258  fi
1259}
1260
1261start_jail_savedstate()
1262{
1263  if [ "$stateRestartJail" = "YES" ] ; then
1264    ${PROGDIR}/scripts/backend/startjail.sh "${JAILNAME}"
1265  fi
1266}
1267
1268##############################################################
1269# Functions for upgrading jails
1270##############################################################
1271
1272echo_logout()
1273{
1274  echo "$@"
1275  echo "$@" >> ${LOGOUT}
1276}
1277
1278set_update_vars()
1279{
1280  unset EVENT_PIPE
1281
1282  # Set some locations
1283  STAGEMNT="$JAILDIR"
1284  LOGOUT="/var/log/warden-update.log"
1285  OLDPKGLIST="/tmp/.pkgUpdateList.$$"
1286  NEWPKGLIST="/tmp/.newPkgUpdateList.$$"
1287  PKGUPGRADELOG="/tmp/.pkgUpdateLog.$$"
1288  PKGDLCACHE="/usr/local/pkg-cache"
1289  PKG_CMD="chroot ${JAILDIR} /usr/sbin/pkg"
1290  echo "" > $LOGOUT
1291
1292  # Some basic sanity tests
1293  if [ ! -d "$JAILDIR" -o "$JAILDIR" = "/" ] ; then
1294     exit_err "Invalid JAILDIR"
1295  fi
1296  chroot ${STAGEMNT} freebsd-version 2>/dev/null >/dev/null
1297  if [ $? -ne 0 ] ; then
1298     exit_err "Needs FreeBSD > 10 to do updates"
1299  fi
1300}
1301
1302update_freebsd()
1303{
1304
1305  set_update_vars
1306
1307  stop_jail_savestate
1308
1309  mk_snapshot "FreeBSD update snapshot"
1310
1311  run_freebsd_update_script
1312
1313  start_jail_savedstate
1314  echo_logout "Your security update is finished!"
1315  exit 0
1316}
1317
1318
1319update_pkgs_only()
1320{
1321  set_update_vars
1322
1323  mk_pkg_conf
1324  build_pkg_list
1325  dl_pkgs
1326
1327  stop_jail_savestate
1328
1329  mk_snapshot "Pkg update snapshot"
1330  prep_pkgs_chroot
1331  install_pkgs_chroot
1332
1333  start_jail_savedstate
1334
1335  echo_logout "Your package update is finished!"
1336  exit 0
1337}
1338
1339update_world_and_pkgs()
1340{
1341  # Set the new version of FreeBSD we are installing
1342  NEWFREEBSDVERSION="$1"
1343
1344  set_update_vars
1345
1346  mk_pkg_conf
1347  build_pkg_list
1348  dl_pkgs
1349
1350  stop_jail_savestate
1351
1352  mk_snapshot "FreeBSD upgrade snapshot"
1353  run_freebsd_upgrade_script
1354  prep_pkgs_chroot
1355  install_pkgs_chroot
1356
1357  start_jail_savedstate
1358  echo_logout "Your FreeBSD upgrade is finished!"
1359  exit 0
1360}
1361
1362mk_pkg_conf()
1363{
1364   PKG_FLAG=""
1365   PKG_CFLAG=""
1366
1367   if [ ! -d "${JAILDIR}/${PKGDLCACHE}" ] ; then
1368     mkdir -p ${JAILDIR}/${PKGDLCACHE}
1369   fi
1370
1371   # Get rid of FreeBSD.conf repo
1372   if [ -e "${JAILDIR}/etc/pkg/FreeBSD.conf" ] ; then
1373      rm ${JAILDIR}/etc/pkg/FreeBSD.conf
1374   fi
1375
1376   # Set the cache directory
1377   PKG_CFLAG="-C /tmp/.pkgUpdate.conf"
1378   echo "PKG_CACHEDIR: $PKGDLCACHE" > ${JAILDIR}/tmp/.pkgUpdate.conf
1379
1380   # If doing a major update also, add the new repos config
1381   if [ -n "$NEWFREEBSDVERSION" ] ; then
1382      setup_pkgng_newrepo_conf
1383   fi
1384}
1385
1386setup_pkgng_newrepo_conf() {
1387
1388  # Lets create a new repo file to match the version of BSD we are upgrading to
1389
[d186df2]1390  # Set the new ABI
1391  ABIVER="`echo $NEWFREEBSDVERSION | cut -d '-' -f 1 | cut -d '.' -f 1`"
1392  pV="`${PKG_CMD} ${PKG_FLAG} query '%v' ports-mgmt/pkg`"
1393  echo $pV | grep -q '^1.3'
1394  if [ $? -eq 0 ] ; then
1395    PKG_FLAG="$PKG_FLAG -o ABI=freebsd:$ABIVER:x86:64"
1396  else
1397    PKG_FLAG="$PKG_FLAG -o ABI=freebsd:$ABIVER:`uname -m`"
1398  fi
[bb13496]1399  #echo "Setting ABI with: ${PKG_FLAG}"
[d186df2]1400
[bb6487e]1401  # See if we need to adjust pcbsd.conf repo file
1402  if [ ! -e "/usr/local/etc/pkg/repos/pcbsd.conf.dist" ];then
1403     echo_logout "ERROR: Missing /usr/local/etc/pkg/repos/pcbsd.conf.dist"
1404     exit 1
1405  fi
1406
1407  ARCH=`uname -m`
1408  FBSDVER="$NEWFREEBSDVERSION"
1409  MAJORVER="`echo $FBSDVER | cut -d '-' -f 1 |  cut -d '.' -f 1`.0-RELEASE"
1410
1411  # Make sure we are on a -RELEASE or -STABLE, otherwise use the proper uname
1412  echo $FBSDVER | grep -q -e 'RELEASE' -e 'STABLE'
1413  if [ $? -ne 0 ] ; then MAJORVER="$FBSDVER"; fi
1414
1415  # If using the EDGE package set, set the right path
1416  case $PACKAGE_SET in
1417       EDGE) FBSDVER="$FBSDVER/edge"
1418             MAJORVER="$MAJORVER/edge"
1419             ;;
1420          *) ;;
1421  esac
1422
1423  rm -rf ${JAILDIR}/tmp/.updateRepo >/dev/null 2>/dev/null
1424  mkdir ${JAILDIR}/tmp/.updateRepo
1425
1426  # Now create standard pcbsd.conf file
1427  if [ "$PACKAGE_SET" = "CUSTOM" -a -n "$CUSTOM_URL" ] ; then
1428     # Change %VERSION% / %ARCH% keys
1429     CUSTOM_URL=`echo $CUSTOM_URL | sed "s|%VERSION%|$MAJORVER|g" | sed "s|%ARCH%|$ARCH|g"`
1430     cat << EOF >${JAILDIR}/tmp/.updateRepo/pkgUpdateRepo.conf
1431pcbsd-major: {
1432               url: "$CUSTOM_URL",
1433               signature_type: "fingerprints",
1434               fingerprints: "/usr/local/etc/pkg/fingerprints/pcbsd",
1435               enabled: true
1436              }
1437EOF
1438  else
1439    # Using PC-BSD CDN
1440    cat /usr/local/etc/pkg/repos/pcbsd.conf.dist \
1441      | sed "s|pcbsd: |pcbsd-major: |g" \
1442      | sed "s|%VERSION%|$MAJORVER|g" \
1443      | sed "s|%ARCH%|$ARCH|g" \
1444      | sed "s|VERSION|$MAJORVER|g" \
1445      | sed "s|ARCH|$ARCH|g" > ${JAILDIR}/tmp/.updateRepo/pkgUpdateRepo.conf
1446  fi
1447
1448  # Set the new PKG_FLAG to use this repo config
[a6e6439]1449  PKG_FLAG="-R /tmp/.updateRepo ${PKG_FLAG}"
[fb46926]1450
[bb6487e]1451}
1452
1453build_pkg_list()
1454{
1455  # Build top-level list of pkgs installed
1456  echo_logout "Getting list of packages..."
1457  ${PKG_CMD} query -e '%#r=0' '%o %n-%v' | sort | grep -v 'ports-mgmt/pkg ' > $OLDPKGLIST
1458
1459  echo "Original top-level packages:" > $PKGUPGRADELOG
1460  echo "-----------------------------------------------" >> $PKGUPGRADELOG
1461  cat $OLDPKGLIST >> $PKGUPGRADELOG
1462  echo "-----------------------------------------------" >> $PKGUPGRADELOG
1463}
1464
1465dl_pkgs()
1466{
1467  # Update the DB first
1468  echo_logout "Updating the package repo database..."
1469  ${PKG_CMD} ${PKG_FLAG} update -f >${LOGOUT} 2>${LOGOUT}
1470
1471  # Clean pkgs
1472  echo_logout "Cleaning old pkg upgrade cache..."
1473  ${PKG_CMD} ${PKG_CFLAG} ${PKG_FLAG} clean -y >${LOGOUT} 2>${LOGOUT}
1474
1475  if [ -e "$NEWPKGLIST" ] ; then rm $NEWPKGLIST; fi
1476
1477  # Save the PKGNG filename
1478  PKGFILENAME="`${PKG_CMD} ${PKG_FLAG} rquery -U '%n-%v' ports-mgmt/pkg 2>/dev/null | head -n 1`.txz"
1479
1480  # First off, fetch the pkgng pkg
1481  echo_logout "Fetching packages for ports-mgmt/pkg - $PKGFILENAME"
1482  ${PKG_CMD} ${PKG_CFLAG} ${PKG_FLAG} fetch -U -d -y ports-mgmt/pkg >/tmp/.pkgOut.$$ 2>/tmp/.pkgOut.$$
1483  if [ $? -ne 0 ] ; then
1484     cat /tmp/.pkgOut.$$
1485     cat /tmp/.pkgOut.$$ >> $LOGOUT
1486     cat /tmp/.pkgOut.$$ >> $PKGUPGRADELOG
1487     exit_err "Failed fetching: ports-mgmt/pkg - $PKGFILENAME"
1488  fi
1489
1490  CHROOTREALPKGDLCACHE="${PKGDLCACHE}"
1491  REALPKGDLCACHE="${JAILDIR}/${PKGDLCACHE}"
1492  # PKGNG lies, we need to verify if the package was really downloaded
1493  if [ ! -e "${JAILDIR}/${PKGDLCACHE}/${PKGFILENAME}" ] ; then
1494     # Also check All/ since pkg docs are rather unclear about if that will be used or not
1495     if [ -e "${JAILDIR}/${PKGDLCACHE}/All/${PKGFILENAME}" ] ; then
1496        CHROOTREALPKGDLCACHE="${PKGDLCACHE}/All"
1497        REALPKGDLCACHE="${JAILDIR}/${PKGDLCACHE}/All"
1498     else
1499        exit_err "Failed downloading ports-mgmt/pkg with: $PKG_CMD $PKG_FLAG fetch -d -y ports-mgmt/pkg"
1500     fi
1501  fi
1502
1503  # Create the NEWPKGLIST
1504  touch $NEWPKGLIST
1505
1506  # Now start fetching all the update packages
1507  while read pkgLine
1508  do
1509    pkgOrigin="`echo $pkgLine | cut -d ' ' -f 1`"
1510    pkgName="`echo $pkgLine | cut -d ' ' -f 2`"
1511
1512    # Check if this pkg exists in the new repo
1513    unset FETCHFILENAME
1514    FETCHFILENAME="`${PKG_CMD} ${PKG_FLAG} rquery -U '%n-%v' $pkgOrigin 2>/dev/null | head -n 1`"
1515    if [ -z "$FETCHFILENAME" ] ; then
1516       echo_logout "*****"
1517       echo_logout "No such package in new repo: $pkgOrigin"
1518       echo_logout "*****" >> $LOGOUT
1519       echo "*****" >> $PKGUPGRADELOG
1520       echo "No such package in new repo: $pkgOrigin" >> $PKGUPGRADELOG
1521       echo "*****" >> $PKGUPGRADELOG
1522       continue
1523    fi
1524    FETCHFILENAME="${FETCHFILENAME}.txz"
1525
1526    # Fetch the pkg now
1527    echo_logout "Fetching packages for ${pkgOrigin} - $FETCHFILENAME"
1528    echo "Fetching packages for ${pkgOrigin} - $FETCHFILENAME" >> ${PKGUPGRADELOG}
1529    ${PKG_CMD} ${PKG_CFLAG} ${PKG_FLAG} fetch -U -d -y $pkgOrigin >/tmp/.pkgOut.$$ 2>/tmp/.pkgOut.$$
1530    if [ $? -ne 0 ] ; then
1531       echo "*****" >> $PKGUPGRADELOG
1532       echo_logout "Failed fetching: $pkgOrigin"
1533       cat /tmp/.pkgOut.$$
1534       cat /tmp/.pkgOut.$$ >> $LOGOUT
1535       echo_logout "*****"
1536
1537       echo "*****" >> $PKGUPGRADELOG
1538       echo "Failed fetching: $pkgOrigin" >> $PKGUPGRADELOG
1539       cat /tmp/.pkgOut.$$ >> $PKGUPGRADELOG
1540       echo "*****" >> $PKGUPGRADELOG
1541    fi
1542
1543    # PKGNG lies, we need to verify if the package was really downloaded
1544    if [ ! -e "${REALPKGDLCACHE}/${FETCHFILENAME}" ] ; then
1545       echo_logout "*****"
1546       echo_logout "Failed fetching: $pkgOrigin - $FETCHFILENAME"
1547       cat /tmp/.pkgOut.$$
1548       cat /tmp/.pkgOut.$$ >> $LOGOUT
1549       echo_logout "*****"
1550
1551       echo "*****" >> $PKGUPGRADELOG
1552       echo "Failed fetching: $pkgOrigin - $FETCHFILENAME" >> $PKGUPGRADELOG
1553       cat /tmp/.pkgOut.$$ >> $PKGUPGRADELOG
1554       echo "*****" >> $PKGUPGRADELOG
1555       echo "Failed downloading $pkgOrigin with: $PKG_CMD $PKG_FLAG fetch -d -y $pkgOrigin"
1556    fi
1557    echo "$pkgOrigin $FETCHFILENAME" >> $NEWPKGLIST
1558  done < $OLDPKGLIST
1559
1560  # Copy the list of packages to install
1561  rc_halt "cp $NEWPKGLIST ${JAILDIR}/install-pkg-list"
1562
1563  echo_logout "-----------------------------------------------"
1564  echo "-----------------------------------------------" >> ${PKGUPGRADELOG}
1565}
1566
1567do_prune_auto_snaps()
1568{
1569  # Get list of snaps
1570  snaps=$(listZFSSnap "${JAILDIR}")
1571
1572  # Reverse the list
1573  for tmp in $snaps
1574  do
1575     rSnaps="$tmp $rSnaps"
1576  done
1577
1578  # Do any pruning
1579  num=0
1580  keep=2
1581  for snap in $rSnaps
1582  do
1583     echo "$snap" | grep -q "beforeUp-"
1584     if [ $? -ne 0 ] ; then continue; fi
1585
1586     if [ $num -ge $keep ] ; then
1587        echo "Pruning old upgrade snapshot: $snap"
1588        rmZFSSnap "${JAILDIR}" "$snap"
1589     fi
1590     num=`expr $num + 1`
1591  done
1592}
1593
1594mk_snapshot()
1595{
1596  echo_logout "Creating snapshot of $JAILNAME..."
1597
1598  # Auto-prune any old / stale BEs
1599  do_prune_auto_snaps
1600
1601  revertSnap="beforeUp-`date +%Y%m%d_%H%M%S`"
1602  ${PROGDIR}/scripts/backend/zfsmksnap.sh ${JAILNAME} "${1}" $revertSnap
1603  if [ $? -ne 0 ] ; then
1604     exit_err "Failed creating automatic snapshot!"
1605  fi
1606}
1607
1608exit_revertsnap()
1609{
1610  # We had an error and need to exit, but first revert the snapshot
1611  echo_logout "Reverting to snapshot: $revertSnap"
1612  ${PROGDIR}/scripts/backend/zfsrevertsnap.sh ${JAILNAME} $revertSnap
1613  if [ $? -ne 0 ] ; then
1614     echo_logout "Failed reverting automatic snapshot!"
1615  fi
[fb46926]1616  umount -f ${JAILDIR}/dev >/dev/null 2>/dev/null
[bb6487e]1617  exit_err "$@"
1618}
1619
1620prep_pkgs_chroot()
1621{
1622  # Make sure jail log dir exists
1623  if [ ! -d "${JAILDIR}/var/log/warden" ] ; then
1624     mkdir -p ${JAILDIR}/var/log/warden
1625  fi
1626
1627  # First, clean the jail environment
1628  echo_logout "Cleaning the jail environment... (This may take a while)"
1629  chroot ${STAGEMNT} /usr/sbin/pkg delete -ay >>${LOGOUT} 2>>${LOGOUT}
1630  if [ $? -ne 0 ] ; then
1631     exit_revertsnap "Failed cleaning jail environment!"
1632  fi
1633
1634  # Next create the script to bootstrap pkgng
1635  echo "#!/bin/sh
1636tar xvpf ${CHROOTREALPKGDLCACHE}/${PKGFILENAME} -C / /usr/local/sbin/pkg-static >/dev/null 2>/dev/null
1637/usr/local/sbin/pkg-static add -f ${CHROOTREALPKGDLCACHE}/${PKGFILENAME}
1638if [ \$? -ne 0 ] ; then exit 1; fi
1639cd ${CHROOTREALPKGDLCACHE}
1640
1641# Cleanup the old /compat/linux for left-overs
1642umount /compat/linux/proc >/dev/null 2>/dev/null
1643umount /compat/linux/sys >/dev/null 2>/dev/null
1644rm -rf /compat/linux
1645mkdir -p /compat/linux/proc
1646mkdir -p /compat/linux/sys
1647
1648while read pkgLine
1649do
1650  pkgOrigin=\"\`echo \$pkgLine | cut -d ' ' -f 1\`\"
1651  pkgName=\"\`echo \$pkgLine | cut -d ' ' -f 2\`\"
1652  if [ ! -e \"\${pkgName}\" ] ; then
1653     echo \"No such package: \${pkgName}\"
1654     echo \"No such package: \${pkgName}\" >>/removed-pkg-list
1655     continue
1656  fi
1657
1658  echo \"Installing \$pkgName...\"
1659  pkg add \${pkgName} >/pkg-add.log 2>/pkg-add.log
1660  if [ \$? -ne 0 ] ; then
1661     echo \"Failed installing \${pkgName}\"
1662     cat /pkg-add.log
1663     echo \"Failed installing \${pkgName}\" >>/failed-pkg-list
1664     cat /pkg-add.log >>/failed-pkg-list
1665  fi
1666done < /install-pkg-list
1667rm /pkg-add.log >/dev/null 2>/dev/null
1668
1669# Save the log files
1670touch /install-pkg-list
1671touch /removed-pkg-list
1672touch /failed-pkg-list
1673mv /install-pkg-list /var/log/warden/
1674mv /removed-pkg-list /var/log/warden/
1675mv /failed-pkg-list /var/log/warden
1676
1677exit 0
1678" > ${STAGEMNT}/.doPkgUp.sh
1679
1680}
1681
1682install_pkgs_chroot()
1683{
1684  # Run it now
1685  echo_logout "Installing packages to jail ${JAILNAME}... (This may take a while)"
1686  chroot ${STAGEMNT} sh /.doPkgUp.sh >>${LOGOUT} 2>>${LOGOUT}
1687  if [ $? -ne 0 ] ; then
1688     exit_revertsnap "Failed upgrading packages!"
1689  fi
1690  rm ${STAGEMNT}/.doPkgUp.sh
1691}
1692
1693run_freebsd_update_script()
1694{
1695  # Start the upgrade with freebsd-update, get files downloaded installed
[fb46926]1696  rc_halt "mount -t devfs devfs ${JAILDIR}/dev"
[bb6487e]1697  echo_logout "Fetching FreeBSD update files..."
1698  chroot ${STAGEMNT} freebsd-update --non-interactive fetch >>${LOGOUT} 2>>${LOGOUT}
1699  if [ $? -ne 0 ] ; then
1700     exit_revertsnap "Failed fetching FreeBSD update files!"
1701  fi
1702  echo_logout "Installing freebsd-update files..."
1703  chroot ${STAGEMNT} freebsd-update install >>${LOGOUT} 2>>${LOGOUT}
1704  if [ $? -ne 0 ] ; then
1705     exit_revertsnap "Failed installing FreeBSD update files!"
1706  fi
1707
1708  # Do it again, remove any old shared objs
1709  chroot ${STAGEMNT} freebsd-update install >/dev/null 2>/dev/null
[fb46926]1710  umount -f ${JAILDIR}/dev
[bb6487e]1711}
1712
1713run_freebsd_upgrade_script()
1714{
[fb46926]1715  # Super ugly hack alert!
1716  # We modify freebsd-update to make it a bit happier running in a chroot / jail
1717  sed -i '' 's|uname -r|freebsd-version|g' ${JAILDIR}/usr/sbin/freebsd-update
1718
[bb6487e]1719  # Start the upgrade with freebsd-update, get files downloaded installed
[fb46926]1720  rc_halt "mount -t devfs devfs ${JAILDIR}/dev"
[bb6487e]1721  echo_logout "Fetching FreeBSD upgrade files..."
1722  chroot ${STAGEMNT} freebsd-update --non-interactive upgrade -r $NEWFREEBSDVERSION >>${LOGOUT} 2>>${LOGOUT}
1723  if [ $? -ne 0 ] ; then
1724     exit_revertsnap "Failed fetching FreeBSD upgrade files!"
1725  fi
1726  echo_logout "Installing freebsd-update files..."
1727  chroot ${STAGEMNT} freebsd-update install >>${LOGOUT} 2>>${LOGOUT}
1728  if [ $? -ne 0 ] ; then
1729     exit_revertsnap "Failed installing FreeBSD upgrade files!"
1730  fi
1731
1732  # Do it again, remove any old shared objs
1733  chroot ${STAGEMNT} freebsd-update install >/dev/null 2>/dev/null
[fb46926]1734  umount -f ${JAILDIR}/dev
[bb6487e]1735}
1736
1737##############################################################
1738# End functions for upgrading jails
1739##############################################################
Note: See TracBrowser for help on using the repository browser.