-
Notifications
You must be signed in to change notification settings - Fork 6
/
deploy.py
executable file
·153 lines (127 loc) · 5.88 KB
/
deploy.py
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
#!/usr/bin/python
# -------------------------------------------------------------------------- #
# Copyright 2016-2018 #
# #
# Portions copyright OpenNebula Project (OpenNebula.org), CG12 Labs #
# #
# 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. #
# -------------------------------------------------------------------------- #
import lxd_common as lc
t0 = lc.time()
from lxd_common import xml_query_list as xql
from lxd_common import xml_query_dict as xqd
from lxd_common import xml_query_item as xqi
client = lc.Client()
def create_profile(xml):
'create a container profile from OpenNebula VM template'
dicc = lc.xml_start(xml)
profile = {'config': [], 'devices': []}
# General
mapped_entries = [lc.map_ram(xqi('MEMORY', dicc)),
lc.map_cpu(xqi('CPU', dicc)),
lc.map_vcpu(xqi('VCPU', dicc)),
lc.map_xml(xml),
{'user.hostname': dicc["/VM/NAME"][0]}]
for x in mapped_entries:
profile['config'].append(x)
VM_ID = profile['VM_ID'] = dicc["/VM/ID"][0]
profile['CONTEXT_DISK_ID'] = xqi('CONTEXT/DISK_ID', dicc)
# VNC
for x in ['PASSWD', 'PORT']:
profile['VNC_' + x] = xqi('GRAPHICS/' + x, dicc)
# Security
for x in ["privileged", "nesting"]:
item = '/VM/USER_TEMPLATE/LXD_SECURITY_' + x.swapcase()
if dicc.get(item):
profile['config'].append({'security.' + x: dicc.get(item)[0]})
# NETWORK_CONFIG
NIC = xql('NIC/NIC_ID', dicc)
if NIC[0]:
NIC_BRIDGE = xqd('NIC/BRIDGE', NIC, dicc)
NIC_MAC = xqd('NIC/MAC', NIC, dicc)
NIC_TARGET = xqd('NIC/TARGET', NIC, dicc)
for iface in NIC:
i = str(iface)
name = 'eth%s' % (iface)
profile['devices'].append(lc.map_nic(name, NIC_BRIDGE[i], NIC_MAC[i], NIC_TARGET[i]))
# STORAGE_CONFIG
DS_ID = profile['DS_ID'] = dicc["/VM/HISTORY_RECORDS/HISTORY/DS_ID"][0]
DISK_TYPE = profile['DISK_TYPE'] = xql('DISK/TYPE', dicc)
DISK_CLONE = profile['DISK_CLONE'] = xql('DISK/CLONE', dicc)
DISK_SOURCE = profile['DISK_SOURCE'] = xql('DISK/SOURCE', dicc)
# extra
num_hdds = profile['num_hdds'] = len(profile['DISK_TYPE'])
profile['DISK_TARGET'] = xql('DISK/TARGET', dicc)
if num_hdds > 1:
DISK_ID = xql('DISK/DISK_ID', dicc)
for x in xrange(1, num_hdds):
source = lc.storage_sysmap(DISK_ID[x], DISK_TYPE[x], DISK_SOURCE[x], VM_ID, DS_ID, DISK_CLONE[x])
profile['devices'].append(lc.map_disk(profile['DISK_TARGET'][x], source))
return profile
def apply_profile(profile, container):
'apply config and devices to container'
# STORAGE_CONFIG
VM_ID = profile['VM_ID']
DS_ID = profile['DS_ID']
DISK_TYPE = profile['DISK_TYPE']
DISK_SOURCE = profile['DISK_SOURCE']
DISK_CLONE = profile['DISK_CLONE']
root_source = lc.storage_rootfs_mount(VM_ID, DISK_TYPE[0], DS_ID, DISK_SOURCE[0], DISK_CLONE[0])
profile['config'].append(root_source)
if profile['CONTEXT_DISK_ID']:
CONTEXT_DISK_ID = profile['CONTEXT_DISK_ID']
DS_ID = profile['DS_ID']
DS_LOCATION = '/var/lib/one/datastores/' + DS_ID + '/' + VM_ID + '/'
contextiso = lc.isoparser.parse(DS_LOCATION + 'disk.' + CONTEXT_DISK_ID)
lc.storage_context(container, contextiso)
# FIXME: duplicated block of code
for i in profile['config']:
try:
container.config.update(i)
container.save(wait=True)
except lc.LXDAPIException as lxdapie:
lc.log_function('ERROR', 'container: ' + i.keys()[0] + ': ' + str(lxdapie))
lc.sys.exit(1)
for i in profile['devices']:
try:
container.devices.update(i)
container.save(wait=True)
except lc.LXDAPIException as lxdapie:
lc.log_function('ERROR', 'container: ' + i.keys()[0] + ': ' + str(lxdapie))
lc.sys.exit(1)
# INITIALIZE_CONTAINER
profile = create_profile(lc.sys.argv[1]) # xml is passed by opennebula as argument ex. deployment.0
VM_ID = profile['VM_ID']
VM_NAME = 'one-' + VM_ID
init = {'name': VM_NAME, 'source': {'type': 'none'}}
lc.log_function('INFO', 40 * "#")
try:
container = client.containers.create(init, wait=True)
except lc.LXDAPIException as lxdapie: # probably this container already exists
container = client.containers.get(VM_NAME)
if container.status == 'Running':
lc.log_function('e', "A container with the same ID is already running")
lc.sys.exit(1)
apply_profile(profile, container)
# BOOT_CONTAINER
try:
container.start(wait=True)
except lc.LXDAPIException as lxdapie:
if container.status == 'Running':
container.stop(wait=True)
lc.container_wipe(container, profile)
lc.log_function('ERROR', 'container: ' + str(lxdapie))
lc.sys.exit(1)
lc.vnc_start(profile['VM_ID'], profile['VNC_PORT'], profile['VNC_PASSWD'])
lc.clock(t0)
print VM_NAME