vendor files

This commit is contained in:
Serguei Bezverkhi
2018-01-09 13:57:14 -05:00
parent 558bc6c02a
commit 7b24313bd6
16547 changed files with 4527373 additions and 0 deletions

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.3
arm=gcr.io/google-containers/debian-base-arm:0.3
arm64=gcr.io/google-containers/debian-base-arm64:0.3
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.3

View File

@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "peer-finder",
importpath = "k8s.io/kubernetes/test/images/pets/peer-finder",
library = ":go_default_library",
)
go_library(
name = "go_default_library",
srcs = ["peer-finder.go"],
importpath = "k8s.io/kubernetes/test/images/pets/peer-finder",
deps = ["//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,24 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
RUN clean-install wget bash dnsutils
COPY peer-finder /
EXPOSE 9376
ENTRYPOINT ["/peer-finder"]

View File

@ -0,0 +1,25 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
bin:
../../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -0,0 +1,39 @@
# Peer finder
This is a simple peer finder daemon that is useful with StatefulSet and related use cases.
All it does is watch DNS for changes in the set of endpoints that are part of the governing service
of the PetSet. It periodically looks up the SRV record of the DNS entry that corresponds to a Kubernetes
Service which enumerates the set of peers for this the specified service.
Be sure to use the `service.alpha.kubernetes.io/tolerate-unready-endpoints` on the governing service
of the StatefulSet so that all peers are listed in endpoints before any peers are started.
There are several ways to bundle it with your main application.
1. In an [init container](http://kubernetes.io/docs/user-guide/pods/init-container/),
to help your pod determine its peers when it it first started (determine the desired set of
peers from the governing service of the StatefulSet. For this use case, the `--on-start` option
can be used, but the `--on-change` option should not be used since the init container will no
longer be running after the pod is started. An example of an `--on-start` script would be to
edit a configuration file for the main app to insert the list of peers. This file needs to be
on a Volume shared between the init container and the main container.
2. In a sidecar (e.g. a second container in the same pod as the main app), in which case the `--on-change`
option can be used, but `--on-start` may not be useful without a way to guarantee the ordering
of the sidecar relative to the main app container. An example of an on-change script would be to
send an administrative command to the main container over the localhost network. (Note that signalling
is not practical since pods currently do not share a PID namespace).
3. As pid 1 of the main container, in which case both `--on-change` and `--on-start` may be used.
In this mode, the ordering of the peer-finder relative to the main app is ensured by having the peer
finder start the main app. An example script would be to modify a configuration file and send SIGHUP
to the main process.
4. Both 1 and 2.
Options 1 and 2 and 4 may be preferable since they do not require changes to the main container image.
Option 3 is useful is signalling is necessary.
The peer-finder tool is intended to help legacy applications run in containers on Kubernetes.
If possible, it may be preferable to modify an applications to poll DNS itself to determine its peer set.
Not all StatefulSets are able to be scaled. For unscalable StatefulSets, only the on-start message is needed, and
so option 1 is a good choice.

View File

@ -0,0 +1 @@
1.1

View File

@ -0,0 +1,128 @@
/*
Copyright 2014 The Kubernetes Authors.
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.
*/
// A small utility program to lookup hostnames of endpoints in a service.
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"sort"
"strings"
"time"
"k8s.io/apimachinery/pkg/util/sets"
)
const (
pollPeriod = 1 * time.Second
)
var (
onChange = flag.String("on-change", "", "Script to run on change, must accept a new line separated list of peers via stdin.")
onStart = flag.String("on-start", "", "Script to run on start, must accept a new line separated list of peers via stdin.")
svc = flag.String("service", "", "Governing service responsible for the DNS records of the domain this pod is in.")
namespace = flag.String("ns", "", "The namespace this pod is running in. If unspecified, the POD_NAMESPACE env var is used.")
domain = flag.String("domain", "cluster.local", "The Cluster Domain which is used by the Cluster.")
)
func lookup(svcName string) (sets.String, error) {
endpoints := sets.NewString()
_, srvRecords, err := net.LookupSRV("", "", svcName)
if err != nil {
return endpoints, err
}
for _, srvRecord := range srvRecords {
// The SRV records ends in a "." for the root domain
ep := fmt.Sprintf("%v", srvRecord.Target[:len(srvRecord.Target)-1])
endpoints.Insert(ep)
}
return endpoints, nil
}
func shellOut(sendStdin, script string) {
log.Printf("execing: %v with stdin: %v", script, sendStdin)
cmd := exec.Command(script)
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalf("Failed to get stdin pipe: %v", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatalf("Failed to get stdout pipe: %v", err)
}
cmd.Start()
stdin.Write([]byte(sendStdin))
stdin.Close()
out, err := ioutil.ReadAll(stdout)
if err != nil {
log.Fatalf("Failed to execute %v: %v, err: %v", script, string(out), err)
}
log.Print(string(out))
}
func main() {
flag.Parse()
ns := *namespace
if ns == "" {
ns = os.Getenv("POD_NAMESPACE")
}
if *svc == "" || ns == "" || (*onChange == "" && *onStart == "") {
log.Fatalf("Incomplete args, require -on-change and/or -on-start, -service and -ns or an env var for POD_NAMESPACE.")
}
hostname, err := os.Hostname()
if err != nil {
log.Fatalf("Failed to get hostname: %s", err)
}
svcLocalSuffix := strings.Join([]string{"svc", *domain}, ".")
myName := strings.Join([]string{hostname, *svc, ns, svcLocalSuffix}, ".")
script := *onStart
if script == "" {
script = *onChange
log.Printf("No on-start supplied, on-change %v will be applied on start.", script)
}
for newPeers, peers := sets.NewString(), sets.NewString(); script != ""; time.Sleep(pollPeriod) {
newPeers, err = lookup(*svc)
if err != nil {
log.Printf("%v", err)
continue
}
if newPeers.Equal(peers) || !newPeers.Has(myName) {
continue
}
peerList := newPeers.List()
sort.Strings(peerList)
log.Printf("Peer list updated\nwas %v\nnow %v", peers.List(), newPeers.List())
shellOut(strings.Join(peerList, "\n"), script)
peers = newPeers
script = *onChange
}
// TODO: Exit if there's no on-change?
log.Printf("Peer finder exiting")
}

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.3
arm=gcr.io/google-containers/debian-base-arm:0.3
arm64=gcr.io/google-containers/debian-base-arm64:0.3
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.3

View File

@ -0,0 +1,40 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
# TODO: get rid of bash dependency and switch to plain busybox.
# The tar in busybox also doesn't seem to understand compression.
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
# TODO: just use standard redis when there is one for 3.2.0.
RUN clean-install wget make gcc libc-dev
# See README.md
RUN wget -qO /redis-3.2.0.tar.gz http://download.redis.io/releases/redis-3.2.0.tar.gz && \
tar -xzf /redis-3.2.0.tar.gz -C /tmp/ && rm /redis-3.2.0.tar.gz
# Clean out existing deps before installation
# see https://github.com/antirez/redis/issues/722
RUN cd /tmp/redis-3.2.0 && make distclean && mkdir -p /redis && \
make install INSTALL_BIN=/redis && \
mv /tmp/redis-3.2.0/redis.conf /redis/redis.conf && \
rm -rf /tmp/redis-3.2.0
ADD on-start.sh /
COPY peer-finder /
ADD install.sh /
RUN chmod -c 755 /install.sh /on-start.sh /peer-finder
Entrypoint ["/install.sh"]

View File

@ -0,0 +1,25 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
bin:
../../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -0,0 +1,12 @@
# Redis statefulset e2e tester
The image in this directory is the init container for contrib/pets/redis but for one difference, it bakes a specific version of redis into the base image so we get deterministic test results without having to depend on a redis download server. Discussing the tradeoffs to either approach (download the version at runtime, or maintain an image per version) are outside the scope of this document.
You can execute the image locally via:
```
$ docker run -it gcr.io/google_containers/redis-install-3.2.0:e2e --cmd --install-into=/opt --work-dir=/work-dir
```
To share the installation with other containers mount the appropriate volumes as `--install-into` and `--work-dir`, where `install-into` is the directory to install redis into, and `work-dir` is the directory to install the user/admin supplied on-{start,change} hook scripts.
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/pets/redis/README.md?pixel)]()

View File

@ -0,0 +1 @@
1.1

View File

@ -0,0 +1,51 @@
#! /bin/bash
# Copyright 2016 The Kubernetes Authors.
#
# 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.
# This volume is assumed to exist and is shared with parent of the init
# container. It contains the redis installation.
INSTALL_VOLUME="/opt"
# This volume is assumed to exist and is shared with the peer-finder
# init container. It contains on-start/change configuration scripts.
WORK_DIR="/work-dir"
VERSION="3.2.0"
for i in "$@"
do
case $i in
-i=*|--install-into=*)
INSTALL_VOLUME="${i#*=}"
shift
;;
-w=*|--work-dir=*)
WORK_DIR="${i#*=}"
shift
;;
*)
# unknown option
;;
esac
done
echo installing config scripts into "${WORK_DIR}"
mkdir -p "${WORK_DIR}"
cp /on-start.sh "${WORK_DIR}"/
cp /peer-finder "${WORK_DIR}"/
echo installing redis-"${VERSION}" into "${INSTALL_VOLUME}"
mkdir -p "${INSTALL_VOLUME}"
mv /redis "${INSTALL_VOLUME}"/redis

View File

@ -0,0 +1,49 @@
#!/bin/bash
# Copyright 2016 The Kubernetes Authors.
#
# 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 -e
CFG=/opt/redis/redis.conf
HOSTNAME=$(hostname)
DATADIR="/data"
# Port on which redis listens for connections.
PORT=6379
# Ping everyone but ourself to see if there's a master. Only one pet starts at
# a time, so if we don't see a master we can assume the position is ours.
while read -ra LINE; do
if [[ "${LINE}" == *"${HOSTNAME}"* ]]; then
sed -i -e "s|^bind.*$|bind ${LINE}|" ${CFG}
elif [ "$(/opt/redis/redis-cli -h $LINE info | grep role | sed 's,\r$,,')" = "role:master" ]; then
# TODO: More restrictive regex?
sed -i -e "s|^# slaveof.*$|slaveof ${LINE} ${PORT}|" ${CFG}
fi
done
# Set the data directory for append only log and snapshot files. This should
# be a persistent volume for consistency.
sed -i -e "s|^.*dir .*$|dir ${DATADIR}|" ${CFG}
# The append only log is written for every SET operation. Without this setting,
# redis just snapshots periodically which is only safe for a cache. This will
# produce an appendonly.aof file in the configured data dir.
sed -i -e "s|^appendonly .*$|appendonly yes|" ${CFG}
# Every write triggers an fsync. Recommended default is "everysec", which
# is only safe for AP applications.
sed -i -e "s|^appendfsync .*$|appendfsync always|" ${CFG}

View File

@ -0,0 +1,4 @@
amd64=gcr.io/google-containers/debian-base-amd64:0.3
arm=gcr.io/google-containers/debian-base-arm:0.3
arm64=gcr.io/google-containers/debian-base-arm64:0.3
ppc64le=gcr.io/google-containers/debian-base-ppc64le:0.3

View File

@ -0,0 +1,33 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
# TODO: get rid of bash dependency and switch to plain busybox.
# The tar in busybox also doesn't seem to understand compression.
FROM BASEIMAGE
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
RUN clean-install wget netcat
ADD on-start.sh /
COPY peer-finder /
# See README.md
RUN wget -q -O /zookeeper-3.5.0-alpha.tar.gz http://apache.mirrors.pair.com/zookeeper/zookeeper-3.5.0-alpha/zookeeper-3.5.0-alpha.tar.gz && \
tar -xzf /zookeeper-3.5.0-alpha.tar.gz -C /tmp/ && mv /tmp/zookeeper-3.5.0-alpha /zookeeper && rm /zookeeper-3.5.0-alpha.tar.gz
ADD install.sh /
RUN chmod -c 755 /install.sh /on-start.sh /peer-finder
Entrypoint ["/install.sh"]

View File

@ -0,0 +1,25 @@
# Copyright 2016 The Kubernetes Authors.
#
# 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.
SRCS = peer-finder
ARCH ?= amd64
TARGET ?= $(CURDIR)
GOLANG_VERSION ?= latest
SRC_DIR = pets/peer-finder
export
bin:
../../image-util.sh bin $(SRCS)
.PHONY: bin

View File

@ -0,0 +1,12 @@
# Zookeeper statefulset e2e tester
The image in this directory is the init container for contrib/pets/zookeeper but for one difference, it bakes a specific version of zookeeper into the base image so we get deterministic test results without having to depend on a zookeeper download server. Discussing the tradeoffs to either approach (download the version at runtime, or maintain an image per version) are outside the scope of this document.
You can execute the image locally via:
```
$ docker run -it gcr.io/google_containers/zookeeper-install-3.5.0-alpha:e2e --cmd --install-into=/opt --work-dir=/work-dir
```
To share the installation with other containers mount the appropriate volumes as `--install-into` and `--work-dir`, where `install-into` is the directory to install zookeeper into, and `work-dir` is the directory to install the user/admin supplied on-{start,change} hook scripts.
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/pets/zookeeper/README.md?pixel)]()

View File

@ -0,0 +1 @@
1.1

View File

@ -0,0 +1,70 @@
#! /bin/bash
# Copyright 2016 The Kubernetes Authors.
#
# 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.
# This volume is assumed to exist and is shared with parent of the init
# container. It contains the zookeeper installation.
INSTALL_VOLUME="/opt"
# This volume is assumed to exist and is shared with the peer-finder
# init container. It contains on-start/change configuration scripts.
WORKDIR_VOLUME="/work-dir"
# As of April-2016 is 3.4.8 is the latest stable, but versions 3.5.0 onward
# allow dynamic reconfiguration.
VERSION="3.5.0-alpha"
for i in "$@"
do
case $i in
-i=*|--install-into=*)
INSTALL_VOLUME="${i#*=}"
shift
;;
-w=*|--work-dir=*)
WORKDIR_VOLUME="${i#*=}"
shift
;;
*)
# unknown option
;;
esac
done
echo installing config scripts into "${WORKDIR_VOLUME}"
mkdir -p "${WORKDIR_VOLUME}"
cp /on-start.sh "${WORKDIR_VOLUME}"/
cp /peer-finder "${WORKDIR_VOLUME}"/
echo installing zookeeper-"${VERSION}" into "${INSTALL_VOLUME}"
mkdir -p "${INSTALL_VOLUME}"
mv /zookeeper "${INSTALL_VOLUME}"/zookeeper
cp "${INSTALL_VOLUME}"/zookeeper/conf/zoo_sample.cfg "${INSTALL_VOLUME}"/zookeeper/conf/zoo.cfg
# TODO: Should dynamic config be tied to the version?
IFS="." read -ra RELEASE <<< "${VERSION}"
if [ $(expr "${RELEASE[1]}") -gt 4 ]; then
echo zookeeper-"${VERSION}" supports dynamic reconfiguration, enabling it
echo "standaloneEnabled=false" >> "${INSTALL_VOLUME}"/zookeeper/conf/zoo.cfg
echo "dynamicConfigFile="${INSTALL_VOLUME}"/zookeeper/conf/zoo.cfg.dynamic" >> "${INSTALL_VOLUME}"/zookeeper/conf/zoo.cfg
fi
# TODO: This is a hack, netcat is convenient to have in the zookeeper container
# I want to avoid using a custom zookeeper image just for this. So copy it.
NC=$(which nc)
if [ "${NC}" != "" ]; then
echo copying nc into "${INSTALL_VOLUME}"
cp "${NC}" "${INSTALL_VOLUME}"
fi

View File

@ -0,0 +1,106 @@
#! /bin/bash
# Copyright 2016 The Kubernetes Authors.
#
# 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 -eo pipefail
# This script configures zookeeper cluster member ship for version of zookeeper
# >= 3.5.0. It should not be used with the on-change.sh script in this example.
# As of April-2016 is 3.4.8 is the latest stable.
# Both /opt and /tmp/zookeeper are assumed to be volumes shared with the parent.
# The format of each line in the dynamic config file is:
# server.<1 based index>=<server-dns-name>:<peer port>:<election port>[:role];[<client port address>:]<client port>
# <1 based index> is the server index that matches the id in datadir/myid
# <peer port> is the port on which peers communicate to agree on updates
# <election port> is the port used for leader election
# [:role] can be set to observer, participant by default
# <client port address> is optional and defaults to 0.0.0.0
# <client port> is the port on which the server accepts client connections
CFG=/opt/zookeeper/conf/zoo.cfg.dynamic
CFG_BAK=/opt/zookeeper/conf/zoo.cfg.bak
MY_ID_FILE=/tmp/zookeeper/myid
HOSTNAME=$(hostname)
while read -ra LINE; do
PEERS=("${PEERS[@]}" $LINE)
done
# Don't add the first member as an observer
if [ ${#PEERS[@]} -eq 1 ]; then
# We need to write our index in this list of servers into MY_ID_FILE.
# Note that this may not always coincide with the hostname id.
echo 1 > "${MY_ID_FILE}"
echo "server.1=${PEERS[0]}:2888:3888;2181" > "${CFG}"
# TODO: zkServer-initialize is the safe way to handle changes to datadir
# because simply starting will create a new datadir, BUT if the user changed
# pod template they might end up with 2 datadirs and brief split brain.
exit
fi
# Every subsequent member is added as an observer and promoted to a participant
echo "" > "${CFG_BAK}"
i=0
LEADER=$HOSTNAME
for peer in "${PEERS[@]}"; do
let i=i+1
if [[ "${peer}" == *"${HOSTNAME}"* ]]; then
MY_ID=$i
MY_NAME=${peer}
echo $i > "${MY_ID_FILE}"
echo "server.${i}=${peer}:2888:3888:observer;2181" >> "${CFG_BAK}"
else
if [[ $(echo srvr | /opt/nc "${peer}" 2181 | grep Mode) = "Mode: leader" ]]; then
LEADER="${peer}"
fi
echo "server.${i}=${peer}:2888:3888:participant;2181" >> "${CFG_BAK}"
fi
done
# zookeeper won't start without myid anyway.
# This means our hostname wasn't in the peer list.
if [ ! -f "${MY_ID_FILE}" ]; then
exit 1
fi
# Once the dynamic config file is written it shouldn't be modified, so the final
# reconfigure needs to happen through the "reconfig" command.
cp ${CFG_BAK} ${CFG}
# TODO: zkServer-initialize is the safe way to handle changes to datadir
# because simply starting will create a new datadir, BUT if the user changed
# pod template they might end up with 2 datadirs and brief split brain.
/opt/zookeeper/bin/zkServer.sh start
# TODO: We shouldn't need to specify the address of the master as long as
# there's quorum. According to the docs the new server is just not allowed to
# vote, it's still allowed to propose config changes, and it knows the
# existing members of the ensemble from *its* config.
ADD_SERVER="server.$MY_ID=$MY_NAME:2888:3888:participant;0.0.0.0:2181"
/opt/zookeeper/bin/zkCli.sh reconfig -s "${LEADER}":2181 -add "${ADD_SERVER}"
# Prove that we've actually joined the running cluster
ITERATION=0
until $(echo config | /opt/nc localhost 2181 | grep "${ADD_SERVER}" > /dev/null); do
echo $ITERATION] waiting for updated config to sync back to localhost
sleep 1
let ITERATION=ITERATION+1
if [ $ITERATION -eq 20 ]; then
exit 1
fi
done
/opt/zookeeper/bin/zkServer.sh stop