From 7d60cf26b2e6980d32e1518b17fe1ae1210113b1 Mon Sep 17 00:00:00 2001 From: Kuralamudhan Ramakrishnan Date: Fri, 26 Jul 2019 12:44:04 -0700 Subject: [PATCH] adding inital packages for bootstrap cluster Change-Id: Ie8020c6669f709a90608bedf5146e1216bc01070 --- deploy/metal3/scripts/metal3.sh | 162 ++++++++++++ env/01_install_package.sh | 107 ++++++++ env/02_configure.sh | 147 +++++++++++ env/03_launch_prereq.sh | 139 ++++++++++ env/lib/common.sh | 44 +++ env/lib/logging.sh | 10 + .../bootloader-env/01_bootloader_package_req.sh | 294 +++++++++++++++++++++ .../02_clean_bootloader_package_req.sh | 144 ++++++++++ 8 files changed, 1047 insertions(+) create mode 100755 deploy/metal3/scripts/metal3.sh mode change 100644 => 100755 env/01_install_package.sh mode change 100644 => 100755 env/02_configure.sh mode change 100644 => 100755 env/03_launch_prereq.sh mode change 100644 => 100755 env/lib/common.sh mode change 100644 => 100755 env/lib/logging.sh create mode 100755 env/ubuntu/bootloader-env/01_bootloader_package_req.sh create mode 100755 env/ubuntu/bootloader-env/02_clean_bootloader_package_req.sh diff --git a/deploy/metal3/scripts/metal3.sh b/deploy/metal3/scripts/metal3.sh new file mode 100755 index 0000000..b5ba520 --- /dev/null +++ b/deploy/metal3/scripts/metal3.sh @@ -0,0 +1,162 @@ +#!/bin/bash +set -ex + +LIBDIR="$(dirname "$(dirname "$(dirname "$PWD")")")" + +eval "$(go env)" + +BM_OPERATOR="${BM_OPERATOR:-https://github.com/metal3-io/baremetal-operator.git}" + +source $LIBDIR/env/lib/common.sh + +function get_default_inteface_ipaddress() { + local _ip=$1 + local _default_interface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route) + local _ipv4address=$(ip addr show dev $_default_interface | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }') + eval $_ip="'$_ipv4address'" +} + +create_ssh_key() { + #ssh key for compute node to communicate back to bootstrap server + mkdir -p $BUILD_DIR/ssh_key + ssh-keygen -C "compute.icn.akraino.lfedge.org" -f $BUILD_DIR/ssh_key/id_rsa + cat $BUILD_DIR/ssh_key/id_rsa.pub >> $HOME/.ssh/authorized_keys +} + +set_compute_key() { +_SSH_LOCAL_KEY=$(cat $BUILD_DIR/ssh_key/id_rsa) +cat << EOF +write_files: +- path: /opt/ssh_id_rsa + owner: root:root + permissions: '0600' + content: | + $_SSH_LOCAL_KEY +EOF +} + +provision_compute_node() { + IMAGE_URL=http://172.22.0.1/images/${BM_IMAGE} + IMAGE_CHECKSUM=http://172.22.0.1/images/${BM_IMAGE}.md5sum + + if [ ! -d $GOPATH/src/github.com/metal3-io/baremetal-operator ]; then + go get github.com/metal3-io/baremetal-operator + fi + + go run $GOPATH/src/github.com/metal3-io/baremetal-operator/cmd/make-bm-worker/main.go \ + -address "ipmi://$COMPUTE_IPMI_ADDRESS" \ + -user "$COMPUTE_IPMI_USER" \ + -password "$COMPUTE_IPMI_PASSWORD" \ + "$COMPUTE_NODE_NAME" > $COMPUTE_NODE_NAME-bm-node.yaml + + printf " image:" >> $COMPUTE_NODE_NAME-bm-node.yaml + printf "\n url: ""%s" "$IMAGE_URL" >> $COMPUTE_NODE_NAME-bm-node.yaml + printf "\n checksum: ""%s" "$IMAGE_CHECKSUM" >> $COMPUTE_NODE_NAME-bm-node.yaml + printf "\n userData:" >> $COMPUTE_NODE_NAME-bm-node.yaml + printf "\n name: ""%s" "$COMPUTE_NODE_NAME""-user-data" >> $COMPUTE_NODE_NAME-bm-node.yaml + printf "\n namespace: metal3\n" >> $COMPUTE_NODE_NAME-bm-node.yaml + kubectl apply -f $COMPUTE_NODE_NAME-bm-node.yaml +} + +deprovision_compute_node() { + kubectl patch baremetalhost $COMPUTE_NODE_NAME -n metal3 --type merge \ + -p '{"spec":{"image":{"url":"","checksum":""}}}' +} + +set_compute_ssh_config() { +get_default_inteface_ipaddress default_addr +cat << EOF +- path: /root/.ssh/config + owner: root:root + permissions: '0600' + content: | + Host bootstrapmachine $default_addr + HostName $default_addr + IdentityFile /opt/ssh_id_rsa + User $USER +- path: /etc/apt/sources.list + owner: root:root + permissions: '0665' + content: | + deb [trusted=yes] ssh://$USER@$default_addr:$LOCAL_APT_REPO ./ +EOF +} + +create_userdata() { + printf "#cloud-config\n" > userdata.yaml + if [ -n "$COMPUTE_NODE_PASSWORD" ]; then + printf "password: ""%s" "$COMPUTE_NODE_PASSWORD" >> userdata.yaml + printf "\nchpasswd: {expire: False}\n" >> userdata.yaml + printf "ssh_pwauth: True\n" >> userdata.yaml + fi + + if [ -n "$COMPUTE_NODE_FQDN" ]; then + printf "fqdn: ""%s" "$COMPUTE_NODE_FQDN" >> userdata.yaml + printf "\n" >> userdata.yaml + fi + + printf "ssh_authorized_keys:\n - " >> userdata.yaml + + if [ -f $HOME/.ssh/id_rsa.pub ]; then + yes y | ssh-keygen -t rsa -N "" -f $HOME/.ssh/id_rsa + fi + + cat $HOME/.ssh/id_rsa.pub >> userdata.yaml + printf "\n" >> userdata.yaml +} + +apply_userdata_credential() { + cat < ./$COMPUTE_NODE_NAME-user-data.yaml +apiVersion: v1 +data: + userData: $(base64 -w 0 userdata.yaml) +kind: Secret +metadata: + name: $COMPUTE_NODE_NAME-user-data + namespace: metal3 +type: Opaque +EOF + kubectl apply -n metal3 -f $COMPUTE_NODE_NAME-user-data.yaml +} + +launch_baremetal_operator() { + if [ ! -d $GOPATH/src/github.com/metal3-io/baremetal-operator ]; then + go get github.com/metal3-io/baremetal-operator + fi + + pushd $GOPATH/src/github.com/metal3-io/baremetal-operator + make deploy + popd + +} + +if [ "$1" == "launch" ]; then + launch_baremetal_operator + exit 0 +fi + +if [ "$1" == "deprovision" ]; then + deprovision_compute_node + exit 0 +fi + +if [ "$1" == "provision" ]; then + create_userdata + apply_userdata_credential + provision_compute_node + exit 0 +fi + + +echo "Usage: metal3.sh" +echo "launch - Launch the metal3 operator" +echo "provision - provision baremetal node as specified in common.sh" +echo "deprovision - deprovision baremetal node as specified in common.sh" +exit 1 + +#Following code is tested for the offline mode +#Will be intergrated for the offline mode for ICNi v.0.1.0 beta +#create_ssh_key +#create_userdata +#set_compute_key +#set_compute_ssh_config diff --git a/env/01_install_package.sh b/env/01_install_package.sh old mode 100644 new mode 100755 index 3e369c3..b38cce9 --- a/env/01_install_package.sh +++ b/env/01_install_package.sh @@ -1,4 +1,111 @@ #!/usr/bin/env bash set -ex +lib/common.sh +lib/logging.sh +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +function install_essential_packages() { + apt-get update + apt-get -y install \ + crudini \ + curl \ + dnsmasq \ + figlet \ + golang \ + nmap \ + patch \ + psmisc \ + python-pip \ + python-requests \ + python-setuptools \ + vim \ + wget +} + +function install_ironic_packages() { + apt-get update + apt-get -y install \ + jq \ + nodejs \ + python-ironicclient \ + python-ironic-inspector-client \ + python-lxml \ + python-netaddr \ + python-openstackclient \ + unzip \ + genisoimage + + if [ "$1" == "offline" ]; then + pip install --no-index + --find-links=file:$PIP_CACHE_DIR locat yq + return + fi + + pip install \ + lolcat \ + yq +} + +function install_docker_packages() { + apt-get remove docker \ + docker-engine \ + docker.io \ + containerd \ + runc + apt-get update + apt-get -y install \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common + if [ "$1" != "offline" ]; then + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + apt-get update + fi + apt-get -y install docker-ce=18.06.0~ce~3-0~ubuntu +} + +function install_podman_packages() { + if [ "$1" != "offline" ]; then + add-apt-repository -y ppa:projectatomic/ppa + apt-get update + fi + apt-get -y install podman +} + +function install_kubernetes_packages() { + if [ "$1" != "offline" ]; then + curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - + bash -c 'cat </etc/apt/sources.list.d/kubernetes.list +deb https://apt.kubernetes.io/ kubernetes-xenial main +EOF' + apt-get update + fi + apt-get install -y kubelet=1.15.0-00 kubeadm=1.15.0-00 kubectl=1.15.0-00 + apt-mark hold kubelet kubeadm kubectl +} + +install() { + install_essential_packages + install_ironic_packages $1 + install_docker_packages $1 + install_podman_packages $1 + install_kubernetes_packages $1 +} + +if ["$1" == "-o"]; then + install offline + exit 0 +fi + +install diff --git a/env/02_configure.sh b/env/02_configure.sh old mode 100644 new mode 100755 index c1ddb47..016f202 --- a/env/02_configure.sh +++ b/env/02_configure.sh @@ -1,2 +1,149 @@ #!/usr/bin/env bash set -xe + +source lib/logging.sh +source lib/common.sh + +if [[ $EUID -ne 0 ]]; then + echo "confgiure script must be run as root" + exit 1 +fi + +function check_inteface_ip() { + local interface=$1 + local ipaddr=$2 + + if [ ! $(ip addr show dev $interface) ]; then + exit 1 + fi + + local ipv4address=$(ip addr show dev $interface | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }') + if [ "$ipv4address" != "$ipaddr" ]; then + exit 1 + fi +} + +function configure_kubelet() { + swapoff -a + #Todo addition kubelet configuration +} + +function configure_kubeadm() { + #Todo error handing + if [ "$1" == "offline" ]; then + for images in kube-apiserver kube-controller-manager kube-scheduler kube-proxy; do + docker load --input $CONTAINER_IMAGES_DIR/$images.tar; + done + + docker load --input $CONTAINER_IMAGES_DIR/pause.tar + docker load --input $CONTAINER_IMAGES_DIR/etcd.tar + docker load --input $CONTAINER_IMAGES_DIR/coredns.tar + return + fi + kubeadm config images pull --kubernetes-version=$KUBE_VERSION +} + +function configure_ironic_interfaces() { + #Todo later to change the CNI networking for podman networking + # Add firewall rules to ensure the IPA ramdisk can reach httpd, Ironic and the Inspector API on the host + if [ "$IRONIC_PROVISIONING_INTERFACE" ]; then + check_inteface_ip $IRONIC_PROVISIONING_INTERFACE $IRONIC_PROVISIONING_INTERFACE_IP + else + exit 1 + + fi + + if [ "$IRONIC_IPMI_INTERFACE" ]; then + check_inteface_ip $IRONIC_IPMI_INTERFACE $IRONIC_IPMI_INTERFACE_IP + else + exit 1 + fi + + for port in 80 5050 6385 ; do + if ! sudo iptables -C INPUT -i $IRONIC_PROVISIONING_INTERFACE -p tcp -m tcp --dport $port -j ACCEPT > /dev/null 2>&1; then + sudo iptables -I INPUT -i $IRONIC_PROVISIONING_INTERFACE -p tcp -m tcp --dport $port -j ACCEPT + fi + done + + # Allow ipmi to the bmc processes + if ! sudo iptables -C INPUT -i $IRONIC_IPMI_INTERFACE -p udp -m udp --dport 6230:6235 -j ACCEPT 2>/dev/null ; then + sudo iptables -I INPUT -i $IRONIC_IPMI_INTERFACE -p udp -m udp --dport 6230:6235 -j ACCEPT + fi + + #Allow access to dhcp and tftp server for pxeboot + for port in 67 69 ; do + if ! sudo iptables -C INPUT -i $IRONIC_PROVISIONING_INTERFACE -p udp --dport $port -j ACCEPT 2>/dev/null ; then + sudo iptables -I INPUT -i $IRONIC_PROVISIONING_INTERFACE -p udp --dport $port -j ACCEPT + fi + done +} + +function configure_ironic_offline() { + if [ ! -d $CONTAINER_IMAGES_DIR ] && [ ! -d $BUILD_DIR ]; then + exit 1 + fi + + for image in ironic-inspector-image ironic-image podman-pause \ + baremetal-operator socat; do + if [ ! -f "$CONTAINER_IMAGES_DIR/$image" ]; then + exit 1 + fi + done + + if [ ! -f "$BUILD_DIR/ironic-python-agent.initramfs"] && [ ! -f \ + "$BUILD_DIR/ironic-python-agent.kernel" ] && [ ! -f + "$BUILD_DIR/$BM_IMAGE" ]; then + exit 1 + fi + + podman load --input $CONTAINER_IMAGES_DIR/ironic-inspector-image.tar + podman load --input $CONTAINER_IMAGES_DIR/ironic-image.tar + podman load --input $CONTAINER_IMAGES_DIR/podman-pause.tar + + docker load --input $CONTAINER_IMAGES_DIR/baremetal-operator.tar + docker load --input $CONTAINER_IMAGES_DIR/socat.tar + + mkdir -p "$IRONIC_DATA_DIR/html/images" + + cp $BUILD_DIR/ironic-python-agent.initramfs $IRONIC_DATA_DIR/html/images/ + cp $BUILD_DIR/ironic-python-agent.kernel $IRONIC_DATA_DIR/html/images/ + cp $BUILD_DIR/$BM_IMAGE $IRONIC_DATA_DIR/html/images/ + md5sum $BUILD_DIR/$BM_IMAGE | awk '{print $1}' > $BUILD_DIR/${BM_IMAGE}.md5sum +} + +function configure_ironic() { + if [ "$1" == "offline" ]; then + configure_ironic_offline + return + fi + + podman pull $IRONIC_IMAGE + podman pull $IRONIC_INSPECTOR_IMAGE + + mkdir -p "$IRONIC_DATA_DIR/html/images" + pushd $IRONIC_DATA_DIR/html/images + + if [ ! -f ironic-python-agent.initramfs ]; then + curl --insecure --compressed -L https://images.rdoproject.org/master/rdo_trunk/current-tripleo-rdo/ironic-python-agent.tar | tar -xf - + fi + + if [[ "$BM_IMAGE_URL" && "$BM_IMAGE" ]]; then + curl -o ${BM_IMAGE} --insecure --compressed -O -L ${BM_IMAGE_URL} + md5sum ${BM_IMAGE} | awk '{print $1}' > ${BM_IMAGE}.md5sum + fi + popd +} + +function configure() { + configure_kubeadm $1 + configure_kubelet + configure_ironic_interfaces + configure_ironic $1 +} + +if [ "$1" == "-o" ]; then + configure offline + exit 0 +fi + +configure diff --git a/env/03_launch_prereq.sh b/env/03_launch_prereq.sh old mode 100644 new mode 100755 index d2577bb..544ae0a --- a/env/03_launch_prereq.sh +++ b/env/03_launch_prereq.sh @@ -1,2 +1,141 @@ #!/bin/bash set -xe + +source lib/logging.sh +source lib/common.sh + +if [[ $EUID -ne 0 ]]; then + echo "confgiure script must be run as root" + exit 1 +fi + +function get_default_inteface_ipaddress() { + local _ip=$1 + local _default_interface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route) + local _ipv4address=$(ip addr show dev $_default_interface | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }') + eval $_ip="'$_ipv4address'" +} + + + +function check_cni_network() { + #since bootstrap cluster is a single node cluster, + #podman and bootstap cluster have same network configuration to avoid the cni network conf conflicts + if [ ! -d "/etc/cni/net.d" ]; then + mkdir -p "/etc/cni/net.d" + fi + + if [ ! -f "/etc/cni/net.d/87-podman-bridge.conflist" ]; then + if [ "$1" == "offline" ]; then + cp $BUILD_DIR/87-podman-bridge.conflist /etc/cni/net.d/ + return + fi + + if !(wget $PODMAN_CNI_CONFLIST -P /etc/cni/net.d/); then + exit 1 + fi + fi +} + +function create_k8s_regular_user() { + if [ ! -d "$HOME/.kube" ]; then + mkdir -p $HOME/.kube + fi + + if [ ! -f /etc/kubernetes/admin.conf]; then + exit 1 + fi + + cp -rf /etc/kubernetes/admin.conf $HOME/.kube/config + chown $(id -u):$(id -g) $HOME/.kube/config +} + +function check_k8s_node_status(){ + echo 'checking bootstrap cluster single node status' + node_status="False" + + for i in {1..5} + do + check_node=$(kubectl get node -o \ + jsonpath='{.items[0].status.conditions[?(@.reason == "KubeletReady")].status}') + if [ $check_node != "" ]; then + node_status=${check_node} + fi + + if [ $node_status == "True" ]; then + break + fi + + sleep 3 + done + + if [ $node_status != "True" ]; then + echo "bootstrap cluster single node status is not ready" + exit 1 + fi +} + +function install_podman() { + # set password for mariadb + mariadb_password=$(echo $(date;hostname)|sha256sum |cut -c-20) + + # Create pod + podman pod create -n ironic-pod + + # Start dnsmasq, http, mariadb, and ironic containers using same image + podman run -d --net host --privileged --name dnsmasq --pod ironic-pod \ + -v $IRONIC_DATA_DIR:/shared --entrypoint /bin/rundnsmasq ${IRONIC_IMAGE} + + podman run -d --net host --privileged --name httpd --pod ironic-pod \ + -v $IRONIC_DATA_DIR:/shared --entrypoint /bin/runhttpd ${IRONIC_IMAGE} + + podman run -d --net host --privileged --name mariadb --pod ironic-pod \ + -v $IRONIC_DATA_DIR:/shared --entrypoint /bin/runmariadb \ + --env MARIADB_PASSWORD=$mariadb_password ${IRONIC_IMAGE} + + podman run -d --net host --privileged --name ironic --pod ironic-pod \ + --env MARIADB_PASSWORD=$mariadb_password \ + -v $IRONIC_DATA_DIR:/shared ${IRONIC_IMAGE} + + # Start Ironic Inspector + podman run -d --net host --privileged --name ironic-inspector \ + --pod ironic-pod "${IRONIC_INSPECTOR_IMAGE}" +} + +function remove_k8s_noschedule_taint() { + #Bootstrap cluster is a single node + nodename=$(kubectl get node -o jsonpath='{.items[0].metadata.name}') + if !(kubectl taint node $nodename node-role.kubernetes.io/master:NoSchedule-); then + exit 1 + fi +} + +function install_k8s_single_node() { + get_default_inteface_ipaddress apiserver_advertise_addr + kubeadm_init="kubeadm init --kubernetes-version=$KUBE_VERSION \ + --pod-network-cidr=$POD_NETWORK_CIDR \ + --apiserver-advertise-address=$apiserver_advertise_addr" + if !(${kubeadm_init}); then + exit 1 + fi +} + +function install() { + #install_kubernetes + install_k8s_single_node + check_cni_network $1 + create_k8s_regular_user + check_k8s_node_status + remove_k8s_noschedule_taint + + #install_podman + #Todo - error handling mechanism + install_podman +} + +if [ "$1" == "-o" ]; then + install offline + exit 0 +fi + +install diff --git a/env/lib/common.sh b/env/lib/common.sh old mode 100644 new mode 100755 index e69de29..0d589a5 --- a/env/lib/common.sh +++ b/env/lib/common.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +#supported OS version +UBUNTU_BIONIC=${UBUNTU_BIONIC:-Ubuntu 18.04.2 LTS} + +#offline mode variable +DOWNLOAD_PATH=${DOWNLOAD_PATH:-/opt/icn/} +LOCAL_APT_REPO=${LOCAL_APT_REPO:-$DOWNLOAD_PATH/apt} +PIP_CACHE_DIR=${PIP_CACHE_DIR:-$DOWNLOAD_PATH/pip-cache-dir} +BUILD_DIR=${BUILD_DIR:-$DOWNLOAD_PATH/build-dir} +CONTAINER_IMAGES_DIR=${CONTAINER_IMAGES_DIR:-$OFFLINE_DOWNLOAD_PATH/docker-dir} + +#set variables +#Todo include over all variables here +KUBE_VERSION=${KUBE_VERSION:-"v1.15.0"} +POD_NETWORK_CIDR=${POD_NETWORK_CIDR:-"10.244.0.0/16"} +PODMAN_CNI_CONFLIST=${PODMAN_CNI_CONFLIST:-"https://raw.githubusercontent.com/containers/libpod/v1.4.4/cni/87-podman-bridge.conflist"} + +#Bootstrap K8s cluster + + +#Ironic variables +IRONIC_IMAGE=${IRONIC_IMAGE:-"quay.io/metal3-io/ironic:master"} +IRONIC_INSPECTOR_IMAGE=${IRONIC_INSPECTOR_IMAGE:-"quay.io/metal3-io/ironic-inspector"} +IRONIC_BAREMETAL_IMAGE=${IRONIC_BAREMETAL_IMAGE:-"quay.io/metal3-io/baremetal-operator:master"} +IRONIC_BAREMETAL_SOCAT_IMAGE=${IRONIC_BAREMETAL_SOCAT_IMAGE:-"alpine/socat:latest"} + +IRONIC_DATA_DIR=${IRONIC_DATA_DIR:-"/opt/ironic"} +#IRONIC_PROVISIONING_INTERFACE is required to be provisioning, don't change it +IRONIC_PROVISIONING_INTERFACE=${IRONIC_PROVISIONING_INTERFACE:-"provisioning"} +IRONIC_IPMI_INTERFACE=${IRONIC_IPMI_INTERFACE:-"eno1"} +IRONIC_PROVISIONING_INTERFACE_IP=${IRONIC_PROVISIONING_INTERFACE_IP:-"172.22.0.1"} +IRONIC_IPMI_INTERFACE_IP=${IRONIC_IPMI_INTERFACE_IP:-"172.31.1.9"} +BM_IMAGE_URL=${BM_IMAGE_URL:-"https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img"} +BM_IMAGE=${BM_IMAGE:-"bionic-server-cloudimg-amd64.img"} + +#Todo change into nodes list in json pattern +COMPUTE_NODE_NAME=${COMPUTE_NODE_NAME:-"el-100-node-01"} +COMPUTE_IPMI_ADDRESS=${COMPUTE_IPMI_ADDRESS:-"172.31.1.17"} +COMPUTE_IPMI_USER=${COMPUTE_IPMI_USER:-"ryeleswa"} +COMPUTE_IPMI_PASSWORD=${COMPUTE_IPMI_PASSWORD:-"changeme1"} +COMPUTE_NODE_FQDN=${COMPUTE_NODE_FQDN:-"node01.akraino.org"} +#COMPUTE_NODE_HOSTNAME=${COMPUTE_NODE_HOSTNAME:-"node01"} +COMPUTE_NODE_PASSWORD=${COMPUTE_NODE_PASSWORD:-"mypasswd"} diff --git a/env/lib/logging.sh b/env/lib/logging.sh old mode 100644 new mode 100755 index e69de29..40a29f8 --- a/env/lib/logging.sh +++ b/env/lib/logging.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Log output automatically +# referred from metal3 project +LOGDIR="$(dirname $0)/logs" +if [ ! -d "$LOGDIR" ]; then + mkdir -p "$LOGDIR" +fi +LOGFILE="$LOGDIR/$(basename $0 .sh)-$(date +%F-%H%M%S).log" +exec 1> >( tee "${LOGFILE}" ) 2>&1 diff --git a/env/ubuntu/bootloader-env/01_bootloader_package_req.sh b/env/ubuntu/bootloader-env/01_bootloader_package_req.sh new file mode 100755 index 0000000..793fce1 --- /dev/null +++ b/env/ubuntu/bootloader-env/01_bootloader_package_req.sh @@ -0,0 +1,294 @@ +#!/usr/bin/env bash +set -ex +shopt -s extglob + +source $(dirname $PWD)/../lib/common.sh +source $(dirname $PWD)/../lib/logging.sh + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if [[ $(lsb_release -d | cut -f2) != $UBUNTU_BIONIC ]]; then + echo "Currently Ubuntu 18.04.2 LTS is only supported" + exit 1 +fi + +function download_essential_packages() { + apt-get update + for package in crudini curl dnsmasq figlet golang nmap patch psmisc \ + python-pip python-requests python-setuptools vim wget; do + apt-get -d install $package -y + done +} + +function build_baremetal_operator_images() { + if [ ! -d "$BUILD_DIR/baremetal-operator"]; then + return + fi + + pushd $BUILD_DIR/baremetal-operator + docker build -t $IRONIC_BAREMETAL_IMAGE . -f build/Dockerfile + docker save --output \ + $CONTAINER_IMAGES_DIR/baremetal-operator.tar $IRONIC_BAREMETAL_IMAGE + popd + + docker pull $IRONIC_BAREMETAL_SOCAT_IMAGE + docker save --output $CONTAINER_IMAGES_DIR/socat.tar $IRONIC_BAREMETAL_SOCAT_IMAGE +} + +function build_ironic_images() { + for images in ironic-image ironic-inspector-image; do + if [ -d "$BUILD_DIR/$images" ]; then + pushd $BUILD_DIR/$images + podman build -t $images . + popd + fi + done + + if podman images -q localhost/ironic-inspector-image ; then + podman tag localhost/ironic-inspector-image $IRONIC_INSPECTOR_IMAGE + podman save --output \ + $CONTAINER_IMAGES_DIR/ironic-inspector-image.tar \ + $IRONIC_INSPECTOR_IMAGE + fi + + if podman images -q localhost/ironic-image ; then + podman tag localhost/ironic-inspector-image $IRONIC_IMAGE + podman save --output $CONTAINER_IMAGES_DIR/ironic-image.tar \ + $IRONIC_IMAGE + fi + + podman pull k8s.gcr.io/pause:3.1 + podman save --output $CONTAINER_IMAGES_DIR/podman-pause.tar \ + k8s.gcr.io/pause:3.1 + + #build_baremetal_operator_images +} + + +function download_container_images() { + check_docker + pushd $CONTAINER_IMAGES_DIR + #docker images for Kubernetes + for images in kube-apiserver kube-controller-manager kube-scheduler kube-proxy; do + docker pull k8s.gcr.io/$images:v1.15.0; + docker save --output $images.tar k8s.gcr.io/$images; + done + + docker pull k8s.gcr.io/pause:3.1 + docker save --output pause.tar k8s.gcr.io/pause + + docker pull k8s.gcr.io/etcd:3.3.10 + docker save --output etcd.tar k8s.gcr.io/etcd + + docker pull k8s.gcr.io/coredns:1.3.1 + docker save --output coredns.tar k8s.gcr.io/coredns + + #podman images for Ironic + check_podman + build_ironic_images + #podman pull $IRONIC_IMAGE + #podman save --output ironic.tar $IRONIC_IMAGE + #podman pull $IRONIC_INSPECTOR_IMAGE + #podman save --output ironic-inspector.tar $IRONIC_INSPECTOR_IMAGE + popd +} + +function download_build_packages() { + check_curl + pushd $BUILD_DIR + if [ ! -f ironic-python-agent.initramfs ]; then + curl --insecure --compressed \ + -L https://images.rdoproject.org/master/rdo_trunk/current-tripleo-rdo/ironic-python-agent.tar | tar -xf - + fi + + if [[ "$BM_IMAGE_URL" && "$BM_IMAGE" ]]; then + curl -o ${BM_IMAGE} --insecure --compressed -O -L ${BM_IMAGE_URL} + md5sum ${BM_IMAGE} | awk '{print $1}' > ${BM_IMAGE}.md5sum + fi + + if [ ! -f 87-podman-bridge.conflist ]; then + curl --insecure --compressed -O -L $PODMAN_CNI_CONFLIST + fi + + if [ ! -d baremetal-operator ]; then + git clone https://github.com/metal3-io/baremetal-operator.git + pushd ./baremetal-operator + git checkout -b icn_baremetal_operator 11ea02ab5cab8b3ab14972ae7c0e70206bba00b5 + popd + fi + + if [ ! -d ironic-inspector-image ]; then + git clone https://github.com/metal3-io/ironic-inspector-image.git + pushd ./ironic-inspector-image + git checkout -b icn_ironic_inspector_image 25431bd5b7fc87c6f3cfb8b0431fe66b86bbab0e + popd + fi + + if [ ! -d ironic-image ]; then + git clone https://github.com/metal3-io/ironic-image.git + pushd ./ironic-image + git checkout -b icn_ironic_image 329eb4542f0d8d0f0e9cf0d7e550e33b07efe7fb + popd + fi +} + +function check_pip() { + if ! which pip ; then + apt-get install python-pip -y + fi +} + +function check_curl() { + if ! which curl ; then + apt-get install curl -y + fi +} + +function check_apt_tools() { + if ! which add-apt-repository ; then + apt-get install software-properties-common -y + fi +} + +function download_ironic_packages() { + for package in jq nodejs python-ironicclient \ + python-ironic-inspector-client python-lxml python-netaddr \ + python-openstackclient unzip genisoimage; do + apt-get -d install $package -y + done + + check_pip + pip download lolcat yq -d $PIP_CACHE_DIR +} + +function check_docker() { + if which docker ; then + return + fi + + apt-get remove -y docker \ + docker-engine \ + docker.io \ + containerd \ + runc \ + docker-ce + apt-get update + for package in apt-transport-https ca-certificates gnupg-agent \ + software-properties-common; do + apt-get -d install $package -y + done + + check_curl + check_apt_tools + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + apt-get update + apt-get install docker-ce=18.06.0~ce~3-0~ubuntu -y +} + +function check_podman() { + if which podman; then + return + fi + + add-apt-repository -y ppa:projectatomic/ppa + apt-get update + apt-get install podman -y +} + +function download_docker_packages() { + apt-get remove -y docker \ + docker-engine \ + docker.io \ + containerd \ + runc \ + docker-ce + apt-get update + for package in apt-transport-https ca-certificates gnupg-agent \ + software-properties-common; do + apt-get -d install $package -y + done + + check_curl + check_apt_tools + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + apt-get update + apt-get -d install docker-ce=18.06.0~ce~3-0~ubuntu -y +} + +function download_podman_packages() { + apt-get update + add-apt-repository -y ppa:projectatomic/ppa + apt-get -d install podman -y +} + +function download_kubernetes_packages() { + curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - + bash -c 'cat </etc/apt/sources.list.d/kubernetes.list +deb https://apt.kubernetes.io/ kubernetes-xenial main +EOF' + apt-get update + apt-get install -d kubelet=1.15.0-00 kubeadm=1.15.0-00 kubectl=1.15.0-00 -y +} + +function clean_apt_cache() { + pushd /var/cache/apt/archives + + if [ $(ls -1q . | wc -l ) -ge 3 ]; then + $(rm !("lock"|"partial")) + fi + popd + +} + +function mv_apt_cache() { + pushd /var/cache/apt/archives + + if [ $(ls -1q . | wc -l ) -gt 2 ]; then + $(mv !("lock"|"partial") $LOCAL_APT_REPO) + fi + popd +} + +function check_dir() { + if [ ! -d $1 ]; then + mkdir -p $1 + fi +} + +function clean_dir() { + pushd $1 + + if [ $(ls -1q . | wc -l ) -ne 0 ]; then + $(rm -r ./*) + fi + popd +} + +clean_apt_cache +check_dir $LOCAL_APT_REPO +clean_dir $LOCAL_APT_REPO +check_dir $PIP_CACHE_DIR +clean_dir $PIP_CACHE_DIR +check_dir $BUILD_DIR +clean_dir $BUILD_DIR +check_dir $CONTAINER_IMAGES_DIR +clean_dir $CONTAINER_IMAGES_DIR +download_essential_packages +download_ironic_packages +download_docker_packages +download_podman_packages +download_kubernetes_packages +download_build_packages +download_container_images +mv_apt_cache diff --git a/env/ubuntu/bootloader-env/02_clean_bootloader_package_req.sh b/env/ubuntu/bootloader-env/02_clean_bootloader_package_req.sh new file mode 100755 index 0000000..4154b6f --- /dev/null +++ b/env/ubuntu/bootloader-env/02_clean_bootloader_package_req.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +set -ex + +source $(dirname $PWD)/../lib/common.sh +source $(dirname $PWD)/../lib/logging.sh + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if [[ $(lsb_release -d | cut -f2) != $UBUNTU_BIONIC ]]; then + echo "Currently Ubuntu 18.04.2 LTS is only supported" + exit 1 +fi + +function clean_essential_packages() { + apt-get update + for package in crudini curl dnsmasq figlet golang nmap patch psmisc \ + python-pip python-requests python-setuptools vim wget; do + apt-get remove $package -y + done + + apt-get autoremove -y + rm -rf /etc/apt/sources.list.d/* +} + +function check_prerequisite() { + if !(which pip); then + apt-get install python-pip -y + fi + + if !(which curl); then + apt-get install curl -y + fi + + if !(which add-apt-repository); then + apt-get install software-properties-common -y + fi +} + +function clean_ironic_packages() { + for package in jq nodejs python-ironicclient \ + python-ironic-inspector-client python-lxml python-netaddr \ + python-openstackclient unzip genisoimage; do + apt-get remove $package -y + done +} + +function clean_docker_packages() { + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" + apt-get update + apt-get remove docker-ce -y + for package in apt-transport-https ca-certificates gnupg-agent \ + software-properties-common; do + apt-get remove $package -y + done + + apt-get remove -y docker \ + docker-engine \ + docker.io \ + containerd \ + runc \ + docker-ce + + apt-get update +} + +function clean_podman_packages() { + apt-get update + add-apt-repository -y ppa:projectatomic/ppa + apt-get remove podman -y +} + +function clean_kubernetes_packages() { + #Just to make sure kubernetes packages are removed during the download + curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - + bash -c 'cat </etc/apt/sources.list.d/kubernetes.list +deb https://apt.kubernetes.io/ kubernetes-xenial main +EOF' + apt-get update + apt-get remove kubelet kubeadm kubectl -y +} + +function clean_apt_cache() { + shopt -s extglob + pushd /var/cache/apt/archives + + if [ $(ls -1q . | wc -l ) -ge 3 ]; then + $(rm !("lock"|"partial")) + fi + popd + +} + +function mv_apt_cache() { + shopt -s extglob + pushd /var/cache/apt/archives + + if [ $(ls -1q . | wc -l ) -gt 2 ]; then + $(mv !("lock"|"partial") $LOCAL_APT_REPO) + fi + popd +} + +function check_dir() { + if [ ! -d $1 ]; then + mkdir -p $1 + fi +} + +function clean_dir() { + shopt -s extglob + pushd $1 + + if [ $(ls -1q . | wc -l ) -ne 0 ]; then + $(rm -r ./*) + fi + popd +} + +check_prerequisite +clean_apt_cache +check_dir $LOCAL_APT_REPO +clean_dir $LOCAL_APT_REPO +check_dir $PIP_CACHE_DIR +clean_dir $PIP_CACHE_DIR +check_dir $BUILD_DIR +clean_dir $BUILD_DIR +check_dir $CONTAINER_IMAGES_DIR +clean_dir $CONTAINER_IMAGES_DIR +clean_kubernetes_packages +clean_podman_packages +clean_docker_packages +clean_ironic_packages +clean_essential_packages +rm -rf $LOCAL_APT_REPO +rm -rf $PIP_CACHE_DIR +rm -rf $BUILD_DIR +rm -rf $CONTAINER_IMAGES_DIR -- 2.16.6