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

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