Skip to content
This repository has been archived by the owner on Jul 5, 2022. It is now read-only.

Auto Install(Beta)

雾雨 edited this page Sep 16, 2020 · 5 revisions
  • generate the following scripts and run 'chmod +x install.sh && chmod +x generate_confs.py && ./install.sh ${network_name}', replace network_name with the calico network name on your machine
  • install.sh
#!/bin/bash
declare -a FILES=( 
  "barrel.conf" "/etc/eru/"
  "eru-barrel" "/usr/bin/"
  "eru-barrel.service" "/usr/lib/systemd/system/"
  "daemon.json" "/etc/docker/"
  "docker.socket" "/lib/systemd/system/"
)

./generate_confs.py $1

if [ -d "/etc/eru" ];
then
  echo "/etc/eru exists"
else 
  echo "create /etc/eru"
  mkdir -p /etc/eru
fi

copy_file () {
  echo "copy $1 to $2"
  cp "$1" "$2"
}

echo "===copy files==="
for i in $(eval echo "{0..$((${#FILES[@]} - 1))..2}") 
do
  copy_file "${FILES[${i}]}" "${FILES[$((i + 1))]}"
done

echo "===start service==="
systemctl enable eru-barrel.service
systemctl start eru-barrel.service

echo "===barrel install success==="
  • generate_confs.py
#!/usr/bin/env python3

import sys
import os
import subprocess
from string import Template
import json
import re
from typing import List, Tuple, Any

white_spaces_regex = re.compile("\s+")

def run(args: List[str]) -> Tuple[Any, Any]:
  process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  return process.communicate()

def create_container() -> str:
  stdout, stderr = run(['docker', 'container', 'create', '--network', sys.argv[1], 'nginx'])
  if stdout == b'':
    raise Exception(
      Template('create container error cause = $cause')
        .substitute({'cause': stderr[:len(stderr) - 1].decode()})
    )
  return stdout[:len(stdout) - 1].decode()

def start_container(id: str):
  stdout, stderr = run(['docker', 'container', 'start', id])
  if stdout == b'':
    raise Exception(
      Template('start container $id failed, cause = $cause')
        .substitute({'id': id, 'cause': stderr[:len(stderr) - 1].decode()})
    )

def inspect_container_addr(id: str) -> str:
  stdout, stderr = run(['docker', 'container', 'inspect', id])
  if stdout == b'':
    raise Exception(
      Template('inspect container $id failed, cause = $cause')
        .substitute({'id': id, 'cause': stderr[:len(stderr) - 1].decode()})
    )
  result = stdout[:len(stdout) - 1].decode()
  container_infos = json.loads(result)
  if len(container_infos) != 1:
    raise Exception(
      Template('inspect container $id failed, cause = $cause')
        .substitute({'id': id, 'cause': 'less then or more then one container is inspected'})
    )
  return container_infos[0]['NetworkSettings']['Networks'][sys.argv[1]]['IPAddress']

def look_up_namespace(ip: str) -> str:
  stdout, stderr = run(['calicoctl', 'get', '--all-namespaces', 'weps'])
  if stdout == b'':
    raise Exception(
      Template('look up namespace by ip $ip failed, cause = $cause')
        .substitute({'ip': ip, 'cause': stderr[:len(stderr) - 1].decode()})
    )
  table = stdout[:len(stdout) - 1].decode().split('\n')
  if len(table) <= 1:
    return ""
  for line in table:
    values = white_spaces_regex.split(line)
    if len(values) >= 3 and values[3].startswith(ip):
      return values[0]
  return ""

def remove_container(id: str):
  stdout, stderr = run(['docker', 'container', 'rm', id, '--force'])
  if stdout == b'':
    raise Exception(
      Template('remove container $id failed, cause = $cause')
        .substitute({'id': id, 'cause': stderr[:len(stderr) - 1].decode()})
    )

def get_namespace() -> str:
  containerID = create_container()
  print("created container " + containerID)
  start_container(containerID)
  address = inspect_container_addr(containerID)
  print("container address = " + address)
  namespace = look_up_namespace(address)
  remove_container(containerID)
  return namespace

def generate_conf():
  with open("/etc/docker/daemon.json", "r") as daemon_confs:
    daemon_conf = json.loads("".join(map(lambda x: x[:len(x) - 1], daemon_confs.readlines())))
    if "cluster-store" not in daemon_conf:
      raise Exception("not found cluster-store in docker daemon config")
    if "hosts" not in daemon_conf:
      raise Exception("not found hosts in docker daemon config")
    with open("./barrel.conf", "w") as conf:
      etcd_endpoints: str = daemon_conf["cluster-store"]
      if etcd_endpoints.startswith("etcd"):
        etcd_endpoints = etcd_endpoints.replace("etcd", "http")
      conf.write("ETCD_ENDPOINTS=" + etcd_endpoints + "\n")
      hosts: List[str] = daemon_conf["hosts"]
      print("hosts = " + ",".join(hosts))
      hosts = list(filter(lambda x: x != "unix:///var/run/dockerd.sock" and x != "unix:///var/run/docker.sock", hosts))
      hosts.append("unix:///var/run/docker.sock")
      conf.write("BARREL_HOSTS="+",".join(hosts) + "\n")
      conf.write("DOCKERD_SOCKET_PATH=unix:///var/run/dockerd.sock\n")
      if "tlsverify" in daemon_conf and daemon_conf["tlsverify"] == True:
        if "tlscert" not in daemon_conf:
          raise Exception("not found hosts in docker daemon config")
        if "tlskey" not in daemon_conf:
          raise Exception("not found hosts in docker daemon config")
        conf.write("BARREL_TLS_CERT_FILE_PATH=" + daemon_conf["tlscert"] + "\n")
        conf.write("BARREL_TLS_KEY_FILE_PATH=" + daemon_conf["tlskey"] + "\n")
      namespace = get_namespace()
      print("calico namespace = " + namespace)
      if namespace != os.uname().nodename:
        conf.write("CALICO_LIBNETWORK_NAMESPACE=" + namespace + "\n")

def generate_docker_sock():
  with open("/lib/systemd/system/docker.socket", "r") as docker_socket_service:
    with open("./docker.socket", "w") as gen:
      for line in docker_socket_service.readlines():
        if line.startswith("ListenStream"):
          gen.write("ListenStream=/var/run/dockerd.sock\n")
        else:
          gen.write(line)

def generate_docker_daemon_json():
  with open("/etc/docker/daemon.json", "r") as docker_daemon_json:
    with open("./daemon.json", "w") as gen:
      obj = json.loads("".join(map(lambda x: x[:len(x) - 1], docker_daemon_json.readlines())))
      for key, value in obj.items():
        if key == "hosts":
          value = list(filter(lambda x: x != "unix:///var/run/dockerd.sock" and x != "unix:///var/run/docker.sock", value))
          value.append("unix:///var/run/dockerd.sock")
          obj[key] = value
          break
      gen.write(json.dumps(obj, indent = 2))

def backup_file(src: str, dst: str):
  stdout, stderr = run(['cp', src, dst])
  if stderr != b'':
    raise Exception(
      Template('backup docker daemon.json failed, cause = $cause')
        .substitute({'cause': stderr[:len(stderr) - 1].decode()})
    )

def backup_docker_configs():
  backup_file('/etc/docker/daemon.json', './daemon.json.backup')
  backup_file('/lib/systemd/system/docker.socket', './docker.socket.backup')

def main():
  backup_docker_configs()
  generate_conf()
  generate_docker_sock()
  generate_docker_daemon_json()
  

if __name__ == '__main__':
  sys.exit(main())
Clone this wiki locally