1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
from base64 import b64decode
import os
from socket import gethostbyname, gethostname, gaierror
from subprocess import (
CalledProcessError,
check_call,
check_output
)
import netifaces
import time
import platform
import json
from charmhelpers.contrib.network.ip import get_address_in_network
from charmhelpers.core.hookenv import (
config,
status_set,
log,
ERROR,
application_version_set,
)
from charmhelpers.core.host import write_file
from docker_utils import (
is_container_launched,
is_container_present,
apply_config_in_container,
get_docker_image_id,
load_docker_image,
launch_docker_image,
dpkg_version,
docker_exec,
)
config = config()
def get_ip():
network = config.get("control-network")
ip = get_address_in_network(network) if network else None
if not ip:
ip = _get_default_ip()
return ip
def _get_default_ip():
if hasattr(netifaces, "gateways"):
iface = netifaces.gateways()["default"][netifaces.AF_INET][1]
else:
data = check_output("ip route | grep ^default", shell=True).split()
iface = data[data.index("dev") + 1]
return netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["addr"]
def fix_hostname():
hostname = gethostname()
try:
gethostbyname(hostname)
except gaierror:
ip = get_ip()
check_call(["sed", "-E", "-i", "-e",
("/127.0.0.1[[:blank:]]+/a \\\n" + ip + " " + hostname),
"/etc/hosts"])
def decode_cert(key):
val = config.get(key)
if not val:
return None
try:
return b64decode(val)
except Exception as e:
log("Couldn't decode certificate from config['{}']: {}".format(
key, str(e)), level=ERROR)
return None
def save_file(path, data):
if data:
fdir = os.path.dirname(path)
if not os.path.exists(fdir):
os.makedirs(fdir)
write_file(path, data, perms=0o400)
elif os.path.exists(path):
os.remove(path)
def update_services_status(name, services):
try:
output = docker_exec(name, "contrail-status")
except CalledProcessError as e:
log("Container is not ready to get contrail-status: " + str(e))
status_set("waiting", "Waiting services to run in container")
return
statuses = dict()
for line in output.splitlines()[1:]:
if len(line) == 0 or line.startswith("=="):
continue
lst = line.split()
if len(lst) < 2:
continue
srv = lst[0].split(":")[0]
statuses[srv] = (lst[1], " ".join(lst[2:]))
for srv in services:
if srv not in statuses:
status_set("waiting", srv + " is absent in the contrail-status")
return
status, desc = statuses.get(srv)
if status != "active":
workload = "waiting" if status == "initializing" else "blocked"
status_set(workload, "{} is not ready. Reason: {}"
.format(srv, desc))
return
status_set("active", "Unit is ready")
def check_run_prerequisites(name, config_name, update_config_func, services):
if is_container_launched(name):
check = True
if update_config_func:
update_config_func()
check = apply_config_in_container(name, config_name)
if check:
update_services_status(name, services)
return False
if is_container_present(name):
status_set(
"blocked",
"Container is present but is not running. Run or remove it.")
return False
image_id = get_docker_image_id(name)
if not image_id:
image_id = load_docker_image(name)
if not image_id:
status_set("waiting", "Awaiting for container resource")
return False
return True
def run_container(name, pkg_to_check):
args = []
if platform.linux_distribution()[2].strip() == "trusty":
args.append("--pid=host")
launch_docker_image(name, args)
time.sleep(5)
version = dpkg_version(name, pkg_to_check)
application_version_set(version)
status_set("waiting", "Waiting services to run in container")
def json_loads(data, default=None):
return json.loads(data) if data else default
|