* Add Virtual Kubelet provider for VIC Initial virtual kubelet provider for VMware VIC. This provider currently handles creating and starting of a pod VM via the VIC portlayer and persona server. Image store handling via the VIC persona server. This provider currently requires the feature/wolfpack branch of VIC. * Added pod stop and delete. Also added node capacity. Added the ability to stop and delete pod VMs via VIC. Also retrieve node capacity information from the VCH. * Cleanup and readme file Some file clean up and added a Readme.md markdown file for the VIC provider. * Cleaned up errors, added function comments, moved operation code 1. Cleaned up error handling. Set standard for creating errors. 2. Added method prototype comments for all interface functions. 3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder. * Add mocking code and unit tests for podcache, podcreator, and podstarter Used the unit test framework used in VIC to handle assertions in the provider's unit test. Mocking code generated using OSS project mockery, which is compatible with the testify assertion framework. * Vendored packages for the VIC provider Requires feature/wolfpack branch of VIC and a few specific commit sha of projects used within VIC. * Implementation of POD Stopper and Deleter unit tests (#4) * Updated files for initial PR
372 lines
11 KiB
Bash
Executable File
372 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
# Copyright 2016 VMware, Inc. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
# utility functions for staged authoring of ISOs
|
|
[ -n "$DEBUG" ] && set -x
|
|
BASE_DIR=$(dirname $(readlink -f "$BASH_SOURCE"))
|
|
|
|
if [ -z ${BUILD_NUMBER+x} ]; then
|
|
BUILD_NUMBER=0
|
|
fi
|
|
|
|
VERSION=`git describe --abbrev=0 --tags`-${BUILD_NUMBER}-`git rev-parse --short HEAD`
|
|
|
|
# initialize a directory with the assumptions we make for authoring
|
|
# 1: target directory
|
|
initialize_bundle() {
|
|
mkdir -p $1
|
|
|
|
# we copy the xorriso config template during init as it's part of the base directory
|
|
# - variable replacement occurs during generation step however
|
|
cp $BASE_DIR/xorriso-options.cfg $1/xorriso-options.cfg
|
|
|
|
mkdir -p $1/rootfs/var/lib/rpm $1/bootfs/boot
|
|
|
|
rpm --root=$1/rootfs --initdb
|
|
cp -a $BASE_DIR/isolinux $1/bootfs/boot/isolinux
|
|
}
|
|
|
|
# unpackage working ISO filesystem bundle
|
|
# args:
|
|
# 1: package (tar archive) - created by pack()
|
|
# 2: directory to unpack to
|
|
unpack() {
|
|
mkdir -p $2 || {
|
|
echo "Unable to create target directory $2 for unpacking: $?" 1>&2
|
|
return 1
|
|
}
|
|
|
|
tar -C $2 -xf $1 || {
|
|
echo "Error extracting package archive $1: $?" 1>&2
|
|
return 2
|
|
}
|
|
|
|
# record the correct file ownerships and permissions if we cannot restore them
|
|
if [ "$(id -u)" != "0" ]; then
|
|
# for now we're just going to fail when this is run as non-root
|
|
echo "Unable to preserve ownership or permissions - run as root" 1>&2
|
|
return 3
|
|
|
|
# Leaving this in here for later reference - successfully restored permissions at
|
|
# boot time via a manifest and systemd unit but want to try to do so during build
|
|
# time if possible
|
|
echo "Storing correct file ownership and permissions restoration" 1>&2
|
|
|
|
# we need to chain these permission files, because when the archive is retarred
|
|
# we can no longer rely on tar tvf to supply the correct permissions.
|
|
# FILO because repeated non-superuser unpacks/pack cycles will trample attrs otherwise
|
|
if [ -e $2/tar-attr.cfg ]; then
|
|
mv $2/tar-attr.cfg $2/tar-attr.cfg~
|
|
fi
|
|
tar_attr_to_cmd $1 rootfs > $2/tar-attr.cfg || {
|
|
echo "Failed to preserve file owner and permissions - run as root to avoid this step: $?" 1>&2
|
|
return 4
|
|
}
|
|
|
|
# make those FI options, LO in the file
|
|
if [ -e $2/tar-attr.cfg~ ]; then
|
|
cat $2/tar-attr.cfg~ >> $2/tar-attr.cfg
|
|
rm -f $2/tar-attr.cfg~
|
|
fi
|
|
elif [ -e $2/tar-attr.cfg ]; then
|
|
# restore the recorded attributes
|
|
( cd $2/rootfs && . ../tar-attr.cfg ) || {
|
|
echo "Failed to restore file permissions from manifest: $?" 1>&2
|
|
return 5
|
|
}
|
|
fi
|
|
}
|
|
|
|
# package up bundle
|
|
# 1: bundle base directory
|
|
# 2: target package (tgz)
|
|
pack() {
|
|
#subshell so we don't end up with ./ leading all names
|
|
out=$(readlink -f $2)
|
|
(
|
|
cd $1
|
|
tar -zcf $out rootfs bootfs xorriso* || {
|
|
echo "Failed to package bundle directory: $?" 1>&2
|
|
return 1
|
|
}
|
|
)
|
|
|
|
if [ -z "$DEBUG" ]; then
|
|
rm -fr $1
|
|
fi
|
|
}
|
|
|
|
|
|
# turn the permissions and owner/group info into xorriso options
|
|
# 1: the archive to process
|
|
# 2: the subdir in the archive to restrict output to
|
|
tar_attr_to_xorriso() {
|
|
tar --numeric-owner -tvf $1 "$2" | awk -v prefix="$2" '
|
|
function convertId(id, type)
|
|
{
|
|
idcmd="id -" type " "id
|
|
|
|
idcmd | getline nid
|
|
close(idcmd)
|
|
|
|
return nid
|
|
}
|
|
|
|
function txt2octal(txt)
|
|
{
|
|
# this is used to convert between text perms and octal
|
|
v["r1"]=400; v["w2"]=200; v["x3"]=100; v["s3"]=4100; v["S3"]=4000
|
|
v["r4"]=40 ; v["w5"]=20 ; v["x6"]=10 ; v["s6"]=2010; v["S6"]=2000
|
|
v["r7"]=4 ; v["w8"]=2 ; v["x9"]=1 ; v["t9"]=1001; v["T9"]=1000
|
|
|
|
val=0
|
|
for (i=1; i<=9; i++)
|
|
val=val+v[substr(txt, i+1, 1)i]
|
|
|
|
return val
|
|
}
|
|
|
|
BEGIN {
|
|
}
|
|
/^[^l]/ {
|
|
# assemble the permissions mdoe
|
|
val=txt2octal($0)
|
|
|
|
# make our commands relative
|
|
sub(prefix, "." , $6)
|
|
|
|
# translate to numeric ids from textual
|
|
split($2, owner, "/")
|
|
uid=owner[1]
|
|
gid=owner[2]
|
|
|
|
# convert to numeric
|
|
# uid=convertId(uid,"u")
|
|
# gid=convertId(gid,"g")
|
|
|
|
chown[uid]=chown[uid]" "$6
|
|
chgrp[gid]=chgrp[gid]" "$6
|
|
chmod[val]=chmod[val]" "$6
|
|
}
|
|
END {
|
|
for (uid in chown)
|
|
print "chown", uid, chown[uid]
|
|
|
|
for (gid in chgrp)
|
|
print "chgrp", gid, chgrp[gid]
|
|
|
|
for (mode in chmod)
|
|
printf "chmod %4d %s\n", mode, chmod[mode]
|
|
}'
|
|
return $?
|
|
}
|
|
|
|
# Helper to ensure, if possible, that the specified packages are installed
|
|
# ...: space separted list of packages
|
|
ensure_apt_packages() {
|
|
local install
|
|
|
|
# ensure we've got the utils we need
|
|
for pkg in "$@"; do
|
|
dpkg -s $pkg >/dev/null 2>&1 || install="$install $pkg"
|
|
done
|
|
|
|
if [ -n "$install" ]; then
|
|
if [ "$(id -u)" != "0" ]; then
|
|
echo "Need to install packages - rerun as root" 1>&2
|
|
echo "packages: $install" 1>&2
|
|
return 1
|
|
fi
|
|
|
|
# try without update first
|
|
echo "Installing necessary packages: $install"
|
|
apt-get -y install $install >/dev/null 2>&1 || {
|
|
(apt-get update && apt-get -y install $install) || {
|
|
echo "Failed to install $install packages: $?" 1>&2
|
|
return 1
|
|
}
|
|
}
|
|
fi
|
|
}
|
|
|
|
# build an ISO from the specified bundle directory.
|
|
# 1: bundle base directory
|
|
# 2: output file for ISO image - stdio:/dev/fd/1 can be used for stdout
|
|
# 3: init binary to use
|
|
generate_iso() {
|
|
[ -n "$3" ] || {
|
|
echo "Init binary must be specified to generate_iso" 1>&2
|
|
return 1
|
|
}
|
|
|
|
ensure_apt_packages cpio xorriso || {
|
|
echo "cpio and xorriso packages must be installed for ISO authoring: $?" 1>&2
|
|
return 1
|
|
}
|
|
|
|
out=$(readlink -f $2)
|
|
# subshell to avoid changing directory for invoker in failure cases
|
|
(
|
|
# operate relative to the package
|
|
cd $1
|
|
|
|
test -r bootfs/boot/isolinux/isolinux.bin -a -w bootfs/boot/isolinux/isolinux.cfg || {
|
|
echo "isolinux files must exist in $1/boot/isolinux: $?" 1>&2
|
|
return 2
|
|
}
|
|
|
|
# ensure the target init exists
|
|
test -x rootfs/$3 || {
|
|
echo "Specified init ($3) does not exist or is not executable: $?" 1>&2
|
|
return 3
|
|
}
|
|
# set the init binary in isolinux.cfg
|
|
sed -i -e "s|^#\(\s*append rdinit\)=_INIT_BINARY_|\1=$3|" bootfs/boot/isolinux/isolinux.cfg || {
|
|
echo "Unable to update rdinit entry in isolinux.cfg: $?" 1>&2
|
|
return 4
|
|
}
|
|
|
|
# create the initramfs archive - subshell to avoid changing directory
|
|
echo "Constructing initramfs archive"
|
|
( cd rootfs && find | cpio -o -H newc | gzip --fast ) > bootfs/boot/core.gz || {
|
|
echo "Failed to package root filesystem from $1/rootfs: $?" 1>&2
|
|
return 5
|
|
}
|
|
|
|
echo "Embedding build version ${VERSION} (use BUILD_NUMBER environment variable to override)"
|
|
sed -i -e "s/\${VERSION}/${VERSION}/" xorriso-options.cfg
|
|
|
|
# deleting the file first seems to be necessary in some cases
|
|
rm -f "$out"
|
|
|
|
# generate the ISO and write it to $ISOOUT
|
|
xorriso -dev "$out" -options_from_file xorriso-options.cfg || {
|
|
echo "Failed to generate ISO file from package: $?" 1>&2
|
|
return 6
|
|
}
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
|
|
# Support use of yum cached packages with installroot
|
|
# This has been written to use getopts to:
|
|
# a. allow the cache to be optional
|
|
# b. as a reference for other functions
|
|
yum_cached() {
|
|
usage() { echo "Usage: yum_cached [-c yum-cache(tgz)] [-u (update cache if present)] -p package-dir <options>" 1>&2; }
|
|
|
|
# must ensure OPTIND is local, along with any set by processing
|
|
local OPTIND flag cache update INSTALLROOT cmds
|
|
while getopts "c:up:a:" flag; do
|
|
case $flag in
|
|
c)
|
|
# Optional. Cache name (tgz)
|
|
cache="$OPTARG"
|
|
;;
|
|
|
|
u)
|
|
# Optional. Update cache after running command
|
|
update="true"
|
|
;;
|
|
|
|
p)
|
|
# Required. Package directory
|
|
PKGDIR="$OPTARG"
|
|
INSTALLROOT=$(rootfs_dir $PKGDIR)
|
|
;;
|
|
|
|
*)
|
|
usage
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
|
|
cmds="$*"
|
|
|
|
# check there were no extra args and the required ones are set to sane values
|
|
[ -e "$PKGDIR" ] || {
|
|
echo "Specified package directory must exist" 1>&2
|
|
return 1
|
|
}
|
|
|
|
# bundle specific - if we're cleaning the cache and we want it all gone
|
|
# $1 because of the shift after getopts
|
|
if [ "$1" == "clean" -a "$2" == "all" ]; then
|
|
rm -fr ${INSTALLROOT}/var/cache/yum/*
|
|
else
|
|
# do this before we bother unpacking the cache
|
|
ensure_apt_packages yum || {
|
|
echo "cpio and xorriso packages must be installed for ISO authoring: $?" 1>&2
|
|
return 2
|
|
}
|
|
|
|
# unpack cache
|
|
if [ -n "${cache}" -a -e "${cache}" ]; then
|
|
echo "Unpacking yum cache into ${INSTALLROOT}"
|
|
|
|
tar -C ${INSTALLROOT} -zxf $cache || {
|
|
echo "Unpacking yum cache $cache failed: $?" 1>&2
|
|
return 3
|
|
}
|
|
fi
|
|
|
|
/usr/bin/yum --installroot $INSTALLROOT $ACTION $cmds || {
|
|
echo "Error while running yum command \"$cmds\": $?" 1>&2
|
|
return 4
|
|
}
|
|
fi
|
|
|
|
# repack cache
|
|
if [ -n "$update" -a -n "${cache}" -a -d ${INSTALLROOT}/var/cache/yum ]; then
|
|
tar -C ${INSTALLROOT} -zcf $cache var/cache/yum
|
|
fi
|
|
}
|
|
|
|
# Runs a command in the rootfs of the specified bundle. This prevents callers from needing
|
|
# to know about internal bundle structure
|
|
# 1: bundle directory
|
|
# ...: command and args
|
|
rootfs_cmd() {
|
|
(
|
|
cd $1/rootfs || {
|
|
echo "Specified directory $1 doesn't contain expected rootfs directory" 1>&2
|
|
return 1
|
|
}
|
|
|
|
shift 1
|
|
cmd=$1
|
|
shift 1
|
|
|
|
$cmd "$@" || return $?
|
|
)
|
|
}
|
|
|
|
# Echos the full path of the root filesystem, given the bundle directory
|
|
# 1: bundle directory
|
|
rootfs_dir() {
|
|
echo $1/rootfs
|
|
}
|
|
|
|
# Echos the full path of the boot filesystem, given the bundle directory
|
|
# 1: bundle directory
|
|
bootfs_dir() {
|
|
echo $1/bootfs
|
|
}
|