#!/bin/bash # Parameters: # $1 is the vagrant install mode or user name to SSH as (see "Usage:" below) # $2 is the IP address of the bootstrap node # $3 is the optional knife recipe name, default "Test-Laptop" source ./virtualbox_env.sh source ./vmware/vmware_env.sh if [[ $OSTYPE == msys || $OSTYPE == cygwin ]] { # try to fix permission mismatch between windows and real unix global RSYNCEXTRA := '"--perms --chmod=a=rwx,Da+x'" } if [[ -f ./proxy_setup.sh ]] { source ./proxy_setup.sh } set -e global DIR := $[dirname $0] if [[ $# -gt 1 ]] { global KEYFILE := '"bootstrap_chef.id_rsa'" global IP := $2 global BCPC_DIR := '"chef-bcpc'" global VAGRANT := ''"" global VMWARE := ''"" global VBOX := ''"" # override the ssh-user and keyfile if using Vagrant if [[ $1 == "--vagrant-local" ]] { echo "Running on the local Vagrant VM" global VAGRANT := '"true'" global VBOX := '"true'" global BCPC_DIR := '"~vagrant/chef-bcpc'" global SSH_USER := $USER global SSH_CMD := '"bash -c'" } elif [[ $1 == "--vagrant-remote" ]] { echo "SSHing to the Vagrant VM" global VAGRANT := '"true'" global VBOX := '"true'" global BCPC_DIR := '"~vagrant/chef-bcpc'" global SSH_USER := '"vagrant'" global SSH_CMD := '"vagrant ssh -c'" } elif [[ $1 == "--vagrant-vmware" ]] { echo "SSHing to the Vagrant VM (on VMware)" global VAGRANT := '"true'" global VMWARE := '"true'" global BCPC_DIR := '"~vagrant/chef-bcpc'" global SSH_USER := '"vagrant'" global SSH_CMD := '"vagrant ssh -c'" global DIR := "$DIR/vmware" if [[ -z "$VMRUN" ]] { echo "vmrun not found!" > !2 echo " Please ensure VMWare is installed and vmrun is accessible." > !2 exit 1 } } else { global SSH_USER := $1 global SSH_CMD := ""ssh -t -i $KEYFILE $(SSH_USER)@$(IP)"" echo "SSHing to the non-Vagrant machine $(IP) as $(SSH_USER)" } if [[ $# -ge 3 ]] { global CHEF_ENVIRONMENT := $3 } else { global CHEF_ENVIRONMENT := '"Test-Laptop'" } echo "Chef environment: $(CHEF_ENVIRONMENT)" } else { echo "Usage: $[basename $0] --vagrant-local|--vagrant-remote|--vagrant-vmware| IP-Address [chef environment]" >> /dev/stderr exit } # protect against rsyncing to the wrong bootstrap node if [[ ! -f "environments/${CHEF_ENVIRONMENT}.json" ]] { echo "Error: environment file $(CHEF_ENVIRONMENT).json not found" exit } pushd $DIR if [[ -z $VAGRANT ]] { global ISO := 'ubuntu-14.04-mini.iso' if [[ ! -f $KEYFILE ]] { ssh-keygen -N "" -f $KEYFILE } echo "Running rsync of non-Vagrant install" rsync $RSYNCEXTRA -avP -e "ssh -i $KEYFILE" --exclude vbox --exclude vmware --exclude $KEYFILE --exclude .chef . $(SSH_USER)@$IP:chef-bcpc rsync $RSYNCEXTRA -avP -e "ssh -i $KEYFILE" vbox/$ISO $(SSH_USER)@$IP:chef-bcpc/cookbooks/bcpc/files/default/bins $SSH_CMD "cd $BCPC_DIR && ./setup_ssh_keys.sh $(KEYFILE).pub" } else { echo "Running rsync of Vagrant install" $SSH_CMD "rsync $RSYNCEXTRA -avP --exclude vbox --exclude vmware --exclude .chef /chef-bcpc-host/ /home/vagrant/chef-bcpc/" echo "Rsync over the hypervisor mini ISO to avoid redownloading" $SSH_CMD "rsync $RSYNCEXTRA -avP /chef-bcpc-host/vbox/$ISO /home/vagrant/chef-bcpc/cookbooks/bcpc/files/default/bins" } echo "Updating server" $SSH_CMD "cd $BCPC_DIR && sudo apt-get -y update && sudo apt-get -y dist-upgrade" if [[ -n "$VBOX" && -z `$VBM snapshot bcpc-bootstrap list | grep dist-upgrade` ]] { echo "Taking snapshot (VirtualBox)" $VBM snapshot bcpc-bootstrap take dist-upgrade-complete } if test -n $VMWARE { global VM_PATH := $[ls -d .vagrant/machines/bootstrap/vmware_fusion/*/] global VMX_FILE := "$VM_PATH/precise64.vmx" if [[ -z `"$VMRUN" listSnapshots $VMX_FILE | grep dist-upgrade` ]] { echo "Taking snapshot (VMware)" $VMRUN snapshot $VMX_FILE dist-upgrade-complete } } echo "Building binaries" $SSH_CMD "cd $BCPC_DIR && sudo ./cookbooks/bcpc/files/default/build_bins.sh" echo "Setting up chef server" $SSH_CMD "cd $BCPC_DIR && sudo ./setup_chef_server.sh $(IP)" echo "Setting up chef cookbooks" $SSH_CMD "cd $BCPC_DIR && ./setup_chef_cookbooks.sh $(IP) $(SSH_USER)" echo "Setting up chef environment, roles, and uploading cookbooks" $SSH_CMD "cd $BCPC_DIR && knife environment from file environments/$(CHEF_ENVIRONMENT).json && knife role from file roles/*.json && knife cookbook upload -a -o cookbooks" echo "Enrolling local bootstrap node into chef" $SSH_CMD "cd $BCPC_DIR && ./setup_chef_bootstrap_node.sh $(IP) $(CHEF_ENVIRONMENT)" echo "Configuring SSH access keys for bootstrap procedure" $SSH_CMD "cd $BCPC_DIR && sudo ./install_bootstrap_ssh_key.sh" popd echo "Finished bootstrap of Chef server!" (CommandList children: [ (C {(source)} {(./virtualbox_env.sh)}) (C {(source)} {(./vmware/vmware_env.sh)}) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (LogicalOr left: (BoolBinary op_id: BoolBinary_GlobDEqual left: {($ VSub_Name "$OSTYPE")} right: {(msys)} ) right: (BoolBinary op_id: BoolBinary_GlobDEqual left: {($ VSub_Name "$OSTYPE")} right: {(cygwin)} ) ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:RSYNCEXTRA) op: Equal rhs: {(DQ ("--perms --chmod=a=rwx,Da+x"))} spids: [54] ) ] spids: [54] ) ] spids: [-1 47] ) ] spids: [-1 59] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr:(BoolUnary op_id:BoolUnary_f child:{(./proxy_setup.sh)})) terminator: ) ] action: [(C {(.)} {(./proxy_setup.sh)})] spids: [-1 73] ) ] spids: [-1 80] ) (C {(set)} {(-e)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DIR) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(dirname)} {($ VSub_Number "$0")})]) left_token: spids: [89 93] ) } spids: [88] ) ] spids: [88] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id:BoolBinary_gt left:{($ VSub_Pound "$#")} right:{(1)}) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:KEYFILE) op: Equal rhs: {(DQ (bootstrap_chef.id_rsa))} spids: [112] ) ] spids: [112] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:IP) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [118] ) ] spids: [118] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:BCPC_DIR) op: Equal rhs: {(DQ (chef-bcpc))} spids: [124] ) ] spids: [124] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:VAGRANT) op:Equal rhs:{(DQ )} spids:[130])] spids: [130] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:VMWARE) op:Equal rhs:{(DQ )} spids:[135])] spids: [135] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:VBOX) op:Equal rhs:{(DQ )} spids:[140])] spids: [140] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobDEqual left: {($ VSub_Number "$1")} right: {(DQ (--vagrant-local))} ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("Running on the local Vagrant VM"))}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VAGRANT) op: Equal rhs: {(DQ (true))} spids: [174] ) ] spids: [174] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VBOX) op: Equal rhs: {(DQ (true))} spids: [180] ) ] spids: [180] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:BCPC_DIR) op: Equal rhs: {(DQ ("~vagrant/chef-bcpc"))} spids: [186] ) ] spids: [186] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_USER) op: Equal rhs: {(DQ ($ VSub_Name "$USER"))} spids: [192] ) ] spids: [192] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_CMD) op: Equal rhs: {(DQ ("bash -c"))} spids: [198] ) ] spids: [198] ) ] spids: [-1 164] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobDEqual left: {($ VSub_Number "$1")} right: {(DQ (--vagrant-remote))} ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("SSHing to the Vagrant VM"))}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VAGRANT) op: Equal rhs: {(DQ (true))} spids: [229] ) ] spids: [229] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VBOX) op: Equal rhs: {(DQ (true))} spids: [235] ) ] spids: [235] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:BCPC_DIR) op: Equal rhs: {(DQ ("~vagrant/chef-bcpc"))} spids: [241] ) ] spids: [241] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_USER) op: Equal rhs: {(DQ (vagrant))} spids: [247] ) ] spids: [247] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_CMD) op: Equal rhs: {(DQ ("vagrant ssh -c"))} spids: [253] ) ] spids: [253] ) ] spids: [204 219] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobDEqual left: {($ VSub_Number "$1")} right: {(DQ (--vagrant-vmware))} ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("SSHing to the Vagrant VM (on VMware)"))}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VAGRANT) op: Equal rhs: {(DQ (true))} spids: [284] ) ] spids: [284] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VMWARE) op: Equal rhs: {(DQ (true))} spids: [290] ) ] spids: [290] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:BCPC_DIR) op: Equal rhs: {(DQ ("~vagrant/chef-bcpc"))} spids: [296] ) ] spids: [296] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_USER) op: Equal rhs: {(DQ (vagrant))} spids: [302] ) ] spids: [302] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_CMD) op: Equal rhs: {(DQ ("vagrant ssh -c"))} spids: [308] ) ] spids: [308] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DIR) op: Equal rhs: {($ VSub_Name "$DIR") (/vmware)} spids: [314] ) ] spids: [314] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id: BoolUnary_z child: {(DQ ($ VSub_Name "$VMRUN"))} ) ) terminator: ) ] action: [ (SimpleCommand words: [{(echo)} {(DQ ("vmrun not found!"))}] redirects: [ (Redir op_id: Redir_GreatAnd fd: -1 arg_word: {(2)} spids: [341] ) ] ) (SimpleCommand words: [ {(echo)} { (DQ ( " Please ensure VMWare is installed and vmrun is accessible." ) ) } ] redirects: [ (Redir op_id: Redir_GreatAnd fd: -1 arg_word: {(2)} spids: [351] ) ] ) (C {(exit)} {(1)}) ] spids: [-1 332] ) ] spids: [-1 360] ) ] spids: [259 274] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_USER) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [366] ) ] spids: [366] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SSH_CMD) op: Equal rhs: { (DQ ("ssh -t -i ") ($ VSub_Name "$KEYFILE") (" ") (${ VSub_Name SSH_USER) ("@") (${ VSub_Name IP) ) } spids: [372] ) ] spids: [372] ) (C {(echo)} { (DQ ("SSHing to the non-Vagrant machine ") (${ VSub_Name IP) (" as ") (${ VSub_Name SSH_USER) ) } ) ] spids: [363 402] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id:BoolBinary_ge left:{($ VSub_Pound "$#")} right:{(3)}) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:CHEF_ENVIRONMENT) op: Equal rhs: {(DQ ($ VSub_Number "$3"))} spids: [421] ) ] spids: [421] ) ] spids: [-1 418] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:CHEF_ENVIRONMENT) op: Equal rhs: {(DQ (Test-Laptop))} spids: [430] ) ] spids: [430] ) ] spids: [427 436] ) (C {(echo)} {(DQ ("Chef environment: ") (${ VSub_Name CHEF_ENVIRONMENT))}) ] spids: [-1 109] ) ] else_action: [ (SimpleCommand words: [ {(echo)} { (DQ ("Usage: ") (CommandSubPart command_list: (CommandList children:[(C {(basename)} {($ VSub_Number "$0")})]) left_token: spids: [455 459] ) (" --vagrant-local|--vagrant-remote|--vagrant-vmware| IP-Address [chef environment]") ) } ] redirects: [(Redir op_id:Redir_DGreat fd:-1 arg_word:{(/dev/stderr)} spids:[463])] ) (C {(exit)}) ] spids: [448 470] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (LogicalNot child: (BoolUnary op_id: BoolUnary_f child: {(DQ (environments/) (${ VSub_Name CHEF_ENVIRONMENT) (.json))} ) ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("Error: environment file ") (${ VSub_Name CHEF_ENVIRONMENT) (".json not found"))} ) (C {(exit)}) ] spids: [-1 495] ) ] spids: [-1 511] ) (C {(pushd)} {($ VSub_Name "$DIR")}) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr:(BoolUnary op_id:BoolUnary_z child:{($ VSub_Name "$VAGRANT")})) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ISO) op: Equal rhs: {(ubuntu-14.04-mini.iso)} spids: [533] ) ] spids: [533] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (LogicalNot child: (BoolUnary op_id:BoolUnary_f child:{($ VSub_Name "$KEYFILE")}) ) ) terminator: ) ] action: [(C {(ssh-keygen)} {(-N)} {(DQ )} {(-f)} {($ VSub_Name "$KEYFILE")})] spids: [-1 550] ) ] spids: [-1 565] ) (C {(echo)} {(DQ ("Running rsync of non-Vagrant install"))}) (C {(rsync)} {($ VSub_Name "$RSYNCEXTRA")} {(-avP)} {(-e)} {(DQ ("ssh -i ") ($ VSub_Name "$KEYFILE"))} {(--exclude)} {(vbox)} {(--exclude)} {(vmware)} {(--exclude)} {($ VSub_Name "$KEYFILE")} {(--exclude)} {(.chef)} {(.)} {(${ VSub_Name SSH_USER) (Lit_Other "@") ($ VSub_Name "$IP") (Lit_Other ":") (chef-bcpc)} ) (C {(rsync)} {($ VSub_Name "$RSYNCEXTRA")} {(-avP)} {(-e)} {(DQ ("ssh -i ") ($ VSub_Name "$KEYFILE"))} {(vbox/) ($ VSub_Name "$ISO")} {(${ VSub_Name SSH_USER) (Lit_Other "@") ($ VSub_Name "$IP") (Lit_Other ":") (chef-bcpc/cookbooks/bcpc/files/default/bins) } ) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && ./setup_ssh_keys.sh ") (${ VSub_Name KEYFILE) (.pub) ) } ) ] spids: [-1 530] ) ] else_action: [ (C {(echo)} {(DQ ("Running rsync of Vagrant install"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("rsync ") ($ VSub_Name "$RSYNCEXTRA") ( " -avP --exclude vbox --exclude vmware --exclude .chef /chef-bcpc-host/ /home/vagrant/chef-bcpc/" ) ) } ) (C {(echo)} {(DQ ("Rsync over the hypervisor mini ISO to avoid redownloading"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("rsync ") ($ VSub_Name "$RSYNCEXTRA") (" -avP /chef-bcpc-host/vbox/") ($ VSub_Name "$ISO") (" /home/vagrant/chef-bcpc/cookbooks/bcpc/files/default/bins") ) } ) ] spids: [653 689] ) (C {(echo)} {(DQ ("Updating server"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && sudo apt-get -y update && sudo apt-get -y dist-upgrade") ) } ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (LogicalAnd left: (BoolUnary op_id:BoolUnary_n child:{(DQ ($ VSub_Name "$VBOX"))}) right: (BoolUnary op_id: BoolUnary_z child: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {($ VSub_Name "$VBM")} {(snapshot)} {(bcpc-bootstrap)} {(list)} ) (C {(grep)} {(dist-upgrade)}) ] negated: False ) ] ) left_token: spids: [720 734] ) } ) ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("Taking snapshot (VirtualBox)"))}) (C {($ VSub_Name "$VBM")} {(snapshot)} {(bcpc-bootstrap)} {(take)} {(dist-upgrade-complete)}) ] spids: [-1 739] ) ] spids: [-1 759] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$VMWARE"))} {(Lit_Other "]")}) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VM_PATH) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(ls)} {(-d)} {(.vagrant/machines/bootstrap/vmware_fusion/) (Lit_Other "*") (/)} ) ] ) left_token: spids: [778 786] ) } spids: [777] ) ] spids: [777] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:VMX_FILE) op: Equal rhs: {($ VSub_Name "$VM_PATH") (/precise64.vmx)} spids: [789] ) ] spids: [789] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id: BoolUnary_z child: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(DQ ($ VSub_Name "$VMRUN"))} {(listSnapshots)} {($ VSub_Name "$VMX_FILE")} ) (C {(grep)} {(dist-upgrade)}) ] negated: False ) ] ) left_token: spids: [800 814] ) } ) ) terminator: ) ] action: [ (C {(echo)} {(DQ ("Taking snapshot (VMware)"))}) (C {(DQ ($ VSub_Name "$VMRUN"))} {(snapshot)} {($ VSub_Name "$VMX_FILE")} {(dist-upgrade-complete)} ) ] spids: [-1 819] ) ] spids: [-1 840] ) ] spids: [-1 774] ) ] spids: [-1 842] ) (C {(echo)} {(DQ ("Building binaries"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && sudo ./cookbooks/bcpc/files/default/build_bins.sh")) } ) (C {(echo)} {(DQ ("Setting up chef server"))}) (C {($ VSub_Name "$SSH_CMD")} {(DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && sudo ./setup_chef_server.sh ") (${ VSub_Name IP))} ) (C {(echo)} {(DQ ("Setting up chef cookbooks"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && ./setup_chef_cookbooks.sh ") (${ VSub_Name IP) (" ") (${ VSub_Name SSH_USER) ) } ) (C {(echo)} {(DQ ("Setting up chef environment, roles, and uploading cookbooks"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && knife environment from file environments/") (${ VSub_Name CHEF_ENVIRONMENT) (".json && knife role from file roles/*.json && knife cookbook upload -a -o cookbooks") ) } ) (C {(echo)} {(DQ ("Enrolling local bootstrap node into chef"))}) (C {($ VSub_Name "$SSH_CMD")} { (DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && ./setup_chef_bootstrap_node.sh ") (${ VSub_Name IP) (" ") (${ VSub_Name CHEF_ENVIRONMENT) ) } ) (C {(echo)} {(DQ ("Configuring SSH access keys for bootstrap procedure"))}) (C {($ VSub_Name "$SSH_CMD")} {(DQ ("cd ") ($ VSub_Name "$BCPC_DIR") (" && sudo ./install_bootstrap_ssh_key.sh"))} ) (C {(popd)}) (C {(echo)} {(DQ ("Finished bootstrap of Chef server!"))}) ] )