From 24dc804bab7aee9d3f70180d345f873e4c315640 Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Tue, 29 Mar 2016 11:02:43 -0700 Subject: [PATCH] move addon manatger into subdirectory --- init.sls | 241 -------------------- initd | 120 ---------- kube-addon-update.sh | 514 ------------------------------------------- kube-addons.service | 9 - kube-addons.sh | 243 -------------------- namespace.yaml | 4 - 6 files changed, 1131 deletions(-) delete mode 100644 init.sls delete mode 100644 initd delete mode 100755 kube-addon-update.sh delete mode 100644 kube-addons.service delete mode 100644 kube-addons.sh delete mode 100644 namespace.yaml diff --git a/init.sls b/init.sls deleted file mode 100644 index 465c8b0332..0000000000 --- a/init.sls +++ /dev/null @@ -1,241 +0,0 @@ -addon-dir-delete: - file.absent: - - name: /etc/kubernetes/addons - -addon-dir-create: - file.directory: - - name: /etc/kubernetes/addons - - user: root - - group: root - - mode: 0755 - - require: - - file: addon-dir-delete - -/etc/kubernetes/addons/namespace.yaml: - file.managed: - - source: salt://kube-addons/namespace.yaml - - user: root - - group: root - - file_mode: 644 - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'influxdb' %} -/etc/kubernetes/addons/cluster-monitoring/influxdb: - file.recurse: - - source: salt://kube-addons/cluster-monitoring/influxdb - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - template: jinja - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_l7_loadbalancing', '').lower() == 'glbc' %} -/etc/kubernetes/addons/cluster-loadbalancing/glbc: - file.recurse: - - source: salt://kube-addons/cluster-loadbalancing/glbc - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'google' %} -/etc/kubernetes/addons/cluster-monitoring/google: - file.recurse: - - source: salt://kube-addons/cluster-monitoring/google - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - template: jinja - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'standalone' %} -/etc/kubernetes/addons/cluster-monitoring/standalone: - file.recurse: - - source: salt://kube-addons/cluster-monitoring/standalone - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - template: jinja - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'standalone' %} -/etc/kubernetes/addons/cluster-monitoring/standalone: - file.recurse: - - source: salt://kube-addons/cluster-monitoring/standalone - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'googleinfluxdb' %} -/etc/kubernetes/addons/cluster-monitoring/googleinfluxdb: - file.recurse: - - source: salt://kube-addons/cluster-monitoring - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - exclude_pat: E@(^.+heapster-controller\.yaml$|^.+heapster-controller\.json$) - - template: jinja - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_monitoring', '').lower() == 'googleinfluxdb' %} -/etc/kubernetes/addons/cluster-monitoring/googleinfluxdb: - file.recurse: - - source: salt://kube-addons/cluster-monitoring - - include_pat: E@(^.+\.yaml$|^.+\.json$) - - exclude_pat: E@(^.+heapster-controller\.yaml$|^.+heapster-controller\.json$) - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_dns', '').lower() == 'true' %} -/etc/kubernetes/addons/dns/skydns-svc.yaml: - file.managed: - - source: salt://kube-addons/dns/skydns-svc.yaml.in - - template: jinja - - group: root - - dir_mode: 755 - - makedirs: True - -/etc/kubernetes/addons/dns/skydns-rc.yaml: - file.managed: - - source: salt://kube-addons/dns/skydns-rc.yaml.in - - template: jinja - - group: root - - dir_mode: 755 - - makedirs: True -{% endif %} - -{% if pillar.get('enable_cluster_registry', '').lower() == 'true' %} -/etc/kubernetes/addons/registry/registry-svc.yaml: - file.managed: - - source: salt://kube-addons/registry/registry-svc.yaml - - user: root - - group: root - - file_mode: 644 - - makedirs: True - -/etc/kubernetes/addons/registry/registry-rc.yaml: - file.managed: - - source: salt://kube-addons/registry/registry-rc.yaml - - user: root - - group: root - - file_mode: 644 - - makedirs: True - -/etc/kubernetes/addons/registry/registry-pv.yaml: - file.managed: - - source: salt://kube-addons/registry/registry-pv.yaml.in - - template: jinja - - user: root - - group: root - - file_mode: 644 - - makedirs: True - -/etc/kubernetes/addons/registry/registry-pvc.yaml: - file.managed: - - source: salt://kube-addons/registry/registry-pvc.yaml.in - - template: jinja - - user: root - - group: root - - file_mode: 644 - - makedirs: True -{% endif %} - -{% if pillar.get('enable_node_logging', '').lower() == 'true' - and pillar.get('logging_destination', '').lower() == 'elasticsearch' - and pillar.get('enable_cluster_logging', '').lower() == 'true' %} -/etc/kubernetes/addons/fluentd-elasticsearch: - file.recurse: - - source: salt://kube-addons/fluentd-elasticsearch - - include_pat: E@^.+\.yaml$ - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -{% if pillar.get('enable_cluster_ui', '').lower() == 'true' %} -/etc/kubernetes/addons/dashboard: - file.recurse: - - source: salt://kube-addons/dashboard - - include_pat: E@^.+\.yaml$ - - user: root - - group: root - - dir_mode: 755 - - file_mode: 644 -{% endif %} - -/etc/kubernetes/kube-addons.sh: - file.managed: - - source: salt://kube-addons/kube-addons.sh - - user: root - - group: root - - mode: 755 - -/etc/kubernetes/kube-addon-update.sh: - file.managed: - - source: salt://kube-addons/kube-addon-update.sh - - user: root - - group: root - - mode: 755 - -{% if pillar.get('is_systemd') %} - -{{ pillar.get('systemd_system_path') }}/kube-addons.service: - file.managed: - - source: salt://kube-addons/kube-addons.service - - user: root - - group: root - cmd.wait: - - name: /opt/kubernetes/helpers/services bounce kube-addons - - watch: - - file: {{ pillar.get('systemd_system_path') }}/kube-addons.service - -{% else %} - -/etc/init.d/kube-addons: - file.managed: - - source: salt://kube-addons/initd - - user: root - - group: root - - mode: 755 - -{% endif %} - -# Stop kube-addons service each time salt is executed, just in case -# there was a modification of addons. -# Actually, this should be handled by watching file changes, but -# somehow it doesn't work. -service-kube-addon-stop: - service.dead: - - name: kube-addons - -kube-addons: - service.running: - - enable: True - - require: - - service: service-kube-addon-stop - - watch: -{% if pillar.get('is_systemd') %} - - file: {{ pillar.get('systemd_system_path') }}/kube-addons.service -{% else %} - - file: /etc/init.d/kube-addons -{% endif %} -{% if pillar.get('is_systemd') %} - - provider: - - service: systemd -{%- endif %} diff --git a/initd b/initd deleted file mode 100644 index c9abf854b2..0000000000 --- a/initd +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/bash -# -### BEGIN INIT INFO -# Provides: kube-addons -# Required-Start: $local_fs $network $syslog kube-apiserver -# Required-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Kubernetes Addon Object Manager -# Description: -# Enforces installation of Kubernetes Addon Objects -### END INIT INFO - - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="Kubernetes Addon Object Manager" -NAME=kube-addons -DAEMON_LOG_FILE=/var/log/${NAME}.log -PIDFILE=/var/run/${NAME}.pid -SCRIPTNAME=/etc/init.d/${NAME} -KUBE_ADDONS_SH=/etc/kubernetes/kube-addons.sh - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.2-14) to ensure that this file is present -# and status_of_proc is working. -. /lib/lsb/init-functions - - - - -# -# Function that starts the daemon/service -# -do_start() -{ - # use setsid to make sure the new daemon has its own group (I suppose - # start-stop-daemon does create a process group, but let's stay on the - # safe side). - setsid start-stop-daemon --start --verbose --background --no-close --make-pidfile --pidfile "${PIDFILE}" --startas "${KUBE_ADDONS_SH}" > ${DAEMON_LOG_FILE} 2>&1 -} - -# -# Function that stops the daemon/service -# -do_stop() -{ - # start-stop-daemon is not used because we have to stop all children - # limitations: - # - stop does not work if the pid file is missing - # - stop does not work if the daemon process is missing (children will not - # be killed) - # This is sufficient - remaining processes will end after a while. - - local pid - pid=$(cat "${PIDFILE}" 2> /dev/null) - if [[ $? != 0 ]]; then - return 1 - fi - local pgrp - # find the process group for the service and kill entire group - # o - output format: pgpg - process group - pgrp=$(ps --no-headers --pid "${pid}" -o pgrp 2>/dev/null) - if [[ $? != 0 ]] || [[ "${pgrp}" == "" ]]; then - return 1 - fi - pgrp=$(echo -e ${pgrp}) # strip whitespaces (that's why there are no quotes around pgrp) - # negative pid is for killing entire group - kill -- -${pgrp} 2> /dev/null - if [[ $? != 0 ]]; then - return 2 - fi - rm -f "${PIDFILE}" - return -} - -case "$1" in - start) - log_daemon_msg "Starting ${DESC}" "${NAME}" - do_start - case "$?" in - 0|1) log_end_msg 0 || exit 0 ;; - 2) log_end_msg 1 || exit 1 ;; - esac - ;; - stop) - log_daemon_msg "Stopping ${DESC}" "${NAME}" - do_stop - case "$?" in - 0|1) log_end_msg 0 || exit 0 ;; - 2) log_end_msg 1 || exit 1 ;; - esac - ;; - status) - status_of_proc -p "${PIDFILE}" "${KUBE_ADDONS_SH}" "${NAME}" - ;; - - restart|force-reload) - log_daemon_msg "Restarting ${DESC}" "${NAME}" - do_stop - case "$?" in - 0|1) - do_start - case "$?" in - 0) log_end_msg 0 ;; - 1) log_end_msg 1 ;; # Old process is still running - *) log_end_msg 1 ;; # Failed to start - esac - ;; - *) - # Failed to stop - log_end_msg 1 - ;; - esac - ;; - *) - echo "Usage: ${SCRIPTNAME} {start|stop|status|restart|force-reload}" >&2 - exit 3 - ;; -esac diff --git a/kube-addon-update.sh b/kube-addon-update.sh deleted file mode 100755 index 9f2f68022e..0000000000 --- a/kube-addon-update.sh +++ /dev/null @@ -1,514 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors 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. - -# The business logic for whether a given object should be created -# was already enforced by salt, and /etc/kubernetes/addons is the -# managed result is of that. Start everything below that directory. - -# Parameters -# $1 path to add-ons - - -# LIMITATIONS -# 1. controllers are not updated unless their name is changed -# 3. Services will not be updated unless their name is changed, -# but for services we actually want updates without name change. -# 4. Json files are not handled at all. Currently addons must be -# in yaml files -# 5. exit code is probably not always correct (I haven't checked -# carefully if it works in 100% cases) -# 6. There are no unittests -# 8. Will not work if the total length of paths to addons is greater than -# bash can handle. Probably it is not a problem: ARG_MAX=2097152 on GCE. -# 9. Performance issue: yaml files are read many times in a single execution. - -# cosmetic improvements to be done -# 1. improve the log function; add timestamp, file name, etc. -# 2. logging doesn't work from files that print things out. -# 3. kubectl prints the output to stderr (the output should be captured and then -# logged) - - - -# global config -KUBECTL=${TEST_KUBECTL:-} # substitute for tests -KUBECTL=${KUBECTL:-${KUBECTL_BIN:-}} -KUBECTL=${KUBECTL:-/usr/local/bin/kubectl} -if [[ ! -x ${KUBECTL} ]]; then - echo "ERROR: kubectl command (${KUBECTL}) not found or is not executable" 1>&2 - exit 1 -fi - -# If an add-on definition is incorrect, or a definition has just disappeared -# from the local directory, the script will still keep on retrying. -# The script does not end until all retries are done, so -# one invalid manifest may block updates of other add-ons. -# Be careful how you set these parameters -NUM_TRIES=1 # will be updated based on input parameters -DELAY_AFTER_ERROR_SEC=${TEST_DELAY_AFTER_ERROR_SEC:=10} - - -# remember that you can't log from functions that print some output (because -# logs are also printed on stdout) -# $1 level -# $2 message -function log() { - # manage log levels manually here - - # add the timestamp if you find it useful - case $1 in - DB3 ) -# echo "$1: $2" - ;; - DB2 ) -# echo "$1: $2" - ;; - DBG ) -# echo "$1: $2" - ;; - INFO ) - echo "$1: $2" - ;; - WRN ) - echo "$1: $2" - ;; - ERR ) - echo "$1: $2" - ;; - * ) - echo "INVALID_LOG_LEVEL $1: $2" - ;; - esac -} - -#$1 yaml file path -function get-object-kind-from-file() { - # prints to stdout, so log cannot be used - #WARNING: only yaml is supported - cat $1 | ${PYTHON} -c ''' -try: - import pipes,sys,yaml - y = yaml.load(sys.stdin) - labels = y["metadata"]["labels"] - if ("kubernetes.io/cluster-service", "true") not in labels.iteritems(): - # all add-ons must have the label "kubernetes.io/cluster-service". - # Otherwise we are ignoring them (the update will not work anyway) - print "ERROR" - else: - print y["kind"] -except Exception, ex: - print "ERROR" - ''' -} - -# $1 yaml file path -# returns a string of the form / (we call it nsnames) -function get-object-nsname-from-file() { - # prints to stdout, so log cannot be used - #WARNING: only yaml is supported - #addons that do not specify a namespace are assumed to be in "default". - cat $1 | ${PYTHON} -c ''' -try: - import pipes,sys,yaml - y = yaml.load(sys.stdin) - labels = y["metadata"]["labels"] - if ("kubernetes.io/cluster-service", "true") not in labels.iteritems(): - # all add-ons must have the label "kubernetes.io/cluster-service". - # Otherwise we are ignoring them (the update will not work anyway) - print "ERROR" - else: - try: - print "%s/%s" % (y["metadata"]["namespace"], y["metadata"]["name"]) - except Exception, ex: - print "default/%s" % y["metadata"]["name"] -except Exception, ex: - print "ERROR" - ''' -} - -# $1 addon directory path -# $2 addon type (e.g. ReplicationController) -# echoes the string with paths to files containing addon for the given type -# works only for yaml files (!) (ignores json files) -function get-addon-paths-from-disk() { - # prints to stdout, so log cannot be used - local -r addon_dir=$1 - local -r obj_type=$2 - local kind - local file_path - for file_path in $(find ${addon_dir} -name \*.yaml); do - kind=$(get-object-kind-from-file ${file_path}) - # WARNING: assumption that the topmost indentation is zero (I'm not sure yaml allows for topmost indentation) - if [[ "${kind}" == "${obj_type}" ]]; then - echo ${file_path} - fi - done -} - -# waits for all subprocesses -# returns 0 if all of them were successful and 1 otherwise -function wait-for-jobs() { - local rv=0 - local pid - for pid in $(jobs -p); do - wait ${pid} - if [[ $? -ne 0 ]]; then - rv=1; - log ERR "error in pid ${pid}" - fi - log DB2 "pid ${pid} completed, current error code: ${rv}" - done - return ${rv} -} - - -function run-until-success() { - local -r command=$1 - local tries=$2 - local -r delay=$3 - local -r command_name=$1 - while [ ${tries} -gt 0 ]; do - log DBG "executing: '$command'" - # let's give the command as an argument to bash -c, so that we can use - # && and || inside the command itself - /bin/bash -c "${command}" && \ - log DB3 "== Successfully executed ${command_name} at $(date -Is) ==" && \ - return 0 - let tries=tries-1 - log INFO "== Failed to execute ${command_name} at $(date -Is). ${tries} tries remaining. ==" - sleep ${delay} - done - return 1 -} - -# $1 object type -# returns a list of / pairs (nsnames) -function get-addon-nsnames-from-server() { - local -r obj_type=$1 - "${KUBECTL}" get "${obj_type}" --all-namespaces -o go-template="{{range.items}}{{.metadata.namespace}}/{{.metadata.name}} {{end}}" --api-version=v1 -l kubernetes.io/cluster-service=true -} - -# returns the characters after the last separator (including) -# If the separator is empty or if it doesn't appear in the string, -# an empty string is printed -# $1 input string -# $2 separator (must be single character, or empty) -function get-suffix() { - # prints to stdout, so log cannot be used - local -r input_string=$1 - local -r separator=$2 - local suffix - - if [[ "${separator}" == "" ]]; then - echo "" - return - fi - - if [[ "${input_string}" == *"${separator}"* ]]; then - suffix=$(echo "${input_string}" | rev | cut -d "${separator}" -f1 | rev) - echo "${separator}${suffix}" - else - echo "" - fi -} - -# returns the characters up to the last '-' (without it) -# $1 input string -# $2 separator -function get-basename() { - # prints to stdout, so log cannot be used - local -r input_string=$1 - local -r separator=$2 - local suffix - suffix="$(get-suffix ${input_string} ${separator})" - # this will strip the suffix (if matches) - echo ${input_string%$suffix} -} - -function stop-object() { - local -r obj_type=$1 - local -r namespace=$2 - local -r obj_name=$3 - log INFO "Stopping ${obj_type} ${namespace}/${obj_name}" - - run-until-success "${KUBECTL} stop --namespace=${namespace} ${obj_type} ${obj_name}" ${NUM_TRIES} ${DELAY_AFTER_ERROR_SEC} -} - -function create-object() { - local -r obj_type=$1 - local -r file_path=$2 - - local nsname_from_file - nsname_from_file=$(get-object-nsname-from-file ${file_path}) - if [[ "${nsname_from_file}" == "ERROR" ]]; then - log INFO "Cannot read object name from ${file_path}. Ignoring" - return 1 - fi - IFS='/' read namespace obj_name <<< "${nsname_from_file}" - - log INFO "Creating new ${obj_type} from file ${file_path} in namespace ${namespace}, name: ${obj_name}" - # this will keep on failing if the ${file_path} disappeared in the meantime. - # Do not use too many retries. - run-until-success "${KUBECTL} create --namespace=${namespace} -f ${file_path}" ${NUM_TRIES} ${DELAY_AFTER_ERROR_SEC} -} - -function update-object() { - local -r obj_type=$1 - local -r namespace=$2 - local -r obj_name=$3 - local -r file_path=$4 - log INFO "updating the ${obj_type} ${namespace}/${obj_name} with the new definition ${file_path}" - stop-object ${obj_type} ${namespace} ${obj_name} - create-object ${obj_type} ${file_path} -} - -# deletes the objects from the server -# $1 object type -# $2 a list of object nsnames -function stop-objects() { - local -r obj_type=$1 - local -r obj_nsnames=$2 - local namespace - local obj_name - for nsname in ${obj_nsnames}; do - IFS='/' read namespace obj_name <<< "${nsname}" - stop-object ${obj_type} ${namespace} ${obj_name} & - done -} - -# creates objects from the given files -# $1 object type -# $2 a list of paths to definition files -function create-objects() { - local -r obj_type=$1 - local -r file_paths=$2 - local file_path - for file_path in ${file_paths}; do - # Remember that the file may have disappear by now - # But we don't want to check it here because - # such race condition may always happen after - # we check it. Let's have the race - # condition happen a bit more often so that - # we see that our tests pass anyway. - create-object ${obj_type} ${file_path} & - done -} - -# updates objects -# $1 object type -# $2 a list of update specifications -# each update specification is a ';' separated pair: ; -function update-objects() { - local -r obj_type=$1 # ignored - local -r update_spec=$2 - local objdesc - local nsname - local obj_name - local namespace - - for objdesc in ${update_spec}; do - IFS=';' read nsname file_path <<< "${objdesc}" - IFS='/' read namespace obj_name <<< "${nsname}" - - update-object ${obj_type} ${namespace} ${obj_name} ${file_path} & - done -} - -# Global variables set by function match-objects. -nsnames_for_delete="" # a list of object nsnames to be deleted -for_update="" # a list of pairs ; for objects that should be updated -nsnames_for_ignore="" # a list of object nsnames that will be ignored -new_files="" # a list of file paths that weren't matched by any existing objects (these objects must be created now) - - -# $1 path to files with objects -# $2 object type in the API (ReplicationController or Service) -# $3 name separator (single character or empty) -function match-objects() { - local -r addon_dir=$1 - local -r obj_type=$2 - local -r separator=$3 - - # output variables (globals) - nsnames_for_delete="" - for_update="" - nsnames_for_ignore="" - new_files="" - - addon_nsnames_on_server=$(get-addon-nsnames-from-server "${obj_type}") - # if the api server is unavailable then abandon the update for this cycle - if [[ $? -ne 0 ]]; then - log ERR "unable to query ${obj_type} - exiting" - exit 1 - fi - - addon_paths_in_files=$(get-addon-paths-from-disk "${addon_dir}" "${obj_type}") - - log DB2 "addon_nsnames_on_server=${addon_nsnames_on_server}" - log DB2 "addon_paths_in_files=${addon_paths_in_files}" - - local matched_files="" - - local basensname_on_server="" - local nsname_on_server="" - local suffix_on_server="" - local nsname_from_file="" - local suffix_from_file="" - local found=0 - local addon_path="" - - # objects that were moved between namespaces will have different nsname - # because the namespace is included. So they will be treated - # like different objects and not updated but deleted and created again - # (in the current version update is also delete+create, so it does not matter) - for nsname_on_server in ${addon_nsnames_on_server}; do - basensname_on_server=$(get-basename ${nsname_on_server} ${separator}) - suffix_on_server="$(get-suffix ${nsname_on_server} ${separator})" - - log DB3 "Found existing addon ${nsname_on_server}, basename=${basensname_on_server}" - - # check if the addon is present in the directory and decide - # what to do with it - # this is not optimal because we're reading the files over and over - # again. But for small number of addons it doesn't matter so much. - found=0 - for addon_path in ${addon_paths_in_files}; do - nsname_from_file=$(get-object-nsname-from-file ${addon_path}) - if [[ "${nsname_from_file}" == "ERROR" ]]; then - log INFO "Cannot read object name from ${addon_path}. Ignoring" - continue - else - log DB2 "Found object name '${nsname_from_file}' in file ${addon_path}" - fi - suffix_from_file="$(get-suffix ${nsname_from_file} ${separator})" - - log DB3 "matching: ${basensname_on_server}${suffix_from_file} == ${nsname_from_file}" - if [[ "${basensname_on_server}${suffix_from_file}" == "${nsname_from_file}" ]]; then - log DB3 "matched existing ${obj_type} ${nsname_on_server} to file ${addon_path}; suffix_on_server=${suffix_on_server}, suffix_from_file=${suffix_from_file}" - found=1 - matched_files="${matched_files} ${addon_path}" - if [[ "${suffix_on_server}" == "${suffix_from_file}" ]]; then - nsnames_for_ignore="${nsnames_for_ignore} ${nsname_from_file}" - else - for_update="${for_update} ${nsname_on_server};${addon_path}" - fi - break - fi - done - if [[ ${found} -eq 0 ]]; then - log DB2 "No definition file found for replication controller ${nsname_on_server}. Scheduling for deletion" - nsnames_for_delete="${nsnames_for_delete} ${nsname_on_server}" - fi - done - - log DB3 "matched_files=${matched_files}" - - - # note that if the addon file is invalid (or got removed after listing files - # but before we managed to match it) it will not be matched to any - # of the existing objects. So we will treat it as a new file - # and try to create its object. - for addon_path in ${addon_paths_in_files}; do - echo ${matched_files} | grep "${addon_path}" >/dev/null - if [[ $? -ne 0 ]]; then - new_files="${new_files} ${addon_path}" - fi - done -} - - - -function reconcile-objects() { - local -r addon_path=$1 - local -r obj_type=$2 - local -r separator=$3 # name separator - match-objects ${addon_path} ${obj_type} ${separator} - - log DBG "${obj_type}: nsnames_for_delete=${nsnames_for_delete}" - log DBG "${obj_type}: for_update=${for_update}" - log DBG "${obj_type}: nsnames_for_ignore=${nsnames_for_ignore}" - log DBG "${obj_type}: new_files=${new_files}" - - stop-objects "${obj_type}" "${nsnames_for_delete}" - # wait for jobs below is a protection against changing the basename - # of a replication controllerm without changing the selector. - # If we don't wait, the new rc may be created before the old one is deleted - # In such case the old one will wait for all its pods to be gone, but the pods - # are created by the new replication controller. - # passing --cascade=false could solve the problem, but we want - # all orphan pods to be deleted. - wait-for-jobs - stopResult=$? - - create-objects "${obj_type}" "${new_files}" - update-objects "${obj_type}" "${for_update}" - - local nsname - for nsname in ${nsnames_for_ignore}; do - log DB2 "The ${obj_type} ${nsname} is already up to date" - done - - wait-for-jobs - createUpdateResult=$? - - if [[ ${stopResult} -eq 0 ]] && [[ ${createUpdateResult} -eq 0 ]]; then - return 0 - else - return 1 - fi -} - -function update-addons() { - local -r addon_path=$1 - # be careful, reconcile-objects uses global variables - reconcile-objects ${addon_path} ReplicationController "-" & - - # We don't expect names to be versioned for the following kinds, so - # we match the entire name, ignoring version suffix. - # That's why we pass an empty string as the version separator. - # If the description differs on disk, the object should be recreated. - # This is not implemented in this version. - reconcile-objects ${addon_path} Deployment "" & - reconcile-objects ${addon_path} Service "" & - reconcile-objects ${addon_path} PersistentVolume "" & - reconcile-objects ${addon_path} PersistentVolumeClaim "" & - - wait-for-jobs - if [[ $? -eq 0 ]]; then - log INFO "== Kubernetes addon update completed successfully at $(date -Is) ==" - else - log WRN "== Kubernetes addon update completed with errors at $(date -Is) ==" - fi -} - -# input parameters: -# $1 input directory -# $2 retry period in seconds - the script will retry api-server errors for approximately -# this amound of time (it is not very precise), at interval equal $DELAY_AFTER_ERROR_SEC. -# - -if [[ $# -ne 2 ]]; then - echo "Illegal number of parameters. Usage $0 addon-dir [retry-period]" 1>&2 - exit 1 -fi - -NUM_TRIES=$(($2 / ${DELAY_AFTER_ERROR_SEC})) -if [[ ${NUM_TRIES} -le 0 ]]; then - NUM_TRIES=1 -fi - -addon_path=$1 -update-addons ${addon_path} diff --git a/kube-addons.service b/kube-addons.service deleted file mode 100644 index 293ca10ba7..0000000000 --- a/kube-addons.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Kubernetes Addon Object Manager -Documentation=https://github.com/kubernetes/kubernetes - -[Service] -ExecStart=/etc/kubernetes/kube-addons.sh - -[Install] -WantedBy=multi-user.target diff --git a/kube-addons.sh b/kube-addons.sh deleted file mode 100644 index 19fafb6d2c..0000000000 --- a/kube-addons.sh +++ /dev/null @@ -1,243 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors 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. - -# The business logic for whether a given object should be created -# was already enforced by salt, and /etc/kubernetes/addons is the -# managed result is of that. Start everything below that directory. -KUBECTL=${KUBECTL_BIN:-/usr/local/bin/kubectl} - -ADDON_CHECK_INTERVAL_SEC=${TEST_ADDON_CHECK_INTERVAL_SEC:-600} - -SYSTEM_NAMESPACE=kube-system -token_dir=${TOKEN_DIR:-/srv/kubernetes} -trusty_master=${TRUSTY_MASTER:-false} - -function ensure_python() { - if ! python --version > /dev/null 2>&1; then - echo "No python on the machine, will use a python image" - local -r PYTHON_IMAGE=python:2.7-slim-pyyaml - export PYTHON="docker run --interactive --rm --net=none ${PYTHON_IMAGE} python" - else - export PYTHON=python - fi -} - -function create-kubeconfig-secret() { - local -r token=$1 - local -r username=$2 - local -r server=$3 - local -r safe_username=$(tr -s ':_' '--' <<< "${username}") - - # Make a kubeconfig file with the token. - if [[ ! -z "${CA_CERT:-}" ]]; then - # If the CA cert is available, put it into the secret rather than using - # insecure-skip-tls-verify. - read -r -d '' kubeconfig </dev/null - rc=$? - if [[ "$rc" == 124 ]]; then - restart_docker=true - elif [[ "$rc" != 0 ]]; then - success=false - fi - done - if [[ "$success" == "true" ]]; then break; fi - if [[ "$restart_docker" == "true" ]]; then service docker restart; fi - sleep 15 - done -} - -# The business logic for whether a given object should be created -# was already enforced by salt, and /etc/kubernetes/addons is the -# managed result is of that. Start everything below that directory. -echo "== Kubernetes addon manager started at $(date -Is) with ADDON_CHECK_INTERVAL_SEC=${ADDON_CHECK_INTERVAL_SEC} ==" - -# Load any images that we may need. This is not needed for trusty master and -# the way it restarts docker daemon does not work for trusty. -if [[ "${trusty_master}" == "false" ]]; then - load-docker-images /srv/salt/kube-addons-images -fi - -ensure_python - -# Load the kube-env, which has all the environment variables we care -# about, in a flat yaml format. -kube_env_yaml="/var/cache/kubernetes-install/kube_env.yaml" -if [ ! -e "${kubelet_kubeconfig_file}" ]; then - eval $(${PYTHON} -c ''' -import pipes,sys,yaml - -for k,v in yaml.load(sys.stdin).iteritems(): - print("readonly {var}={value}".format(var = k, value = pipes.quote(str(v)))) -''' < "${kube_env_yaml}") -fi - - -# Create the namespace that will be used to host the cluster-level add-ons. -start_addon /etc/kubernetes/addons/namespace.yaml 100 10 "" & - -# Wait for the default service account to be created in the kube-system namespace. -token_found="" -while [ -z "${token_found}" ]; do - sleep .5 - token_found=$(${KUBECTL} get --namespace="${SYSTEM_NAMESPACE}" serviceaccount default -o go-template="{{with index .secrets 0}}{{.name}}{{end}}" || true) -done - -echo "== default service account in the ${SYSTEM_NAMESPACE} namespace has token ${token_found} ==" - -# Generate secrets for "internal service accounts". -# TODO(etune): move to a completely yaml/object based -# workflow so that service accounts can be created -# at the same time as the services that use them. -# NOTE: needs to run as root to read this file. -# Read each line in the csv file of tokens. -# Expect errors when the script is started again. -# NOTE: secrets are created asynchronously, in background. -while read line; do - # Split each line into the token and username. - IFS=',' read -a parts <<< "${line}" - token=${parts[0]} - username=${parts[1]} - # DNS is special, since it's necessary for cluster bootstrapping. - if [[ "${username}" == "system:dns" ]] && [[ ! -z "${KUBERNETES_MASTER_NAME:-}" ]]; then - create-kubeconfig-secret "${token}" "${username}" "https://${KUBERNETES_MASTER_NAME}" - else - # Set the server to https://kubernetes. Pods/components that - # do not have DNS available will have to override the server. - create-kubeconfig-secret "${token}" "${username}" "https://kubernetes.default" - fi -done < "${token_dir}/known_tokens.csv" - -# Create admission_control objects if defined before any other addon services. If the limits -# are defined in a namespace other than default, we should still create the limits for the -# default namespace. -for obj in $(find /etc/kubernetes/admission-controls \( -name \*.yaml -o -name \*.json \)); do - start_addon "${obj}" 100 10 default & - echo "++ obj ${obj} is created ++" -done - -# Check if the configuration has changed recently - in case the user -# created/updated/deleted the files on the master. -while true; do - start_sec=$(date +"%s") - #kube-addon-update.sh must be deployed in the same directory as this file - `dirname $0`/kube-addon-update.sh /etc/kubernetes/addons ${ADDON_CHECK_INTERVAL_SEC} - end_sec=$(date +"%s") - len_sec=$((${end_sec}-${start_sec})) - # subtract the time passed from the sleep time - if [[ ${len_sec} -lt ${ADDON_CHECK_INTERVAL_SEC} ]]; then - sleep_time=$((${ADDON_CHECK_INTERVAL_SEC}-${len_sec})) - sleep ${sleep_time} - fi -done diff --git a/namespace.yaml b/namespace.yaml deleted file mode 100644 index 986f4b4822..0000000000 --- a/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: kube-system