Fix return codes once again
[nitsi.git] / src / nitsi / machine.py
CommitLineData
a6a7fe20
JS
1#!/usr/bin/python3
2
a6a7fe20 3import libvirt
1ed8ca9f 4import logging
6632e137
JS
5import os
6import xml.etree.ElementTree as ET
7
8from .disk import disk
9from .serial_connection import serial_connection
1ed8ca9f
JS
10
11logger = logging.getLogger("nitsi.machine")
a6a7fe20
JS
12
13class machine():
7005787e 14 def __init__(self, libvirt_con, vm_xml_file, snapshot_xml_file, image, root_uid, username, password):
1ed8ca9f 15 self.log = logger.getChild(os.path.basename(vm_xml_file))
7005787e 16 self.con = libvirt_con
a6a7fe20
JS
17 try:
18 with open(vm_xml_file) as fobj:
19 self.vm_xml = fobj.read()
20 except FileNotFoundError as error:
341e7373
JS
21 logger.error("No such file: {}".format(vm_xml_file))
22
23 try:
24 self.name = self.get_name()
25 except BaseException as error:
26 logger.error("Could not get name of the machine: {}".format(vm_xml_file))
27 raise error
28
29 self.log = logger.getChild(self.name)
30 self.log.debug("Name of this machine is {}".format(self.name))
a6a7fe20
JS
31
32 try:
33 with open(snapshot_xml_file) as fobj:
34 self.snapshot_xml = fobj.read()
35 except FileNotFoundError as error:
36 self.log.error("No such file: {}".format(snapshot_xml_file))
37
38 self.image = image
39
40 if not os.path.isfile(self.image):
41 self.log.error("No such file: {}".format(self.image))
42
43 self.root_uid = root_uid
44 self.disk = disk(image)
45
46 self.username = username
47 self.password = password
48
49 def define(self):
8b744f18 50 self.dom = self.con.defineXML(self.vm_xml)
a6a7fe20
JS
51 if self.dom == None:
52 self.log.error("Could not define VM")
53 raise BaseException
54
55 def start(self):
56 if self.dom.create() < 0:
57 self.log.error("Could not start VM")
58 raise BaseException
59
60 def shutdown(self):
61 if self.is_running():
62 if self.dom.shutdown() < 0:
63 self.log.error("Could not shutdown VM")
64 raise BaseException
65 else:
66 self.log.error("Domain is not running")
67
68 def undefine(self):
69 self.dom.undefine()
70
71 def create_snapshot(self):
72
73 self.snapshot = self.dom.snapshotCreateXML(self.snapshot_xml)
74
75 if not self.snapshot:
76 self.log.error("Could not create snapshot")
77 raise BaseException
78
79 def revert_snapshot(self):
80 self.dom.revertToSnapshot(self.snapshot)
81 self.snapshot.delete()
82
83 def is_running(self):
84
85 state, reason = self.dom.state()
86
87 if state == libvirt.VIR_DOMAIN_RUNNING:
88 return True
89 else:
90 return False
91
92 def get_serial_device(self):
93
94 if not self.is_running():
95 raise BaseException
96
97 xml_root = ET.fromstring(self.dom.XMLDesc(0))
98
99 elem = xml_root.find("./devices/serial/source")
100 return elem.get("path")
101
341e7373
JS
102 def get_name(self):
103 xml_root = ET.fromstring(self.vm_xml)
104
105 elem = xml_root.find("./name")
106 return elem.text
107
a6a7fe20
JS
108 def check_is_booted_up(self):
109 serial_con = serial_connection(self.get_serial_device())
110
111 serial_con.write("\n")
112 # This will block till the domain is booted up
113 serial_con.read(1)
114
115 #serial_con.close()
116
fc35cba1 117 def login(self, log_file, log_start_time=None, longest_machine_name=10):
a6a7fe20 118 try:
6c352a80
JS
119 self.serial_con = serial_connection(self.get_serial_device(),
120 username=self.username,
121 log_file=log_file,
122 log_start_time=log_start_time,
fc35cba1
JS
123 name=self.name,
124 longest_machine_name=longest_machine_name)
a6a7fe20
JS
125 self.serial_con.login(self.password)
126 except BaseException as e:
127 self.log.error("Could not connect to the domain via serial console")
61bf2ba3
JS
128 self.log.exception(e)
129 raise e
a6a7fe20
JS
130
131 def cmd(self, cmd):
132 return self.serial_con.command(cmd)
133
134 def copy_in(self, fr, to):
135 try:
136 self.disk.mount(self.root_uid, "/")
137 self.disk.copy_in(fr, to)
138 except BaseException as e:
139 self.log.error(e)
140 finally:
141 self.disk.umount("/")
6632e137 142 self.disk.close()