├── restore_zones.sh ├── sdc-headnode-backup.conf ├── README.md └── sdc-headnode-backup /restore_zones.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Import ZFS images into fresh pool 3 | # Note: this needs to run at least 3 times as 4 | # clone origins need to be imported first. 5 | # ZFS dataset images are expected to be in the same folder 6 | # as this script. 7 | 8 | for image in $(ls *zfs.gz) ; do 9 | uuid=$(echo $image|cut -f1 -d.) && \ 10 | gzcat $image | zfs recv -v zones/${uuid} 11 | done 12 | -------------------------------------------------------------------------------- /sdc-headnode-backup.conf: -------------------------------------------------------------------------------- 1 | # Use Manta (mput) or s3 (s3cmd) for backups 2 | use_manta=1 3 | use_s3=0 4 | 5 | # If use_s3=1 use these s3cmd options 6 | s3bucket="headnode" 7 | s3cmd_flags="--no-check-md5 --force --no-encrypt --multipart-chunk-size-mb=50" 8 | 9 | # If use_manta=1 use these Manta mput options 10 | mput_destination="/myusername/stor/myfolder" 11 | mput_flags='--account=myuser --url=https://us-east.manta.joyent.com --keyId= -p' 12 | 13 | # SSH options 14 | ssh_user="foo" 15 | ssh_host="IP address" 16 | ssh_key="/root/.ssh/sdc.id_rsa" 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | 3 | Usage: sdc-headnode-backup [ global | UUID | all | -f filename | usb | help | -h ] 4 | 5 | Description: 6 | 7 | Simple script to backup all or selected zones. 8 | Each zone is recursively snapshoted and sent 9 | to an SSH gateway zone where it expects to 10 | upload the snapshot to Manta (with mput) or an 11 | S3 compatible object store via s3cmd. 12 | 13 | Additionally the headnode config is backed up. 14 | 15 | Options: 16 | 17 | global backup global zone bits (/opt /var /etc/zones) 18 | UUID backup a single zone identified by UUID 19 | all backup everything (global, non-global and usb config) 20 | -f backup zones listed in file (one UUID per line) 21 | usb backup usb config file 22 | json backup zone_uuid.json configuration 23 | help|-h display this help 24 | 25 | Requires: 26 | 27 | - SmartOS 28 | - SSH zone with s3cmd (installed/configured) 29 | - SSH pubkey auth from headnode to SSH zone 30 | - mput (npm install -g manta) 31 | - s3cmd 1.5.x or higher (pip install s3cmd) 32 | - configuration file /opt/custom/etc/sdc-headnode-backup.conf 33 | 34 | Assumptions: 35 | 36 | - this script is installed in /opt/custom/bin/sdc-headnode-backup 37 | - needs to run on headnode 38 | - SSH pubkey authentication from headnode to SSH zone 39 | - mput flags are configured in sdc-headnode-backup.conf 40 | - s3cmd is configured to access the bucket (sdc-headnode-backup.conf) 41 | - SSH zone/box with Manta or s3 access 42 | 43 | [headnode] 44 | | 45 | (ssh) 46 | | 47 | [SSH zone] 48 | / \ 49 | (s3cmd) (mput) 50 | / \ 51 | [s3 storage] [Manta storage] 52 | (LeoFS) 53 | 54 | ``` 55 | -------------------------------------------------------------------------------- /sdc-headnode-backup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #-------------------------------------------------------------------------+ 3 | # Copyright (c) 2015, pannon 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted providing that the following conditions 8 | # are met: 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 | # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | # POSSIBILITY OF SUCH DAMAGE. 26 | #------------------------------------------------------------------------+ 27 | 28 | PATH='/bin:/usr/sbin:/usr/bin:/sbin:/opt/local/bin/' 29 | 30 | # If we are on SmartOS source the config file 31 | if [ $(uname) == 'SunOS' ] ; then 32 | . /opt/custom/etc/sdc-headnode-backup.conf 33 | fi 34 | 35 | snapshot="backup" 36 | sdc_usb_config="/usbkey/config" 37 | arglen="$1" 38 | upload_cmd="" 39 | 40 | __help () { 41 | cat << 'EOT' 42 | 43 | Usage: sdc-headnode-backup [ global | UUID | all | -f filename | usb | help | -h ] 44 | 45 | Description: 46 | 47 | Simple script to backup all or selected zones. 48 | Each zone is recursively snapshoted and sent 49 | to an SSH gateway zone where it expects to 50 | upload the snapshot to Manta (with mput) or an 51 | S3 compatible object store via s3cmd. 52 | 53 | Additionally the headnode config is backed up. 54 | 55 | Options: 56 | 57 | global backup global zone bits (/opt /var /etc/zones) 58 | UUID backup a single zone identified by UUID 59 | all backup everything (global, non-global and usb config) 60 | -f backup zones listed in file (one UUID per line) 61 | usb backup usb config file 62 | json backup zone_uuid.json configuration 63 | help|-h display this help 64 | 65 | Requires: 66 | 67 | - SmartOS 68 | - SSH zone with s3cmd (installed/configured) 69 | - SSH pubkey auth from headnode to SSH zone 70 | - mput (npm install -g manta) 71 | - s3cmd 1.5.x or higher (pip install s3cmd) 72 | - configuration file /opt/custom/etc/sdc-headnode-backup.conf 73 | 74 | Assumptions: 75 | 76 | - this script is installed in /opt/custom/bin/sdc-headnode-backup 77 | - needs to run on headnode 78 | - SSH pubkey authentication from headnode to SSH zone 79 | - mput flags are configured in sdc-headnode-backup.conf 80 | - s3cmd is configured to access the bucket (sdc-headnode-backup.conf) 81 | - SSH zone/box with Manta or s3 access 82 | 83 | [headnode] 84 | | 85 | (ssh) 86 | | 87 | [SSH zone] 88 | / \ 89 | (s3cmd) (mput) 90 | / \ 91 | [s3 storage] [Manta storage] 92 | (LeoFS) 93 | 94 | EOT 95 | } 96 | 97 | __backup_json () { 98 | # save UUID.json configs - just in case we need these.. 99 | echo "INFO: backing up zone_uuid.json configuration files.." 100 | for zone in $(vmadm list -Ho uuid) ; do 101 | vmadm get $zone | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 102 | "${upload_cmd}/$zone.json" 103 | done 104 | } 105 | 106 | # Backup bits required for successful headnode restore. 107 | # * /etc/zones 108 | # * /var (see excludes) 109 | # * /opt 110 | # * UUID.json for zones 111 | #------------------------------------------------------ 112 | __backup_global_zone () { 113 | echo "INFO: backing up global zone bits.." 114 | # backup zone *.xml files 115 | gtar -czf - /etc/zones | \ 116 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 117 | "${upload_cmd}/globalzone/etc-zones.tgz" 118 | 119 | # backup /var excluding tmp and crash 120 | gtar --exclude='var/tmp' \ 121 | --exclude='var/crash' \ 122 | --exclude='var/log' -czf - /var | \ 123 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 124 | "${upload_cmd}/globalzone/var.tgz" 125 | 126 | # backup /opt 127 | zfs snapshot zones/opt@${snapshot} 128 | zfs send -v zones/opt@${snapshot} | gzip -1 | \ 129 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 130 | "${upload_cmd}/globalzone/opt.zfs.gz" 131 | zfs destroy zones/opt@${snapshot} 132 | } 133 | 134 | # Snapshot the zone and zfs send to the SSH zone where the image 135 | # is uploaded with inline with mput or s3cmd an object store. 136 | # Expects one argument: zone UUID 137 | __snap_and_send () { 138 | _zone="$1" 139 | _size="$(zfs get -Ho value used zones/${_zone})" 140 | 141 | echo "Processing: ${_zone}.zfs" 142 | echo " Size: ${_size}" 143 | 144 | zfs snapshot -r zones/${_zone}@${snapshot} 145 | 146 | zfs send -vR zones/${_zone}@${snapshot} | gzip -1 | \ 147 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 148 | "${upload_cmd}/${_zone}.zfs.gz" 149 | 150 | zfs destroy -r zones/${_zone}@${snapshot} 151 | __fetch_origin ${_zone} 152 | } 153 | 154 | # backup all zones 155 | __backup_all () { 156 | _zones="$(vmadm list -Ho uuid)" 157 | 158 | echo "INFO: backing up all zones.." 159 | for _zone in $_zones ; do 160 | if [ ! -z $_zone ] ; then 161 | __snap_and_send $_zone 162 | fi 163 | done 164 | } 165 | 166 | # backup zones listed in file, one UUID per line 167 | __backup_list () { 168 | _list="$1" 169 | 170 | if [ ! -z $_list ] && [ -e $_list ] ; then 171 | for _zone in $(cat $_list) ; do 172 | 173 | # check if line looks like UUID 174 | if [ ${#_zone} -eq "36" ] ; then 175 | __snap_and_send $_zone 176 | vmadm get $_zone | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 177 | "${upload_cmd}/${_zone}.json" 178 | fi 179 | 180 | done 181 | else 182 | echo "Error: file $_list not found" 183 | fi 184 | } 185 | 186 | # This is required for clones, look up origin ZFS datasets 187 | # and backup those as well (required for restoring cloned zones) 188 | __fetch_origin () { 189 | _dataset="$1" 190 | _origin="$(zfs get -Ho value origin zones/$1)" 191 | 192 | if [ $_origin != '-' ] ; then 193 | _zone=$(echo $_origin | cut -f 2 -d/ | cut -f 1 -d @) 194 | echo "INFO: backing up origin dataset.." 195 | __snap_and_send $_zone 196 | fi 197 | } 198 | 199 | # Take a copy of the current USB configuration 200 | __backup_usb_config () { 201 | echo "Backing up SDC USB config.." 202 | cat ${sdc_usb_config} | \ 203 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 204 | "${upload_cmd}/globalzone/usbkey/config" 205 | } 206 | 207 | # Check whether to use s3cmd or Manta 208 | if [ $use_s3 -eq 1 ] ; then 209 | export upload_cmd="s3cmd put $s3cmd_flags - s3://$s3bucket" 210 | elif [ $use_manta -eq 1 ] ; then 211 | export upload_cmd="mput $mput_flags $mput_destination" 212 | else 213 | echo "Error: both Manta and s3 is disabled" 214 | fi 215 | 216 | # a primitive UUID guess, backup a single zone by UUID 217 | if [ ${#arglen} -eq "36" ] ; then 218 | __snap_and_send "$1" 219 | vmadm get $1 | ssh -i ${ssh_key} ${ssh_user}@${ssh_host} \ 220 | "${upload_cmd}/$1.json" 221 | exit 222 | fi 223 | 224 | while [ $# ] ; do 225 | case "$1" in 226 | help|-h) __help 227 | exit 228 | ;; 229 | usb) __backup_usb_config 230 | exit 231 | ;; 232 | global) __backup_global_zone && __backup_usb_config && \ 233 | __backup_json 234 | exit 235 | ;; 236 | all) __backup_all && __backup_global_zone && \ 237 | __backup_usb_config && __backup_json 238 | exit 239 | ;; 240 | json) __backup_json 241 | exit 242 | ;; 243 | -f) __backup_list "$2" && __backup_global_zone && \ 244 | __backup_usb_config && __backup_json 245 | exit 246 | ;; 247 | *) __help 248 | exit 249 | ;; 250 | esac 251 | shift 252 | done 253 | --------------------------------------------------------------------------------