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