From 347f10ccbb70624ec61746490c3ee94fd3044f9a Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 21 Feb 2022 11:09:04 +0100 Subject: [PATCH 1/6] subo feed_graphite_sys.pl e incluyo el borrado recursivo, en el servidor de copias, del dataset a copiar, antes de enviar la copia --- feed_graphite_sys.pl | 236 +++++++++++++++++++++++++++++++++++++++++++ zonebackuptozone.sh | 4 + 2 files changed, 240 insertions(+) create mode 100644 feed_graphite_sys.pl diff --git a/feed_graphite_sys.pl b/feed_graphite_sys.pl new file mode 100644 index 0000000..7c44806 --- /dev/null +++ b/feed_graphite_sys.pl @@ -0,0 +1,236 @@ +#!/usr/bin/perl + +use strict; +use IO::Socket; +use Data::Dumper; + +my $graphitehost = "graphite.open6hosting.com"; +my $port = "2003"; +my $hostname = "o6hsmartos16"; +my $grupo = "joyent"; + +my %ipmistatus = ( + "CPU_Temp" => "cpu_temp", + "CPU_Temperature" => "cpu_temp", + "CPU1_Temperature" => "cpu_temp", + "+12V_" => "12v", + "12V" => "12v", + "12V_" => "12v", + "CPU_FAN1" => "cpu_fan1", + "CPU_FAN1_" => "cpu_fan1", + "FAN1" => "cpu_fan1", + "FAN1_" => "cpu_fan1", +); + +my %mdbstatus = ( + "Kernel_" => "kernel", + "Boot_pages" => "boot_pages", + "ZFS_File_Data_" => "zfs_file", + "Anon_" => "anon", + "Exec_and_libs_" => "exec_and_libs", + "Page_cache" => "page_cache", + "Free_(cachelist)" => "free_cachelist", + "Free_(freelist)" => "free_freelist", +); + +# create Socket +my $socket = IO::Socket::INET -> new +( + PeerAddr => $graphitehost, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM +) or die "Couldn't connect to $graphitehost:$port: $@ \n"; + +# enviaremos algo asi +# print $socket "$grupo.$hostname.vfsstat.read_s $estructura{read_s} $time\n"; +sub enviadatos ($$$$) +{ + my $hash = shift; + my $socket = shift; + my $tabla = shift; + my $tiempo = shift; + + while ( my ( $keys, $values ) = each %{$hash} ) + { + print $socket "$grupo.$hostname.$tabla.$keys ${$hash}{$keys} $tiempo\n"; + } +} + + +######## +# +# iostat +# +######## + + +# numero de dispositivos +my $devices = `zpool list -v | grep -c "c[0-9]*" | tr -d '\n'`; + +# r/s w/s kr/s kw/s read_t write_t +# iostat -xzr 10 2 +# device,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b +# sd1,27.9,0.0,111.5,0.0,0.0,0.7,24.6,0,45 +my $captura = `iostat -xr 15 2 | awk -F, '\$1 ~ /^sd[0-8]|blkdev/ { print \$1,\$2,\$3,\$4,\$5,\$7,\$8,\$9,\$10 }' | tail -n$devices`; + +my @fields = split(" ", $captura); +my @wcfields = @fields; + +my %estructura; +my $disco; + +foreach (@fields) +{ + if ( $_ =~ /^sd[0-9]|blkdev[0-9]/ ) + { + $disco = $_; + shift @wcfields; + $estructura{$disco}{r_s} = shift @wcfields; + $estructura{$disco}{w_s} = shift @wcfields; + $estructura{$disco}{kr_s} = shift @wcfields; + $estructura{$disco}{kw_s} = shift @wcfields; + if ( $estructura{$disco}{kr_s} > 0 && $estructura{$disco}{r_s} > 0 ) + { + $estructura{$disco}{ars} = $estructura{$disco}{kr_s} / $estructura{$disco}{r_s}; + } + if ( $estructura{$disco}{kw_s} > 0 && $estructura{$disco}{w_s} > 0 ) + { + $estructura{$disco}{awrs} = $estructura{$disco}{kw_s} / $estructura{$disco}{w_s}; + } + $estructura{$disco}{actv} = shift @wcfields; + $estructura{$disco}{svc_t} = shift @wcfields; + $estructura{$disco}{w} = shift @wcfields; + $estructura{$disco}{b} = shift @wcfields; + } +} + +my $time = time(); + +foreach $disco (keys %estructura) +{ + &enviadatos (\%{ $estructura{$disco} }, $socket, "iostat.$disco", $time); +} + + +######## +# +# ziostat +# +######## + + +# numero de zonas +my $zonas = `vmadm list -H state=running | wc -l | tr -d '\n'`; + +$captura = `ziostat -Z -r 15 2 | awk -F, '\$1 ~ /^[0-9]/ { print \$7,\$1,\$2,\$3,\$4,\$5,\$6 }' | tail -n$zonas`; + +@fields = split(" ", $captura); +@wcfields = @fields; + +my %ziostat; +my $uuid; + +foreach (@fields) +{ + if ( $_ =~ /.*[a-z].*/ ) + { + $uuid = $_; + shift @wcfields; + $ziostat{$uuid}{r_s} = shift @wcfields; + $ziostat{$uuid}{kr_s} = shift @wcfields; + $ziostat{$uuid}{actv} = shift @wcfields; + $ziostat{$uuid}{wsvc_t} = shift @wcfields; + $ziostat{$uuid}{asvc_t} = shift @wcfields; + $ziostat{$uuid}{b} = shift @wcfields; + } +} + +$time = time(); + +foreach $uuid (keys %ziostat) +{ + &enviadatos (\%{ $ziostat{$uuid} }, $socket, "ziostat.$uuid", $time); +} + + +######## +# +# zonememstat +# +######## + +my $memcommand = `zonememstat -H | awk '{ print \$1,\$2,\$4,\$5,\$6 }'`; + +my %zonememstat; +my @memfields = split(" ", $memcommand); +my @wcmemfields = @memfields; +my $memuuid; + + +foreach (@memfields) +{ + if ( $_ =~ /^([a-z0-9]{8}-|global)/ ) { + $memuuid = $_; + shift @wcmemfields; + $zonememstat{$memuuid}{rss} = shift @wcmemfields; + $zonememstat{$memuuid}{nover} = shift @wcmemfields; + $zonememstat{$memuuid}{pout} = shift @wcmemfields; + $zonememstat{$memuuid}{swap} = shift @wcmemfields; + } +} + +my $memtime = time(); + +foreach my $uuid (keys %zonememstat) +{ + &enviadatos ( \%{ $zonememstat{$uuid} }, $socket, "zonememstat.$uuid", $memtime ); +} + +######## +# +# cerramos el descriptor +# +######## + +shutdown($socket,2); + +######## +# +# collect IPMI sensors +# +######## + +my $ipmicommand = "ipmitool sdr list | sed 's/|//g' | sed 's/ /_/' | awk '\$1 ~ /CPU_Temp/ || \$1 ~ /CPU1_Temp/ || \$1 ~ /CPU_FAN1/ || \$1 ~ /^FAN1/ || \$1 ~ /12V/ { print \$1,\$2 }'"; + +open(IPMI, "$ipmicommand |") or die("Could not execute '$ipmicommand': $!"); + +while () { + my ($k, $v) = (m/([\+\w\d]*).*?(\d+(?:\.\d+)?)/); + next unless ($k); + if (exists $ipmistatus{$k} ) { + system("echo -n '$grupo.$hostname.ipmi.$ipmistatus{$k} $v $time' | nc -w 0 $graphitehost $port"); + } +} + +close (IPMI); + +######## +# +# collect memstat mdb data +# +######## + +my $mdbcommand = "mdb -ke '::memstat' | sed 's/ZFS File Data/ZFS_File_Data/' | sed 's/Exec and libs/Exec_and_libs/' | sed 's/ /_/' | awk '{ print \$1,\$3 }'"; + +open(MEMSTAT, "$mdbcommand |") or die("Could not execute '$mdbcommand': $!"); + +while () { + my ($k, $v) = (m/([\w_()]+)\s+?(\d+)?/); + next unless ($k); + if (exists $mdbstatus{$k} ) { + system("echo '$grupo.$hostname.memstat.$mdbstatus{$k} $v $time' | nc -w 0 $graphitehost $port"); + } +} + +close (MEMSTAT); diff --git a/zonebackuptozone.sh b/zonebackuptozone.sh index 523effa..e1d4371 100755 --- a/zonebackuptozone.sh +++ b/zonebackuptozone.sh @@ -72,6 +72,10 @@ create_snap() send_snap () { DATASET=$1 + echo "Deleting dataset ${DATASET} on ${BACKUPZ}..." + ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs destroy -r zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} + check_err + echo "done." echo "Sending snapshot to ${BACKUPZ}..." zfs send zones/${DATASET}@`date +%Y%m%d` | ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs receive -F zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} check_err -- 2.24.1 From 616f2133de0617167fbda0b012695866488bac1f Mon Sep 17 00:00:00 2001 From: psarria Date: Tue, 1 Mar 2022 11:47:41 +0000 Subject: [PATCH 2/6] separo funciones, creo variable DATE e inserto mas checks --- zonebackuptozone.sh | 80 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 13 deletions(-) diff --git a/zonebackuptozone.sh b/zonebackuptozone.sh index e1d4371..16035ab 100755 --- a/zonebackuptozone.sh +++ b/zonebackuptozone.sh @@ -1,5 +1,7 @@ #!/usr/bin/bash +DATE=`date +%Y%m%d` + usage() { echo "Usage: $0 [ -s hostname ] [ -z UUID ] [ -b backupzone ] [ -i idbackupzone ]" >&2 @@ -56,59 +58,111 @@ check_err() check_snap() { ZONE=$1 - echo "Checking for snapshot of ${ZONE}..." - zfs list -t snapshot zones/${ZONE}@`date +%Y%m%d` 2>/dev/null 1>&2 + echo "Checking for local snapshot of ${ZONE}..." + zfs list -t snapshot zones/${ZONE}@${DATE} 2>/dev/null 1>&2 +} + +check_remote_snap() +{ + DATASET=$1 + echo "Checking for an existing remote snapshot of ${DATASET}..." + ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs list zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET}@${DATE} 2>/dev/null 1>&2 +} + +check_remote_dataset() +{ + DATASET=$1 + echo "Checking for an existing remote dataset of ${DATASET}..." + ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs list zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} 2>/dev/null 1>&2 } create_snap() { DS=$1 echo "Creating snapshot of ${DS}..." - zfs snapshot zones/${DS}@`date +%Y%m%d` + zfs snapshot zones/${DS}@${DATE} check_err echo "done." } -send_snap () +delete_local_snap() { DATASET=$1 - echo "Deleting dataset ${DATASET} on ${BACKUPZ}..." - ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs destroy -r zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} + echo "Deleting local snapshot zones/${DATASET}@${DATE}..." + zfs destroy zones/${DATASET}@${DATE} check_err echo "done." - echo "Sending snapshot to ${BACKUPZ}..." - zfs send zones/${DATASET}@`date +%Y%m%d` | ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs receive -F zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} +} + +delete_remote_dataset() +{ + DATASET=$1 + echo "Deleting remote dataset ${DATASET} on ${BACKUPZ}..." + ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs destroy -r zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} 2>/dev/null 1>&2 check_err echo "done." - echo "Deleting snapshot on ${BACKUPZ}..." - ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs destroy zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET}@`date +%Y%m%d` +} + +delete_remote_snap() +{ + DATASET=$1 + echo "Deleting remote snapshot zones/${DATASET}@${DATE} on ${BACKUPZ}..." + ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs destroy -r zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET}@${DATE} 2>/dev/null 1>&2 check_err echo "done." - echo "deleting local snapshot zones/${DATASET}@`date +%Y%m%d`..." - zfs destroy zones/${DATASET}@`date +%Y%m%d` +} + +send_snap () +{ + DATASET=$1 + echo "Sending snapshot to ${BACKUPZ}..." + zfs send zones/${DATASET}@${DATE} | ssh -i /usbkey/ssh/id_rsa -p 2221 $BACKUPZ zfs receive -F zones/${IDBACKUPZ}/data/${SOURCEGZ}/${DATASET} check_err echo "done." } # main + echo "--- BACKUP_ZONE: ${IDBACKUPZ} BACKUP_ZONE_IP: ${BACKUPZ} UUID to backup: ${UUID} +DATE of backup: ${DATE} ---" check_snap ${UUID} - if [ $? -ne 0 ]; then + echo "There is no snapshot available of ${UUID}" create_snap ${UUID} else echo "Snapshot of ${UUID} already available" echo "done." fi +check_remote_dataset ${UUID} +if [ $? -eq 0 ]; then + delete_remote_dataset ${UUID} +else + echo "There is no remote dataset of ${UUID}" + echo "done." +fi + send_snap ${UUID} +check_remote_snap ${UUID} +if [ $? -eq 0 ]; then + delete_remote_snap ${UUID} +else + echo "There is no remote snapshot of ${UUID}" + echo "done." +fi + +check_snap ${UUID} +if [ $? -eq 0 ]; then + delete_local_snap ${UUID} +fi + # we check this UUID for additional datasets echo "Looking for addtional children datasets in ${UUID}..." -- 2.24.1 From f12b08b09e258d5a45a80f8432b8cf46d24ff899 Mon Sep 17 00:00:00 2001 From: psarria Date: Sat, 5 Mar 2022 13:15:27 +0000 Subject: [PATCH 3/6] =?UTF-8?q?a=C3=B1ado=20el=20script=20para=20ajustar?= =?UTF-8?q?=20el=20m=C3=A1ximo=20numero=20de=20grupos=20en=20el=20arranque?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- custom_boot.sh | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 custom_boot.sh diff --git a/custom_boot.sh b/custom_boot.sh new file mode 100755 index 0000000..5338184 --- /dev/null +++ b/custom_boot.sh @@ -0,0 +1,46 @@ +#!/usr/bin/bash + +usage() +{ + echo "Usage: $0 [ -d dirname ]" >&2 + echo "ex: $0 -d /zones/boot/boot-20220113T011608Z" + exit 1 +} + +while getopts ":d:" opt; +do + case "$opt" in + d) + DIR=$OPTARG + ;; + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND -1 )) + +if [ -z ${DIR} ]; then + usage +fi + +mkdir -p $DIR/bootfs/etc +cp /etc/system $DIR/bootfs/etc/ + +echo 'set ngroups_max=1024' >> $DIR/bootfs/etc/system + +cat << EOF >> $DIR/loader.conf.local +etc_system_load=YES +etc_system_type=file +etc_system_name=/boot/bootfs/etc/system +etc_system_flags="name=/etc/system" +EOF -- 2.24.1 From da03ed417f54f81bc53cbbd829d9c2f78b7b6ca3 Mon Sep 17 00:00:00 2001 From: Pablo Sarria Date: Tue, 17 Dec 2024 17:53:06 +0100 Subject: [PATCH 4/6] =?UTF-8?q?a=C3=B1ado=20par=C3=A1metro=20-u=20al=20zfs?= =?UTF-8?q?=20receive=20para=20permitir=20incrementales;=20elimino=20el=20?= =?UTF-8?q?trabajo=20de=20alias,=20no=20es=20necesario=20al=20importarlo?= =?UTF-8?q?=20directamente=20con=20zonecfg;=20mostramos=20la=20mac=20e=20i?= =?UTF-8?q?p=20del=20VPS=20a=20trasladar;=20a=C3=B1adimos=20un=20payload?= =?UTF-8?q?=20de=20.cfg=20para=20modificar=20en=20destino;=20montamos=20da?= =?UTF-8?q?taset=20en=20destino;=20actualizamos=20VPS=20en=20local=20para?= =?UTF-8?q?=20evitar=20su=20inicio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zonemigrate.sh | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/zonemigrate.sh b/zonemigrate.sh index 1a9b69d..a3699a9 100755 --- a/zonemigrate.sh +++ b/zonemigrate.sh @@ -57,7 +57,7 @@ snapshot() zfs snapshot $1@`date +%Y%m%d` check $? echo "enviando snapshot de $1 a $SERVER ..." - zfs send $1@`date +%Y%m%d` | $SSH $SERVER zfs receive $1 + zfs send $1@`date +%Y%m%d` | $SSH $SERVER zfs receive -u $1 check $? echo "creando snapshot incremental de $1 ..." zfs snapshot $1@`date +%Y%m%d`.incremental @@ -67,10 +67,9 @@ snapshot() check $? } -# capturamos el alias que vmadm usa en base64 y que da problemas con el mitico zonecfg - -ALIAS=`vmadm get ${UUID} | json alias | tr -d '\n'` -zonecfg -z ${UUID} "select attr name=alias; set value=temporal; end" +# mostramos mac a exporar por VXLAN +echo "mostramos mac e ips a exportar via VXLAN..." +vmadm get ${UUID} | json nics.0.ips nics.0.mac # creamos snapshot, lo enviamos, creamos incremental y la enviamos @@ -94,31 +93,45 @@ if [ -n "${DATASET}" ]; then fi # exportamos configuracion -echo "exportamos configuracion..." +echo "exportamos configuracion y enviamos a destino..." -zonecfg -z ${UUID} export > $CFG/${UUID}.cfg -$SCP $CFG/${UUID}.cfg $SERVER:$CFG/${UUID}.cfg +zonecfg -z ${UUID} export | $SSH $SERVER "zonecfg -z ${UUID}" -# destino -echo "enviamos config a destino..." +# modificamos de acuerdo a la config de datacenter remoto +echo "modificamos config de acuerdo a datacenter remoto..." -$SSH $SERVER zonecfg -z ${UUID} < $CFG/${UUID}.cfg -$SSH $SERVER zoneadm -z ${UUID} attach -$SSH $SERVER zoneadm -z ${UUID} halt +echo " +select net physical=eth0 + clear vlan-id + set global-nic=v/100 + add property (name=mtu,value="1200") + remove property (name=gateway,value="194.53.148.1") + remove property (name=gateways,value="194.53.148.1") + add property (name=gateway,value="194.53.148.2") + add property (name=gateways,value="194.53.148.2") +end" | $SSH $SERVER "zonecfg -z ${UUID}" + +# montamos el dataset + +$SSH $SERVER zfs mount ${ZONEPATH} -# reestablecemos el alias que usa vmadm +# instalamos -$SSH $SERVER vmadm update ${UUID} alias=${ALIAS} -vmadm update ${UUID} alias=${ALIAS} +$SSH $SERVER zoneadm -z ${UUID} attach # detenemos la zona en local zoneadm -z ${UUID} halt +# actualizamos la zona en local para que no inicie + +vmadm udpate ${UUID} autoboot=false + # iniciamos la zona en remoto $SSH $SERVER zoneadm -z ${UUID} boot + # TODO: # - puede haber mas de un FILESYSTEM en la zona, necesitamos iterar por el array y lanzar la funcion snapshot sobre cada uno de ellos # - puede haber mas de un DATASET en la zona, necesitamos iterar por el array y lanzar la funcion snapshot sobre cada uno -- 2.24.1 From 26569b949f686dc3c86a009dd979b04a395397c5 Mon Sep 17 00:00:00 2001 From: Pablo Sarria Date: Wed, 5 Feb 2025 11:48:06 +0100 Subject: [PATCH 5/6] =?UTF-8?q?a=C3=B1ado=20delete-cores=20y=20llevo=20a?= =?UTF-8?q?=20cabo=20cambios=20mayores=20en=20el=20zonebackuptofile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- delete-cores.sh | 2 + zonebackuptofile.sh | 191 +++++++++++++++++++++++++++++--------------- 2 files changed, 129 insertions(+), 64 deletions(-) create mode 100755 delete-cores.sh diff --git a/delete-cores.sh b/delete-cores.sh new file mode 100755 index 0000000..6bb0663 --- /dev/null +++ b/delete-cores.sh @@ -0,0 +1,2 @@ +#!/usr/bin/bash +zfs list -H | grep "cores$" | grep -v "global" | awk '$2 ~ /G/ { print "find",$5,"-type f -delete"}' | /usr/bin/sh diff --git a/zonebackuptofile.sh b/zonebackuptofile.sh index e3a8e98..9595629 100755 --- a/zonebackuptofile.sh +++ b/zonebackuptofile.sh @@ -2,100 +2,163 @@ usage() { - echo "Usage: $0 -z UUID -d days -r remote_folder -l local_folder -s server -t type" >&2 - echo "ex: $0 -z bbba5ecb-5bda-47a5-e103-a6bfa368bf68 -d 1 -r remote_folder -l /zone/tools/nfsshare -s 192.168.5.243 -t nfs" >&2 + echo "Usage: $0 [ -z UUID ] [ -h hostname ] [ -p port ] [ -k KEY ] [ -n name ] [ -d dir ]" >&2 exit 1 } -while getopts "z:d:r:l:s:t:" opt; +while getopts "z:h:p:k:n:d:" opt; do case "$opt" in z) - UUID=$OPTARG - ;; + UUID=$OPTARG + ;; + h) + HOSTNAME=$OPTARG + ;; + n) + NAME=$OPTARG + ;; + p) + PORT=$OPTARG + ;; + k) + KEY=$OPTARG + ;; d) - DAYS=$OPTARG - ;; - r) - RFOLDER=$OPTARG - ;; - l) - LFOLDER=$OPTARG - ;; - s) - SERVER=$OPTARG - ;; - t) - TYPE=$OPTARG - ;; + DIR=$OPTARG + ;; + + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; *) - usage - ;; + usage + ;; esac done shift $((OPTIND-1)) -if [ -z "${UUID}" || -z "${DAYS}" || -z "${RFOLDER}" || -z "${LFOLDER}" || -z "${SERVER}" && -z "${TYPE}" ]; then +if [ -z "${UUID}" ] || [ -z "${HOSTNAME}" ] || [ -z ${PORT} ] || [ -z ${KEY} ] || [ -z "${NAME}" ] || [ -z "${DIR}" ]; then usage fi -BRAND=`/usr/sbin/vmadm get $UUID | json brand | tr -d '\n'` +SSH="ssh -i $KEY -p ${PORT} -o StrictHostKeyChecking=no" +DSTDIR="${DIR}/${NAME}" -mkdir -p $LFOLDER +################# +# functions +################# -if [ $TYPE = "nfs" ]; then - OVH="/export/ftpbackup/${RFOLDER}" - - mount $SERVER:$OVH $LFOLDER +create_snap() +{ + DATASET=$1 + echo "Creating snapshot of ${DATASET}..." + /usr/sbin/zfs snapshot zones/${DATASET}@`date +%Y%m%d` + check_err + echo "...done." +} - if [ $? != 0 ]; then - echo "MOUNT FAILED." - umount $LFOLDER - exit - fi -elif [ $TYPE = "smb" ]; then - mount -F smbfs //o6h.smartos5:c0c0l1s0@${SERVER}/${RFOLDER} $LFOLDER +send_snap() +{ + DATASET=$1 + echo "Sending snapshot of ${DATASET}..." - if [ $? != 0 ]; then - echo "MOUNT FAILED." - exit + # taking care for additional datasets + SLASH=`echo ${DATASET} | grep -c '/'` + + if [ ${SLASH} -ne 0 ]; then + RENAME=`echo ${DATASET} | sed 's/\//-/'` + /usr/sbin/zfs send zones/${DATASET}@`date +%Y%m%d` | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${UUID}/${RENAME}.zfs bs=4M" + else + /usr/sbin/zfs send zones/${DATASET}@`date +%Y%m%d` | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${DATASET}/${DATASET}.zfs bs=4M" fi -fi -mkdir -p $LFOLDER/$UUID + check_err + echo "...done." +} -if [ $? != 0 ]; then - echo "FAIL TO CREATE FOLDER $UUID." - umount $LFOLDER - exit -fi +check_snap() +{ + ZONE=$1 + echo "Checking for snapshot of ${ZONE}..." + zfs list -t snapshot zones/${ZONE}@`date +%Y%m%d` 2>/dev/null 1>&2 +} -# mantain backups of the last N days -#find $LFOLDER/$UUID -type f -mtime +$DAYS -delete +check_err() +{ + STATUS=$? + if [ ${STATUS} -ne 0 ]; then + echo "Unexpected error: ${STATUS}" + exit ${STATUS} + fi +} -snapshot() +send_config() { - /usr/sbin/zfs snapshot zones/$1@`date +%Y%m%d` - /usr/sbin/zfs send zones/$1@`date +%Y%m%d` > $LFOLDER/$UUID/$1@`date +%Y%m%d` + echo "Sending config to ${HOSTNAME}..." + zonecfg -z ${UUID} export | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${UUID}/${UUID}.cfg" + check_err + echo "...done." } -snapshot $UUID +create_dir() +{ + echo "Creating directory at ${HOSTNAME}..." + ${SSH} ${HOSTNAME} mkdir -p ${DSTDIR}/${UUID} + check_err + echo "...done." +} -if [ $BRAND = "kvm" ] -then - snapshot ${UUID}-disk0 -elif [ $BRAND = "bhyve" ] -then - snapshot ${UUID}/disk0 -fi +check_multidataset() +{ + echo "Looking for addtional children datasets in ${UUID}..." + DATASET=`vmadm get ${UUID} | json datasets.0 | sed 's/zones\///' | tr -d '\n'` + echo "...done." + + if [ ! -z "${DATASET}" ]; then + echo "Finded children dataset: ${DATASET}" + check_snap ${DATASET} + + if [ $? -ne 0 ]; then + create_snap ${DATASET} + else + echo "Snapshot of ${DATASET} already available" + echo "Skipping create snapshot..." + fi + send_snap ${DATASET} + else + echo "No children datasets finded." + fi +} -/usr/sbin/zonecfg -z $UUID export > $LFOLDER/$UUID/$UUID.`date +%Y%m%d`.cfg +################# +# main +################# -if [ $TYPE = "nfs" ]; then - umount $LFOLDER +echo "--- +BACKUP_SERVER: ${HOSTNAME} +UUID to backup: ${UUID} +---" + +create_dir ${UUID} + +check_snap ${UUID} + +if [ $? -ne 0 ]; then + create_snap ${UUID} +else + echo "Snapshot of ${UUID} already available" + echo "...done." fi -## TODO -# smb: query for username -# smb: query for password +send_snap ${UUID} + +check_multidataset + +send_config -- 2.24.1 From 1480bcc9db75f60f0efd52e409cef029eea675cd Mon Sep 17 00:00:00 2001 From: Pablo Sarria Date: Thu, 18 Sep 2025 19:04:11 +0000 Subject: [PATCH 6/6] modifico scripts, hago adds y rms --- LICENSE | 0 alias_vps.sh | 9 ++ delete-cores.sh | 2 + feed_graphite_sys.pl | 236 ------------------------------------------- getsnap.sh | 62 ++++++++++++ perl_fastcgi.xml | 32 ------ recursos.sh | 38 +++++++ restoresnaps.sh | 127 +++++++++++++++++++++++ update_alias_vps.sh | 6 ++ zonebackuptofile.sh | 191 ++++++++++++++++++++++------------ zonemigrate.sh | 17 +--- 11 files changed, 372 insertions(+), 348 deletions(-) delete mode 100644 LICENSE create mode 100755 alias_vps.sh create mode 100755 delete-cores.sh delete mode 100644 feed_graphite_sys.pl create mode 100755 getsnap.sh delete mode 100644 perl_fastcgi.xml create mode 100755 recursos.sh create mode 100755 restoresnaps.sh create mode 100755 update_alias_vps.sh diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e69de29..0000000 diff --git a/alias_vps.sh b/alias_vps.sh new file mode 100755 index 0000000..82f4c80 --- /dev/null +++ b/alias_vps.sh @@ -0,0 +1,9 @@ +#!/bin/bash +UUID=$1 + +for a in $(zoneadm list -n); do + UUID=$a + ZONEALIAS=`zonecfg -z ${UUID} info attr name=alias | awk '$1 ~ /value:/ { print $2 }' | openssl base64 -d` + IP=`zonecfg -z ${UUID} info net | awk '$2 ~ /ips/ { print $2 }' | awk -F\" '{ print $2 }' | sed 's/,/ /'` + echo ${UUID} ${ZONEALIAS} ${IP} +done diff --git a/delete-cores.sh b/delete-cores.sh new file mode 100755 index 0000000..6bb0663 --- /dev/null +++ b/delete-cores.sh @@ -0,0 +1,2 @@ +#!/usr/bin/bash +zfs list -H | grep "cores$" | grep -v "global" | awk '$2 ~ /G/ { print "find",$5,"-type f -delete"}' | /usr/bin/sh diff --git a/feed_graphite_sys.pl b/feed_graphite_sys.pl deleted file mode 100644 index 7c44806..0000000 --- a/feed_graphite_sys.pl +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/perl - -use strict; -use IO::Socket; -use Data::Dumper; - -my $graphitehost = "graphite.open6hosting.com"; -my $port = "2003"; -my $hostname = "o6hsmartos16"; -my $grupo = "joyent"; - -my %ipmistatus = ( - "CPU_Temp" => "cpu_temp", - "CPU_Temperature" => "cpu_temp", - "CPU1_Temperature" => "cpu_temp", - "+12V_" => "12v", - "12V" => "12v", - "12V_" => "12v", - "CPU_FAN1" => "cpu_fan1", - "CPU_FAN1_" => "cpu_fan1", - "FAN1" => "cpu_fan1", - "FAN1_" => "cpu_fan1", -); - -my %mdbstatus = ( - "Kernel_" => "kernel", - "Boot_pages" => "boot_pages", - "ZFS_File_Data_" => "zfs_file", - "Anon_" => "anon", - "Exec_and_libs_" => "exec_and_libs", - "Page_cache" => "page_cache", - "Free_(cachelist)" => "free_cachelist", - "Free_(freelist)" => "free_freelist", -); - -# create Socket -my $socket = IO::Socket::INET -> new -( - PeerAddr => $graphitehost, - PeerPort => $port, - Proto => "tcp", - Type => SOCK_STREAM -) or die "Couldn't connect to $graphitehost:$port: $@ \n"; - -# enviaremos algo asi -# print $socket "$grupo.$hostname.vfsstat.read_s $estructura{read_s} $time\n"; -sub enviadatos ($$$$) -{ - my $hash = shift; - my $socket = shift; - my $tabla = shift; - my $tiempo = shift; - - while ( my ( $keys, $values ) = each %{$hash} ) - { - print $socket "$grupo.$hostname.$tabla.$keys ${$hash}{$keys} $tiempo\n"; - } -} - - -######## -# -# iostat -# -######## - - -# numero de dispositivos -my $devices = `zpool list -v | grep -c "c[0-9]*" | tr -d '\n'`; - -# r/s w/s kr/s kw/s read_t write_t -# iostat -xzr 10 2 -# device,r/s,w/s,kr/s,kw/s,wait,actv,svc_t,%w,%b -# sd1,27.9,0.0,111.5,0.0,0.0,0.7,24.6,0,45 -my $captura = `iostat -xr 15 2 | awk -F, '\$1 ~ /^sd[0-8]|blkdev/ { print \$1,\$2,\$3,\$4,\$5,\$7,\$8,\$9,\$10 }' | tail -n$devices`; - -my @fields = split(" ", $captura); -my @wcfields = @fields; - -my %estructura; -my $disco; - -foreach (@fields) -{ - if ( $_ =~ /^sd[0-9]|blkdev[0-9]/ ) - { - $disco = $_; - shift @wcfields; - $estructura{$disco}{r_s} = shift @wcfields; - $estructura{$disco}{w_s} = shift @wcfields; - $estructura{$disco}{kr_s} = shift @wcfields; - $estructura{$disco}{kw_s} = shift @wcfields; - if ( $estructura{$disco}{kr_s} > 0 && $estructura{$disco}{r_s} > 0 ) - { - $estructura{$disco}{ars} = $estructura{$disco}{kr_s} / $estructura{$disco}{r_s}; - } - if ( $estructura{$disco}{kw_s} > 0 && $estructura{$disco}{w_s} > 0 ) - { - $estructura{$disco}{awrs} = $estructura{$disco}{kw_s} / $estructura{$disco}{w_s}; - } - $estructura{$disco}{actv} = shift @wcfields; - $estructura{$disco}{svc_t} = shift @wcfields; - $estructura{$disco}{w} = shift @wcfields; - $estructura{$disco}{b} = shift @wcfields; - } -} - -my $time = time(); - -foreach $disco (keys %estructura) -{ - &enviadatos (\%{ $estructura{$disco} }, $socket, "iostat.$disco", $time); -} - - -######## -# -# ziostat -# -######## - - -# numero de zonas -my $zonas = `vmadm list -H state=running | wc -l | tr -d '\n'`; - -$captura = `ziostat -Z -r 15 2 | awk -F, '\$1 ~ /^[0-9]/ { print \$7,\$1,\$2,\$3,\$4,\$5,\$6 }' | tail -n$zonas`; - -@fields = split(" ", $captura); -@wcfields = @fields; - -my %ziostat; -my $uuid; - -foreach (@fields) -{ - if ( $_ =~ /.*[a-z].*/ ) - { - $uuid = $_; - shift @wcfields; - $ziostat{$uuid}{r_s} = shift @wcfields; - $ziostat{$uuid}{kr_s} = shift @wcfields; - $ziostat{$uuid}{actv} = shift @wcfields; - $ziostat{$uuid}{wsvc_t} = shift @wcfields; - $ziostat{$uuid}{asvc_t} = shift @wcfields; - $ziostat{$uuid}{b} = shift @wcfields; - } -} - -$time = time(); - -foreach $uuid (keys %ziostat) -{ - &enviadatos (\%{ $ziostat{$uuid} }, $socket, "ziostat.$uuid", $time); -} - - -######## -# -# zonememstat -# -######## - -my $memcommand = `zonememstat -H | awk '{ print \$1,\$2,\$4,\$5,\$6 }'`; - -my %zonememstat; -my @memfields = split(" ", $memcommand); -my @wcmemfields = @memfields; -my $memuuid; - - -foreach (@memfields) -{ - if ( $_ =~ /^([a-z0-9]{8}-|global)/ ) { - $memuuid = $_; - shift @wcmemfields; - $zonememstat{$memuuid}{rss} = shift @wcmemfields; - $zonememstat{$memuuid}{nover} = shift @wcmemfields; - $zonememstat{$memuuid}{pout} = shift @wcmemfields; - $zonememstat{$memuuid}{swap} = shift @wcmemfields; - } -} - -my $memtime = time(); - -foreach my $uuid (keys %zonememstat) -{ - &enviadatos ( \%{ $zonememstat{$uuid} }, $socket, "zonememstat.$uuid", $memtime ); -} - -######## -# -# cerramos el descriptor -# -######## - -shutdown($socket,2); - -######## -# -# collect IPMI sensors -# -######## - -my $ipmicommand = "ipmitool sdr list | sed 's/|//g' | sed 's/ /_/' | awk '\$1 ~ /CPU_Temp/ || \$1 ~ /CPU1_Temp/ || \$1 ~ /CPU_FAN1/ || \$1 ~ /^FAN1/ || \$1 ~ /12V/ { print \$1,\$2 }'"; - -open(IPMI, "$ipmicommand |") or die("Could not execute '$ipmicommand': $!"); - -while () { - my ($k, $v) = (m/([\+\w\d]*).*?(\d+(?:\.\d+)?)/); - next unless ($k); - if (exists $ipmistatus{$k} ) { - system("echo -n '$grupo.$hostname.ipmi.$ipmistatus{$k} $v $time' | nc -w 0 $graphitehost $port"); - } -} - -close (IPMI); - -######## -# -# collect memstat mdb data -# -######## - -my $mdbcommand = "mdb -ke '::memstat' | sed 's/ZFS File Data/ZFS_File_Data/' | sed 's/Exec and libs/Exec_and_libs/' | sed 's/ /_/' | awk '{ print \$1,\$3 }'"; - -open(MEMSTAT, "$mdbcommand |") or die("Could not execute '$mdbcommand': $!"); - -while () { - my ($k, $v) = (m/([\w_()]+)\s+?(\d+)?/); - next unless ($k); - if (exists $mdbstatus{$k} ) { - system("echo '$grupo.$hostname.memstat.$mdbstatus{$k} $v $time' | nc -w 0 $graphitehost $port"); - } -} - -close (MEMSTAT); diff --git a/getsnap.sh b/getsnap.sh new file mode 100755 index 0000000..03634ae --- /dev/null +++ b/getsnap.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +usage() +{ + echo "Usage: $0 -z UUID -h NODE -d DIR -p PORT -i KEY -s STORAGEBOX -u USER" >&2 + exit 1 +} + +while getopts "z:h:d:p:i:s:u:" opt; +do + case "$opt" in + z) + UUID=$OPTARG + ;; + h) + NODE=$OPTARG + ;; + d) + DIR=$OPTARG + ;; + p) + PORT=$OPTARG + ;; + i) + KEY=$OPTARG + ;; + s) + STORAGEBOX=$OPTARG + ;; + u) + USER=$OPTARG + ;; + + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) + +if [ -z "${UUID}" ] || [ -z "${NODE}" ] || [ -z "${DIR}" ] || [ -z "${PORT}" ] || [ -z "${KEY}" ] || [ -z "${STORAGEBOX}" ] || [ -z "${USER}" ]; then + usage +fi + + +VPS=$UUID + +#ssh -p ${PORT} -i ${KEY} -l ${USER} ${STORAGEBOX} ls -hl ${DIR}/${NODE}/${VPS}/${VPS}.zfs | awk '{ print "size;"$5",date;"$7,$6,$8 }' | tr -d '\n' +SIZE="$(ssh -p ${PORT} -i ${KEY} -l ${USER} ${STORAGEBOX} du -h ${DIR}/${NODE}/${VPS}/${VPS}.zfs | awk '{ print $1 }' | tr -d '\n')" +DATE="$(ssh -p ${PORT} -i ${KEY} -l ${USER} ${STORAGEBOX} ls -l ${DIR}/${NODE}/${VPS}/${VPS}.zfs | awk '{ print $7,$6,$8 }' | tr -d '\n')" +echo "size; ${SIZE},date; ${DATE}" | tr -d '\n' + + diff --git a/perl_fastcgi.xml b/perl_fastcgi.xml deleted file mode 100644 index 968a968..0000000 --- a/perl_fastcgi.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/recursos.sh b/recursos.sh new file mode 100755 index 0000000..7c0276e --- /dev/null +++ b/recursos.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +usage() +{ + echo "Usage: $0 -z UUID" >&2 + exit 1 +} + +while getopts "z:" opt; +do + case "$opt" in + z) + UUID=$OPTARG + ;; + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) + +if [ -z "${UUID}" ]; then + usage +fi + + +VPS=$UUID + +zonememstat -Hz ${VPS} | awk '{ print "uso:"$2",ram:"$3",swap:"$6 }' | tr -d '\n' diff --git a/restoresnaps.sh b/restoresnaps.sh new file mode 100755 index 0000000..bf462f3 --- /dev/null +++ b/restoresnaps.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +usage() +{ + echo "Usage: $0 [ -n NODE ] [ -z UUID ] [ -h hostname ] [ -p port ] [ -k KEY ] [ -d dir ] [ -u user ]" >&2 + exit 1 +} + +while getopts "n:z:h:p:k:d:u:" opt; +do + case "$opt" in + n) + NODE=$OPTARG + ;; + z) + UUID=$OPTARG + ;; + h) + HOSTNAME=$OPTARG + ;; + p) + PORT=$OPTARG + ;; + k) + KEY=$OPTARG + ;; + d) + DIR=$OPTARG + ;; + u) + USER=$OPTARG + ;; + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; + *) + usage + ;; + esac +done + +shift $((OPTIND-1)) + +if [ -z "${UUID}" ] || [ -z "${NODE}" ] || [ -z ${HOSTNAME} ] || [ -z ${PORT} ] || [ -z ${KEY} ] || [ -z "${DIR}" ] || [ -z "${USER}" ]; then + usage +fi + +SSH="ssh -i $KEY -p ${PORT} -l ${USER} -o StrictHostKeyChecking=no" +SCP="scp -q -i $KEY -P ${PORT} -o StrictHostKeyChecking=no" +DSTDIR="${DIR}/${UUID}" + +################# +# functions +################# + +check_err() +{ + STATUS=$? + if [ ${STATUS} -ne 0 ]; then + echo "Unexpected error: ${STATUS}" + exit ${STATUS} + fi +} + +remove_vps() +{ + VPS=$1 + echo "Deleteing VPS ${VPS}..." + vmadm destroy ${VPS} + check_err + echo "...done." +} + +recover_dataset() +{ + VPS=$1 + echo "Recovering VPS ${VPS}..." + ${SSH} ${HOSTNAME} "dd if=${DIR}/${NODE}/${VPS}/${VPS}.zfs bs=4M" | /usr/sbin/zfs receive zones/${VPS} + check_err + echo "...done." +} + +recover_config() +{ + VPS=$1 + echo "Recovering config from backup..." + ${SCP} ${USER}@${HOSTNAME}:${DIR}/${NODE}/${VPS}/${VPS}.cfg /zones/tools/descargas/ + cat /zones/tools/descargas/${VPS}.cfg | zonecfg -z ${VPS} + + check_err + echo "...done." +} + +final_steps() +{ + VPS=$1 + echo "Attaching dataset..." + zoneadm -z ${VPS} attach + check_err + echo "...done." + echo "Booting VPS..." + zoneadm -z ${VPS} boot + check_err + echo "...done." +} + +################# +# main +################# + +echo "--- +BACKUP_SERVER: ${HOSTNAME} +UUID to restore: ${UUID} +---" + +remove_vps ${UUID} + +recover_config ${UUID} + +recover_dataset ${UUID} + +final_steps ${UUID} diff --git a/update_alias_vps.sh b/update_alias_vps.sh new file mode 100755 index 0000000..f570a98 --- /dev/null +++ b/update_alias_vps.sh @@ -0,0 +1,6 @@ +#!/bin/bash +UUID=$1 +ALIAS=$2 +NEWALIAS=`echo ${ALIAS} | tr -d '\n' | openssl base64` + +zonecfg -z ${UUID} "select attr name=alias; set value=\"${NEWALIAS}\";end" diff --git a/zonebackuptofile.sh b/zonebackuptofile.sh index e3a8e98..9595629 100755 --- a/zonebackuptofile.sh +++ b/zonebackuptofile.sh @@ -2,100 +2,163 @@ usage() { - echo "Usage: $0 -z UUID -d days -r remote_folder -l local_folder -s server -t type" >&2 - echo "ex: $0 -z bbba5ecb-5bda-47a5-e103-a6bfa368bf68 -d 1 -r remote_folder -l /zone/tools/nfsshare -s 192.168.5.243 -t nfs" >&2 + echo "Usage: $0 [ -z UUID ] [ -h hostname ] [ -p port ] [ -k KEY ] [ -n name ] [ -d dir ]" >&2 exit 1 } -while getopts "z:d:r:l:s:t:" opt; +while getopts "z:h:p:k:n:d:" opt; do case "$opt" in z) - UUID=$OPTARG - ;; + UUID=$OPTARG + ;; + h) + HOSTNAME=$OPTARG + ;; + n) + NAME=$OPTARG + ;; + p) + PORT=$OPTARG + ;; + k) + KEY=$OPTARG + ;; d) - DAYS=$OPTARG - ;; - r) - RFOLDER=$OPTARG - ;; - l) - LFOLDER=$OPTARG - ;; - s) - SERVER=$OPTARG - ;; - t) - TYPE=$OPTARG - ;; + DIR=$OPTARG + ;; + + \?) + echo "Error: Invalid Option: -${OPTARG}" >&2 + usage + ;; + :) + echo "Error: -${OPTARG} requires an argument." + usage + ;; *) - usage - ;; + usage + ;; esac done shift $((OPTIND-1)) -if [ -z "${UUID}" || -z "${DAYS}" || -z "${RFOLDER}" || -z "${LFOLDER}" || -z "${SERVER}" && -z "${TYPE}" ]; then +if [ -z "${UUID}" ] || [ -z "${HOSTNAME}" ] || [ -z ${PORT} ] || [ -z ${KEY} ] || [ -z "${NAME}" ] || [ -z "${DIR}" ]; then usage fi -BRAND=`/usr/sbin/vmadm get $UUID | json brand | tr -d '\n'` +SSH="ssh -i $KEY -p ${PORT} -o StrictHostKeyChecking=no" +DSTDIR="${DIR}/${NAME}" -mkdir -p $LFOLDER +################# +# functions +################# -if [ $TYPE = "nfs" ]; then - OVH="/export/ftpbackup/${RFOLDER}" - - mount $SERVER:$OVH $LFOLDER +create_snap() +{ + DATASET=$1 + echo "Creating snapshot of ${DATASET}..." + /usr/sbin/zfs snapshot zones/${DATASET}@`date +%Y%m%d` + check_err + echo "...done." +} - if [ $? != 0 ]; then - echo "MOUNT FAILED." - umount $LFOLDER - exit - fi -elif [ $TYPE = "smb" ]; then - mount -F smbfs //o6h.smartos5:c0c0l1s0@${SERVER}/${RFOLDER} $LFOLDER +send_snap() +{ + DATASET=$1 + echo "Sending snapshot of ${DATASET}..." - if [ $? != 0 ]; then - echo "MOUNT FAILED." - exit + # taking care for additional datasets + SLASH=`echo ${DATASET} | grep -c '/'` + + if [ ${SLASH} -ne 0 ]; then + RENAME=`echo ${DATASET} | sed 's/\//-/'` + /usr/sbin/zfs send zones/${DATASET}@`date +%Y%m%d` | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${UUID}/${RENAME}.zfs bs=4M" + else + /usr/sbin/zfs send zones/${DATASET}@`date +%Y%m%d` | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${DATASET}/${DATASET}.zfs bs=4M" fi -fi -mkdir -p $LFOLDER/$UUID + check_err + echo "...done." +} -if [ $? != 0 ]; then - echo "FAIL TO CREATE FOLDER $UUID." - umount $LFOLDER - exit -fi +check_snap() +{ + ZONE=$1 + echo "Checking for snapshot of ${ZONE}..." + zfs list -t snapshot zones/${ZONE}@`date +%Y%m%d` 2>/dev/null 1>&2 +} -# mantain backups of the last N days -#find $LFOLDER/$UUID -type f -mtime +$DAYS -delete +check_err() +{ + STATUS=$? + if [ ${STATUS} -ne 0 ]; then + echo "Unexpected error: ${STATUS}" + exit ${STATUS} + fi +} -snapshot() +send_config() { - /usr/sbin/zfs snapshot zones/$1@`date +%Y%m%d` - /usr/sbin/zfs send zones/$1@`date +%Y%m%d` > $LFOLDER/$UUID/$1@`date +%Y%m%d` + echo "Sending config to ${HOSTNAME}..." + zonecfg -z ${UUID} export | ${SSH} ${HOSTNAME} "dd of=${DSTDIR}/${UUID}/${UUID}.cfg" + check_err + echo "...done." } -snapshot $UUID +create_dir() +{ + echo "Creating directory at ${HOSTNAME}..." + ${SSH} ${HOSTNAME} mkdir -p ${DSTDIR}/${UUID} + check_err + echo "...done." +} -if [ $BRAND = "kvm" ] -then - snapshot ${UUID}-disk0 -elif [ $BRAND = "bhyve" ] -then - snapshot ${UUID}/disk0 -fi +check_multidataset() +{ + echo "Looking for addtional children datasets in ${UUID}..." + DATASET=`vmadm get ${UUID} | json datasets.0 | sed 's/zones\///' | tr -d '\n'` + echo "...done." + + if [ ! -z "${DATASET}" ]; then + echo "Finded children dataset: ${DATASET}" + check_snap ${DATASET} + + if [ $? -ne 0 ]; then + create_snap ${DATASET} + else + echo "Snapshot of ${DATASET} already available" + echo "Skipping create snapshot..." + fi + send_snap ${DATASET} + else + echo "No children datasets finded." + fi +} -/usr/sbin/zonecfg -z $UUID export > $LFOLDER/$UUID/$UUID.`date +%Y%m%d`.cfg +################# +# main +################# -if [ $TYPE = "nfs" ]; then - umount $LFOLDER +echo "--- +BACKUP_SERVER: ${HOSTNAME} +UUID to backup: ${UUID} +---" + +create_dir ${UUID} + +check_snap ${UUID} + +if [ $? -ne 0 ]; then + create_snap ${UUID} +else + echo "Snapshot of ${UUID} already available" + echo "...done." fi -## TODO -# smb: query for username -# smb: query for password +send_snap ${UUID} + +check_multidataset + +send_config diff --git a/zonemigrate.sh b/zonemigrate.sh index a3699a9..e061d3b 100755 --- a/zonemigrate.sh +++ b/zonemigrate.sh @@ -97,20 +97,6 @@ echo "exportamos configuracion y enviamos a destino..." zonecfg -z ${UUID} export | $SSH $SERVER "zonecfg -z ${UUID}" -# modificamos de acuerdo a la config de datacenter remoto -echo "modificamos config de acuerdo a datacenter remoto..." - -echo " -select net physical=eth0 - clear vlan-id - set global-nic=v/100 - add property (name=mtu,value="1200") - remove property (name=gateway,value="194.53.148.1") - remove property (name=gateways,value="194.53.148.1") - add property (name=gateway,value="194.53.148.2") - add property (name=gateways,value="194.53.148.2") -end" | $SSH $SERVER "zonecfg -z ${UUID}" - # montamos el dataset $SSH $SERVER zfs mount ${ZONEPATH} @@ -125,13 +111,12 @@ zoneadm -z ${UUID} halt # actualizamos la zona en local para que no inicie -vmadm udpate ${UUID} autoboot=false +vmadm update ${UUID} autoboot=false # iniciamos la zona en remoto $SSH $SERVER zoneadm -z ${UUID} boot - # TODO: # - puede haber mas de un FILESYSTEM en la zona, necesitamos iterar por el array y lanzar la funcion snapshot sobre cada uno de ellos # - puede haber mas de un DATASET en la zona, necesitamos iterar por el array y lanzar la funcion snapshot sobre cada uno -- 2.24.1