diff --git a/cluster/juju/prereqs/ubuntu-juju.sh b/cluster/juju/prereqs/ubuntu-juju.sh new file mode 100644 index 00000000000..d5ffd7c8f91 --- /dev/null +++ b/cluster/juju/prereqs/ubuntu-juju.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright 2015 Google 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. + + +set -o errexit +set -o nounset +set -o pipefail + + +function check_for_ppa(){ + local repo="$1" + grep -qsw $repo /etcc/apt/sources.list /etc/apt/sources.list.d/* +} + +function package_status(){ + local pkgname=$1 + local pkgstatus + pkgstatus=$(dpkg-query -W --showformat='${Status}\n' "${pkgname}") + if [[ "${pkgstatus}" != "install ok installed" ]]; then + echo "Missing package ${pkgname}" + sudo apt-get --force-yes --yes install ${pkgname} + fi + +} + +function gather_installation_reqs(){ + if ! check_for_ppa "juju"; then + echo "... Detected missing dependencies.. running" + echo "... add-apt-repository ppa:juju/stable" + sudo add-apt-repository -y ppa:juju/stable + sudo apt-get update + fi + + package_status 'juju-quickstart' +} + diff --git a/cluster/juju/util.sh b/cluster/juju/util.sh new file mode 100755 index 00000000000..12587edc357 --- /dev/null +++ b/cluster/juju/util.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +# Copyright 2015 Google 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. + + +set -o errexit +set -o nounset +set -o pipefail + +source $KUBE_ROOT/cluster/juju/prereqs/ubuntu-juju.sh +KUBE_BUNDLE_URL='https://raw.githubusercontent.com/whitmo/bundle-kubernetes/master/bundles.yaml' +function verify-prereqs() { + gather_installation_reqs +} + +function get-password() { + echo "TODO: Assign username/password security" +} + +function kube-up() { + # If something were to happen that I'm not accounting for, do not + # punish the user by making them tear things down. In a perfect world + # quickstart should handle this situation, so be nice in the meantime + local envstatus + envstatus=$(juju status kubernetes-master --format=oneline) + + if [[ "" == "${envstatus}" ]]; then + if [[ -d "~/.juju/current-env" ]]; then + juju quickstart -i --no-browser -i $KUBE_BUNDLE_URL + else + juju quickstart --no-browser ${KUBE_BUNDLE_URL} + fi + sleep 60 + fi + # Sleep due to juju bug http://pad.lv/1432759 + sleep-status +} + + +function detect-master() { + local kubestatus + # Capturing a newline, and my awk-fu was weak - pipe through tr -d + kubestatus=$(juju status --format=oneline kubernetes-master | awk '{print $3}' | tr -d "\n") + export KUBE_MASTER_IP=${kubestatus} + export KUBE_MASTER=$KUBE_MASTER_IP:8080 + export KUBERNETES_MASTER=$KUBE_MASTER + + } + +function detect-minions(){ + # Strip out the components except for STDOUT return + # and trim out the single quotes to build an array of minions + # + # Example Output: + #- MachineId: "10" + # Stdout: '10.197.55.232 + #' + # UnitId: kubernetes/0 + # - MachineId: "11" + # Stdout: '10.202.146.124 + # ' + # UnitId: kubernetes/1 + + KUBE_MINION_IP_ADDRESSES=($(juju run --service kubernetes \ + "unit-get private-address" --format=yaml \ + | awk '/Stdout/ {gsub(/'\''/,""); print $2}')) + NUM_MINIONS=${#KUBE_MINION_IP_ADDRESSES[@]} + MINION_NAMES=$KUBE_MINION_IP_ADDRESSES +} + +function setup-logging-firewall(){ + echo "TODO: setup logging and firewall rules" +} + +function teardown-logging-firewall(){ + echo "TODO: teardown logging and firewall rules" +} + + +function sleep-status(){ + local i + local maxtime + local jujustatus + i=0 + maxtime=900 + jujustatus='' + echo "Waiting up to 15 minutes to allow the cluster to come online... wait for it..." + while [[ $i < $maxtime && $jujustatus != *"started"* ]]; do + jujustatus=$(juju status kubernetes-master --format=oneline) + sleep 30 + i+=30 + done + + # sleep because we cannot get the status back of where the minions are in the deploy phase + # thanks to a generic "started" state and our service not actually coming online until the + # minions have recieved the binary from the master distribution hub during relations + echo "Sleeping an additional minute to allow the cluster to settle" + sleep 60 +} + diff --git a/cluster/kube-env.sh b/cluster/kube-env.sh index 89be7dc8480..2d3aef9b0cc 100644 --- a/cluster/kube-env.sh +++ b/cluster/kube-env.sh @@ -18,7 +18,7 @@ # You can override the default provider by exporting the KUBERNETES_PROVIDER # variable in your bashrc # -# The valid values: 'gce', 'gke', 'aws', 'azure', 'vagrant', 'vsphere', 'libvirt-coreos' +# The valid values: 'gce', 'gke', 'aws', 'azure', 'vagrant', 'vsphere', 'libvirt-coreos', 'juju' KUBERNETES_PROVIDER=${KUBERNETES_PROVIDER:-gce} diff --git a/cluster/validate-cluster.sh b/cluster/validate-cluster.sh index ab4f5c4d2b6..9e04a2f5257 100755 --- a/cluster/validate-cluster.sh +++ b/cluster/validate-cluster.sh @@ -55,7 +55,7 @@ echo "Found ${found} nodes." cat -n "${MINIONS_FILE}" # On vSphere, use minion IPs as their names -if [[ "${KUBERNETES_PROVIDER}" == "vsphere" ]] || [[ "${KUBERNETES_PROVIDER}" == "vagrant" ]] || [[ "${KUBERNETES_PROVIDER}" == "libvirt-coreos" ]]; then +if [[ "${KUBERNETES_PROVIDER}" == "vsphere" || "${KUBERNETES_PROVIDER}" == "vagrant" || "${KUBERNETES_PROVIDER}" == "libvirt-coreos" || "${KUBERNETES_PROVIDER}" == "juju" ]] ; then MINION_NAMES=("${KUBE_MINION_IP_ADDRESSES[@]}") fi @@ -79,7 +79,7 @@ for (( i=0; i<${#MINION_NAMES[@]}; i++)); do fi name="${MINION_NAMES[$i]}" - if [ "$KUBERNETES_PROVIDER" != "vsphere" ] && [ "$KUBERNETES_PROVIDER" != "vagrant" ] && [ "$KUBERNETES_PROVIDER" != "libvirt-coreos" ]; then + if [[ "$KUBERNETES_PROVIDER" != "vsphere" && "$KUBERNETES_PROVIDER" != "vagrant" && "$KUBERNETES_PROVIDER" != "libvirt-coreos" && "$KUBERNETES_PROVIDER" != "juju" ]]; then # Grab fully qualified name name=$(grep "${MINION_NAMES[$i]}\." "${MINIONS_FILE}") fi @@ -89,7 +89,7 @@ for (( i=0; i<${#MINION_NAMES[@]}; i++)); do attempt=0 while true; do echo -n "Attempt $((attempt+1)) at checking Kubelet installation on node ${MINION_NAMES[$i]} ..." - if [ "$KUBERNETES_PROVIDER" != "libvirt-coreos" ]; then + if [[ "$KUBERNETES_PROVIDER" != "libvirt-coreos" && "$KUBERNETES_PROVIDER" != "juju" ]]; then curl_output=$(curl -s --insecure --user "${KUBE_USER}:${KUBE_PASSWORD}" \ "https://${KUBE_MASTER_IP}/api/v1beta1/proxy/minions/${name}/healthz") else