github.com/vmware/govmomi@v0.51.0/toolbox/toolbox-test.sh (about)

     1  #!/bin/bash -e
     2  
     3  # © Broadcom. All Rights Reserved.
     4  # The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     5  # SPDX-License-Identifier: Apache-2.0
     6  #
     7  # Create (or reuse) a VM to run toolbox and/or toolbox.test
     8  # Requires ESX to be configured with:
     9  # govc host.esxcli system settings advanced set -o /Net/GuestIPHack -i 1
    10  
    11  set -o pipefail
    12  
    13  vm="toolbox-test-$(uuidgen)"
    14  destroy=true
    15  verbose=true
    16  
    17  while getopts n:qstv flag
    18  do
    19    case $flag in
    20      n)
    21        vm=$OPTARG
    22        unset destroy
    23        ;;
    24      q)
    25        verbose=false # you want this if generating lots of traffic, such as large file transfers
    26        ;;
    27      s)
    28        start=true
    29        ;;
    30      t)
    31        test=true
    32        ;;
    33      *)
    34        echo "unknown option" 1>&2
    35        exit 1
    36        ;;
    37    esac
    38  done
    39  
    40  echo "Building toolbox binaries..."
    41  pushd "$(git rev-parse --show-toplevel)" >/dev/null
    42  GOOS=linux GOARCH=amd64 go build -o "$GOPATH/bin/toolbox" -v ./toolbox/toolbox
    43  GOOS=linux GOARCH=amd64 go test -race -i -c ./toolbox -o "$GOPATH/bin/toolbox.test"
    44  popd >/dev/null
    45  
    46  iso=coreos_production_iso_image.iso
    47  
    48  govc datastore.mkdir -p images
    49  
    50  if ! govc datastore.ls images | grep -q $iso ; then
    51    echo "Downloading ${iso}..."
    52    if [ ! -e $iso ] ; then
    53      wget https://stable.release.core-os.net/amd64-usr/current/$iso
    54    fi
    55  
    56    echo "Uploading ${iso}..."
    57    govc datastore.upload $iso images/$iso
    58  fi
    59  
    60  if [ ! -e config.iso ] ; then
    61    echo "Generating config.iso..."
    62    keys=$(cat ~/.ssh/id_[rd]sa.pub)
    63  
    64    dir=$(mktemp -d toolbox.XXXXXX)
    65    pushd "${dir}" >/dev/null
    66  
    67    mkdir -p drive/openstack/latest
    68  
    69    cat > drive/openstack/latest/user_data <<EOF
    70  #!/bin/bash
    71  
    72  # Add ${USER}'s public key(s) to .ssh/authorized_keys
    73  echo "$keys" | update-ssh-keys -u core -a coreos-cloudinit
    74  EOF
    75    genisoimage=$(type -p genisoimage mkisofs | head -1)
    76    $genisoimage -R -V config-2 -o config.iso ./drive
    77  
    78    popd >/dev/null
    79  
    80    mv -f "$dir/config.iso" .
    81    rm -rf "$dir"
    82  fi
    83  
    84  govc datastore.mkdir -p "$vm"
    85  
    86  vm_path="$(govc find / -type m -name "$vm")"
    87  
    88  if [ -z "$vm_path" ] ; then
    89    echo "Creating VM ${vm}..."
    90    govc vm.create -g otherGuest64 -m 2048 -on=false "$vm"
    91  
    92    device=$(govc device.cdrom.add -vm "$vm")
    93    govc device.cdrom.insert -vm "$vm" -device "$device" images/$iso
    94  
    95    govc datastore.upload config.iso "$vm/config.iso" >/dev/null
    96    device=$(govc device.cdrom.add -vm "$vm")
    97    govc device.cdrom.insert -vm "$vm" -device "$device" "$vm/config.iso"
    98  
    99    vm_path="$(govc find / -type m -name "$vm")"
   100  else
   101    govc object.collect -s "$vm_path" -guest.toolsStatus toolsNot* # wait for previous toolbox to unregister
   102  fi
   103  
   104  state=$(govc object.collect -s "$vm_path" runtime.powerState)
   105  
   106  if [ "$state" != "poweredOn" ] ; then
   107    govc vm.power -on "$vm"
   108  fi
   109  
   110  echo -n "Waiting for ${vm} ip..."
   111  ip=$(govc vm.ip -esxcli "$vm")
   112  
   113  opts=(-o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" -o "LogLevel error" -o "BatchMode yes")
   114  
   115  destroy() {
   116    if [ -n "$test" ] ; then
   117      rm -f "$GOVC_TLS_KNOWN_HOSTS"
   118    fi
   119  
   120    if [ -n "$destroy" ] ; then
   121      echo "Destroying VM ${vm}..."
   122      govc vm.destroy "$vm"
   123      govc datastore.rm -f "$vm"
   124    else
   125      ssh "${opts[@]}" "core@${ip}" pkill toolbox || true
   126    fi
   127  }
   128  
   129  trap destroy EXIT
   130  
   131  scp "${opts[@]}" "$GOPATH"/bin/toolbox{,.test} "core@${ip}:"
   132  
   133  if [ -n "$test" ] ; then
   134    # validate guest.FileManager adds the host thumbprint when transferring files
   135    unset GOVC_INSECURE
   136    GOVC_TLS_KNOWN_HOSTS=$(mktemp --tmpdir toolbox.XXXXXX)
   137    govc about.cert -k -thumbprint > "$GOVC_TLS_KNOWN_HOSTS"
   138  
   139    export GOVC_TLS_KNOWN_HOSTS GOVC_GUEST_LOGIN=user:pass
   140  
   141    echo "Running toolbox tests..."
   142    ssh "${opts[@]}" "core@${ip}" ./toolbox.test -test.v=$verbose -test.run TestServiceRunESX -toolbox.testesx \
   143        -toolbox.testpid="$$" -toolbox.powerState="$state" &
   144  
   145    echo "Waiting for VM ip from toolbox..."
   146    ip=$(govc vm.ip "$vm")
   147    echo "toolbox vm.ip=$ip"
   148  
   149    echo "Testing guest.{start,kill,ps} operations via govc..."
   150    export GOVC_VM="$vm"
   151  
   152    # should be 0 procs as toolbox only lists processes it started, for now
   153    test -z "$(govc guest.ps -e | grep -v STIME)"
   154  
   155    out=$(govc guest.start /bin/date)
   156  
   157    if [ "$out" != "$$" ] ; then
   158      echo "'$out' != '$$'" 1>&2
   159    fi
   160  
   161    # These processes would run for 1h if we didn't kill them.
   162    pid=$(govc guest.start sleep 1h)
   163  
   164    echo "Killing func $pid..."
   165    govc guest.kill -p "$pid"
   166    govc guest.ps -e -p "$pid" -X | grep "$pid"
   167    govc guest.ps -e -p "$pid" -json | jq -r .ProcessInfo[].ExitCode | grep -q 42
   168  
   169    pid=$(govc guest.start /bin/sh -c "sleep 3600")
   170    echo "Killing proc $pid..."
   171    govc guest.kill -p "$pid"
   172    govc guest.ps -e -p "$pid" -X | grep "$pid"
   173  
   174    echo "Testing file copy to and from guest via govc..."
   175    base="$(basename "$0")"
   176    dest="/tmp/$base"
   177  
   178    govc guest.upload -f -perm 0640 -gid 10 "$0" "$dest"
   179    govc guest.download "$dest" - | md5sum --quiet -c <(<"$0" md5sum)
   180    govc guest.chmod 0755 "$dest"
   181    govc guest.ls "$dest" | grep rwxr-xr-x
   182  
   183    echo "Testing custom hgfs.FileHandler..."
   184    if ! govc guest.download "/echo:$dest" - 2>/dev/null ; then
   185        govc guest.download "/echo:$dest?foo=bar" - >/dev/null
   186    fi
   187  
   188    home=$(govc guest.getenv HOME | cut -d= -f2)
   189  
   190    if date | govc guest.upload -f - /tmp 2>/dev/null ; then
   191      echo "guest.upload to directory should fail without .tgz source" 1>&2
   192      exit 1
   193    fi
   194  
   195    if [ "$verbose" = "false" ] ; then # else you don't want to see this noise
   196      # Download the $HOME directory, includes toolbox binaries (~30M total)
   197      # Note: trailing slash is required
   198      prefix=$(basename "$home")
   199      govc guest.download "$home/?prefix=$prefix/&format=tgz" - | tar -tzvf - | grep "$prefix"/toolbox
   200  
   201      govc guest.mkdir -p /tmp/toolbox-src
   202      # Upload source files from this directory
   203      # and validate that query string is not used as the file/dir name (see hgfs.ArchiveHandler)
   204      git archive --format tgz HEAD | govc guest.upload -f - /tmp/toolbox-src?skip=stuff
   205      # Upload .tar
   206      git archive --format tar HEAD | govc guest.upload -f - /tmp/toolbox-src
   207      # Download .tar
   208      govc guest.download "/tmp/toolbox-src/" - | tar -tvf - | grep "$base"
   209      # Download a single file as a .tar.gz (note: /archive: prefix is required)
   210      govc guest.download "/archive:/tmp/toolbox-src/$base?format=tgz" - | tar -tvzf - | grep -v README.md
   211      # Download a single file as a .tar (note: /archive: prefix is required)
   212      govc guest.download "/archive:/tmp/toolbox-src/$base" - | tar -tvf - | grep -v README.md
   213      govc guest.rmdir -r /tmp/toolbox-src
   214    fi
   215  
   216    echo "Testing we can download /proc files..."
   217    for name in uptime diskstats net/dev ; do
   218      test -n "$(govc guest.download /proc/$name -)"
   219    done
   220  
   221    echo "Testing commands with IO..."
   222    # Note that we don't use a pipe here, as guest.ps transitions the vm to VM_STATE_GUEST_OPERATION,
   223    # which prevents guest.run from invoking guest operations.  By letting guest.ps complete before
   224    # guest.run, the vm will have transitioned back to VM_STATE_POWERED_ON.
   225    data=$(govc guest.ps -json)
   226    govc guest.run -d "$data" jq .
   227  
   228    # test ProcessIO download retries
   229    govc version | govc guest.run -d - bash -c "'sleep 2 && cat'"
   230  
   231    echo "Waiting for tests to complete..."
   232    wait
   233  fi
   234  
   235  if [ -n "$start" ] ; then
   236    (
   237      govc object.collect -s "$vm_path" -guest.toolsStatus toolsOk # wait for toolbox to register
   238      /usr/bin/time -f "Waiting for VM ip from toolbox...%e" govc vm.ip -v4 -n ethernet-0 "$vm"
   239    ) &
   240  
   241    echo "Starting toolbox..."
   242    ssh "${opts[@]}" "core@${ip}" ./toolbox -toolbox.trace=$verbose
   243  fi