Merge "Remove Compass from genesis."
[genesis.git] / opensteak / tools / create_foreman.py
1 #!/usr/bin/python3
2 # -*- coding: utf-8 -*-
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain
5 # a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14 #
15 # Authors:
16 # @author: David Blaisonneau <david.blaisonneau@orange.com>
17 # @author: Arnaud Morin <arnaud1.morin@orange.com>
18
19 """
20 Create Virtual Machines
21 """
22
23 # TODO: be sure that we are runnning as root
24
25 from opensteak.conf import OpenSteakConfig
26 from opensteak.printer import OpenSteakPrinter
27 # from opensteak.argparser import OpenSteakArgParser
28 from opensteak.templateparser import OpenSteakTemplateParser
29 from opensteak.virsh import OpenSteakVirsh
30 from pprint import pprint as pp
31 # from ipaddress import IPv4Address
32 import argparse
33 import tempfile
34 import shutil
35 import os
36 # import sys
37
38 p = OpenSteakPrinter()
39
40 #
41 # Check for params
42 #
43 p.header("Check parameters")
44 args = {}
45
46 # Update args with values from CLI
47 parser = argparse.ArgumentParser(description='This script will create a foreman VM.', usage='%(prog)s [options]')
48 parser.add_argument('-c', '--config', help='YAML config file to use (default is config/infra.yaml).', default='config/infra.yaml')
49 args.update(vars(parser.parse_args()))
50
51 # Open config file
52 conf = OpenSteakConfig(config_file=args["config"])
53 # pp(conf.dump())
54
55 a = {}
56 a["name"] = "foreman"
57 a["ip"] = conf["foreman"]["ip"]
58 a["netmask"] = conf["subnets"]["Admin"]["data"]["mask"]
59 a["netmaskshort"] = sum([bin(int(x)).count('1')
60                             for x in conf["subnets"]["Admin"]
61                                                     ["data"]["mask"]
62                             .split('.')])
63 a["gateway"] = conf["subnets"]["Admin"]["data"]["gateway"]
64 a["network"] = conf["subnets"]["Admin"]["data"]["network"]
65 a["admin"] = conf["foreman"]["admin"]
66 a["password"] = conf["foreman"]["password"]
67 a["cpu"] = conf["foreman"]["cpu"]
68 a["ram"] = conf["foreman"]["ram"]
69 a["iso"] = conf["foreman"]["iso"]
70 a["disksize"] = conf["foreman"]["disksize"]
71 a["force"] = conf["foreman"]["force"]
72 a["dhcprange"] = "{0} {1}".format(conf["subnets"]["Admin"]
73                                                     ["data"]["from"],
74                                      conf["subnets"]["Admin"]
75                                                     ["data"]["to"])
76 a["domain"] = conf["domains"]
77 reverse_octets = str(conf["foreman"]["ip"]).split('.')[-2::-1]
78 a["reversedns"] = '.'.join(reverse_octets) + '.in-addr.arpa'
79 a["dns"] = conf["foreman"]["dns"]
80 a["bridge"] = conf["foreman"]["bridge"]
81 if conf["foreman"]["bridge_type"] == "openvswitch":
82     a["bridgeconfig"] = "<virtualport type='openvswitch'></virtualport>"
83 else:
84     # no specific config for linuxbridge
85     a["bridgeconfig"] = ""
86
87 # Update args with values from config file
88 args.update(a)
89 del a
90
91 p.list_id(args)
92
93 # Ask confirmation
94 if args["force"] is not True:
95     p.ask_validation()
96
97 # Create the VM
98 p.header("Initiate configuration")
99
100 ###
101 # Work on templates
102 ###
103 # Create temporary folders and files
104 tempFolder = tempfile.mkdtemp(dir="/tmp")
105 tempFiles = {}
106
107 for f in os.listdir("templates_foreman/"):
108     tempFiles[f] = "{0}/{1}".format(tempFolder, f)
109     try:
110         OpenSteakTemplateParser("templates_foreman/{0}".format(f),
111                                 tempFiles[f], args)
112     except Exception as err:
113         p.status(False, msg=("Something went wrong when trying to create "
114                              "the file {0} from the template "
115                              "templates_foreman/{1}").format(tempFiles[f], f),
116                  failed="{0}".format(err))
117
118 ###
119 # Work on files
120 ###
121 for f in os.listdir("files_foreman/"):
122     tempFiles[f] = "{0}/{1}".format(tempFolder, f)
123     shutil.copyfile("files_foreman/{0}".format(f), tempFiles[f])
124
125 p.status(True, msg="Temporary files created:")
126 p.list_id(tempFiles)
127
128
129 ###
130 # Delete if already exists
131 ###
132
133 # Get all volumes and VM
134 p.header("Virsh calls")
135 OpenSteakVirsh = OpenSteakVirsh()
136 volumeList = OpenSteakVirsh.volumeList()
137 domainList = OpenSteakVirsh.domainList()
138 # p.list_id(volumeList)
139 # p.list_id(domainList)
140
141 # TODO: check that the default image is in the list
142 # (trusty-server-cloudimg-amd64-disk1.img by default)
143
144 # Delete the volume if exists
145 try:
146     oldVolume = volumeList[args["name"]]
147
148     # Ask confirmation
149     if args["force"] is not True:
150         p.ask_validation()
151
152     status = OpenSteakVirsh.volumeDelete(volumeList[args["name"]])
153     if (status["stderr"]):
154         p.status(False, msg=status["stderr"])
155     p.status(True, msg=status["stdout"])
156 except KeyError as err:
157     # no old volume, do nothing
158     pass
159
160 # Delete the VM if exists
161 try:
162     vmStatus = domainList[args["name"]]
163
164     # Ask confirmation
165     if args["force"] is not True:
166         p.ask_validation()
167
168     # Destroy (stop)
169     if vmStatus == "running":
170         status = OpenSteakVirsh.domainDestroy(args["name"])
171         if (status["stderr"]):
172             p.status(False, msg=status["stderr"])
173         p.status(True, msg=status["stdout"])
174
175     # Undefine (delete)
176     status = OpenSteakVirsh.domainUndefine(args["name"])
177     if (status["stderr"]):
178         p.status(False, msg=status["stderr"])
179     p.status(True, msg=status["stdout"])
180 except KeyError as err:
181     # no old VM defined, do nothing
182     pass
183
184 ###
185 # Create the configuration image file from metadata and userdata
186 ###
187 status = OpenSteakVirsh.generateConfiguration(args["name"], tempFiles)
188 if (status["stderr"]):
189     p.status(False, msg=status["stderr"])
190 p.status(True, msg=("Configuration generated successfully in "
191                     "/var/lib/libvirt/images/{0}-configuration.iso")
192          .format(args["name"]))
193
194 # Refresh the pool
195 status = OpenSteakVirsh.poolRefresh()
196 if (status["stderr"]):
197     p.status(False, msg=status["stderr"])
198 p.status(True, msg=status["stdout"])
199
200 ###
201 # Create the new VM
202 ###
203 # Create the volume from a clone
204 status = OpenSteakVirsh.volumeClone(args["iso"], args["name"])
205 if (status["stderr"]):
206     p.status(False, msg=status["stderr"])
207 p.status(True, msg=status["stdout"])
208
209 # Resize the volume
210 status = OpenSteakVirsh.volumeResize(args["name"], args["disksize"])
211 if (status["stderr"]):
212     p.status(False, msg=status["stderr"])
213 p.status(True, msg=status["stdout"])
214
215 # Create the VM
216 status = OpenSteakVirsh.domainDefine(tempFiles["kvm-config"])
217 if (status["stderr"]):
218     p.status(False, msg=status["stderr"])
219 p.status(True, msg=status["stdout"])
220
221
222 ###
223 # Start the VM
224 ###
225 status = OpenSteakVirsh.domainStart(args["name"])
226 if (status["stderr"]):
227     p.status(False, msg=status["stderr"])
228 p.status(True, msg=status["stdout"])
229
230 p.status(True, msg="Log file is at: /var/log/libvirt/qemu/{0}-serial.log"
231                    .format(args["name"]))
232
233 p.header("fini")
234
235 # Delete temporary dir
236 shutil.rmtree(tempFolder)