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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
16 # @author: David Blaisonneau <david.blaisonneau@orange.com>
17 # @author: Arnaud Morin <arnaud1.morin@orange.com>
20 Create Virtual Machines
23 # TODO: be sure that we are runnning as root
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
38 p = OpenSteakPrinter()
43 p.header("Check parameters")
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()))
52 conf = OpenSteakConfig(config_file=args["config"])
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"]
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"]
74 conf["subnets"]["Admin"]
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>"
84 # no specific config for linuxbridge
85 a["bridgeconfig"] = ""
87 # Update args with values from config file
94 if args["force"] is not True:
98 p.header("Initiate configuration")
103 # Create temporary folders and files
104 tempFolder = tempfile.mkdtemp(dir="/tmp")
107 for f in os.listdir("templates_foreman/"):
108 tempFiles[f] = "{0}/{1}".format(tempFolder, f)
110 OpenSteakTemplateParser("templates_foreman/{0}".format(f),
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))
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])
125 p.status(True, msg="Temporary files created:")
130 # Delete if already exists
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)
141 # TODO: check that the default image is in the list
142 # (trusty-server-cloudimg-amd64-disk1.img by default)
144 # Delete the volume if exists
146 oldVolume = volumeList[args["name"]]
149 if args["force"] is not True:
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
160 # Delete the VM if exists
162 vmStatus = domainList[args["name"]]
165 if args["force"] is not True:
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"])
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
185 # Create the configuration image file from metadata and userdata
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"]))
195 status = OpenSteakVirsh.poolRefresh()
196 if (status["stderr"]):
197 p.status(False, msg=status["stderr"])
198 p.status(True, msg=status["stdout"])
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"])
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"])
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"])
225 status = OpenSteakVirsh.domainStart(args["name"])
226 if (status["stderr"]):
227 p.status(False, msg=status["stderr"])
228 p.status(True, msg=status["stdout"])
230 p.status(True, msg="Log file is at: /var/log/libvirt/qemu/{0}-serial.log"
231 .format(args["name"]))
235 # Delete temporary dir
236 shutil.rmtree(tempFolder)