#!/bin/bash # # Quick script to take snapshots after OS build. # TODO: Rewrite me in ruby... the whole thing. hash -r proc wait_for_ssh{ var hostname = $1 var min = $(2:-1), max = $(3:-10) if test -z $(hostname) { return 1 ; } exec !3 > !2 exec !2 >/dev/null while true { if echo > /dev/tcp/$(hostname)/22 { return 0 } sleep $( $RANDOM % $max + $min ) } exec !2 > !3 exec !3 > !- } proc wait_for_snapshot{ var ip = $1 if test -z $(ip) { return 1 } var vmname = $[ip_to_name $(ip)] || return 2 echo "Waiting to snapshot $(vmname) at $(ip)..." wait_for_ssh $(ip) VBoxManage snapshot $(vmname) take build_completed --description "Base OS installed" } # This is highly presumptive proc ip_to_name{ if test -z $1 { return 1 ; } var l = $(1##*.) l := $(l-10) echo "bcpc-vm$(l)" } for ip in [10.0.100.{11..13}] { eval "wait_for_snapshot $(ip) &" ; } wait (CommandList children: [ (C {(hash)} {(-r)}) (FuncDef name: wait_for_ssh body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:hostname) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [25] ) ] spids: [23] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:min) op: Equal rhs: { (BracedVarSub token: suffix_op: (StringUnary op_id:VTest_ColonHyphen arg_word:{(1)}) spids: [34 38] ) } spids: [33] ) (assign_pair lhs: (LhsName name:max) op: Equal rhs: { (BracedVarSub token: suffix_op: (StringUnary op_id:VTest_ColonHyphen arg_word:{(10)}) spids: [41 45] ) } spids: [40] ) ] spids: [31] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-z)} {(DQ (${ VSub_Name hostname))} {(Lit_Other "]")}) terminator: ) ] action: [ (Sentence child: (ControlFlow token: arg_word:{(1)}) terminator: ) ] spids: [-1 65] ) ] spids: [-1 73] ) (SimpleCommand words: [{(exec)}] redirects: [(Redir op_id:Redir_GreatAnd fd:3 arg_word:{(2)} spids:[78])] ) (SimpleCommand words: [{(exec)}] redirects: [(Redir op_id:Redir_Great fd:2 arg_word:{(/dev/null)} spids:[84])] ) (While cond: [(Sentence child:(C {(true)}) terminator:)] body: (DoGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (SimpleCommand words: [{(echo)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/dev/tcp/) (${ VSub_Name hostname) (/22)} spids: [101] ) ] ) terminator: ) ] action: [(ControlFlow token: arg_word:{(0)})] spids: [-1 111] ) ] spids: [-1 119] ) (C {(sleep)} { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithBinary op_id: Arith_Percent left: (ArithWord w:{($ VSub_Name "$RANDOM")}) right: (ArithWord w:{($ VSub_Name "$max")}) ) right: (ArithWord w:{($ VSub_Name "$min")}) ) spids: [124 137] ) } ) ] spids: [94 140] ) ) (SimpleCommand words: [{(exec)}] redirects: [(Redir op_id:Redir_GreatAnd fd:2 arg_word:{(3)} spids:[145])] ) (SimpleCommand words: [{(exec)}] redirects: [(Redir op_id:Redir_GreatAnd fd:3 arg_word:{(-)} spids:[151])] ) ] spids: [20] ) spids: [17 20] ) (FuncDef name: wait_for_snapshot body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:ip) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [165] ) ] spids: [163] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-z)} {(DQ (${ VSub_Name ip))} {(Lit_Other "]")}) terminator: ) ] action: [(ControlFlow token: arg_word:{(1)})] spids: [-1 187] ) ] spids: [-1 195] ) (AndOr children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:vmname) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(ip_to_name)} {(${ VSub_Name ip)})] ) left_token: spids: [202 208] ) ) } spids: [200] ) ] spids: [198] ) (ControlFlow token: arg_word:{(2)}) ] op_id: Op_DPipe ) (C {(echo)} {(DQ ("Waiting to snapshot ") (${ VSub_Name vmname) (" at ") (${ VSub_Name ip) (...))} ) (C {(wait_for_ssh)} {(DQ (${ VSub_Name ip))}) (C {(VBoxManage)} {(snapshot)} {(DQ (${ VSub_Name vmname))} {(take)} {(build_completed)} {(--description)} {(DQ ("Base OS installed"))} ) ] spids: [160] ) spids: [157 160] ) (FuncDef name: ip_to_name body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-z)} {(DQ ($ VSub_Number "$1"))} {(Lit_Other "]")}) terminator: ) ] action: [ (Sentence child: (ControlFlow token: arg_word:{(1)}) terminator: ) ] spids: [-1 288] ) ] spids: [-1 296] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:l) op: Equal rhs: { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id:VOp1_DPound arg_word:{("*.")}) spids: [303 307] ) ) } spids: [301] ) ] spids: [299] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:l) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithVarRef name:l) right: (ArithWord w:{(Lit_Digits 10)}) ) spids: [312 317] ) } spids: [311] ) ] spids: [311] ) (C {(echo)} {(DQ (bcpc-vm) (${ VSub_Name l))}) ] spids: [271] ) spids: [268 271] ) (ForEach iter_name: ip iter_words: [{(10.0.100.) (Lit_LBrace "{") (11..13) (Lit_RBrace "}")}] do_arg_iter: False body: (DoGroup children: [ (Sentence child: (C {(eval)} {(DQ ("wait_for_snapshot ") (${ VSub_Name ip) (" &"))}) terminator: ) ] spids: [345 359] ) spids: [337 343] ) (C {(wait)}) ] )