]>
git.ipfire.org Git - nitsi.git/blob - src/nitsi/machine.py
3e97ecff1bce985fd96a930a81984b34a870d1ab
6 import xml
.etree
.ElementTree
as ET
9 from . import serial_connection
11 logger
= logging
.getLogger("nitsi.machine")
14 def __init__(self
, libvirt_con
, vm_xml_file
, snapshot_xml_file
, image
, root_uid
, username
, password
):
15 self
.log
= logger
.getChild(os
.path
.basename(vm_xml_file
))
16 self
.con
= libvirt_con
17 # self.dom should be always defined
19 # self.snapshot should be also at least None
24 with
open(vm_xml_file
) as fobj
:
25 self
.vm_xml
= fobj
.read()
26 except FileNotFoundError
as error
:
27 logger
.error("No such file: {}".format(vm_xml_file
))
30 self
.name
= self
.get_name()
31 except BaseException
as error
:
32 logger
.error("Could not get name of the machine: {}".format(vm_xml_file
))
35 self
.log
= logger
.getChild(self
.name
)
36 self
.log
.debug("Name of this machine is {}".format(self
.name
))
39 with
open(snapshot_xml_file
) as fobj
:
40 self
.snapshot_xml
= fobj
.read()
41 except FileNotFoundError
as error
:
42 self
.log
.error("No such file: {}".format(snapshot_xml_file
))
46 if not os
.path
.isfile(self
.image
):
47 self
.log
.error("No such file: {}".format(self
.image
))
49 self
.root_uid
= root_uid
50 self
.disk
= disk
.disk(image
)
52 self
.username
= username
53 self
.password
= password
56 self
.log
.info("Defining virtual machine")
57 self
.dom
= self
.con
.defineXML(self
.vm_xml
)
59 self
.log
.error("Could not define VM")
63 self
.log
.info("Starting virtual machine")
64 if self
.dom
.create() < 0:
65 self
.log
.error("Could not start VM")
70 self
.log
.info("Shutting down virtual machine")
71 if self
.dom
.shutdown() < 0:
72 self
.log
.error("Could not shutdown VM")
75 self
.log
.warn("Cannot shutdown a not running domain")
78 # We cannot undefine a not defined dom object
80 self
.log
.info("Undefining virtual machine")
83 self
.log
.warn("Cannot undefine a not defined domain")
85 def create_snapshot(self
):
86 self
.log
.info("Creating snapshot of virtual machine")
87 self
.snapshot
= self
.dom
.snapshotCreateXML(self
.snapshot_xml
)
89 if self
.snapshot
== None:
90 self
.log
.error("Could not create snapshot")
93 def revert_snapshot(self
):
94 if self
.snapshot
!= None:
95 self
.log
.info("Reverting snapshot")
96 self
.dom
.revertToSnapshot(self
.snapshot
)
97 self
.log
.info("Deleting snapshot")
98 self
.snapshot
.delete()
100 self
.log
.warn("No active snapshot. Cannot revert and delete snapshot")
102 def is_running(self
):
103 # Only if we have a valid dom object we can check the dom state
107 state
, reason
= self
.dom
.state()
109 if state
== libvirt
.VIR_DOMAIN_RUNNING
:
114 def get_serial_device(self
):
116 if not self
.is_running():
119 xml_root
= ET
.fromstring(self
.dom
.XMLDesc(0))
121 elem
= xml_root
.find("./devices/serial/source")
122 return elem
.get("path")
125 xml_root
= ET
.fromstring(self
.vm_xml
)
127 elem
= xml_root
.find("./name")
130 def check_is_booted_up(self
):
131 serial_con
= serial_connection
.serial_connection(self
.get_serial_device())
133 serial_con
.write("\n")
134 # This will block till the domain is booted up
139 def login(self
, log_file
, log_start_time
=None, longest_machine_name
=10):
141 self
.serial_con
= serial_connection
.serial_connection(self
.get_serial_device(),
142 username
=self
.username
,
144 log_start_time
=log_start_time
,
146 longest_machine_name
=longest_machine_name
)
147 self
.serial_con
.login(self
.password
)
148 except BaseException
as e
:
149 self
.log
.error("Could not connect to the domain via serial console")
150 self
.log
.exception(e
)
154 return self
.serial_con
.command(cmd
)
156 def copy_in(self
, fr
, to
):
158 self
.disk
.mount(self
.root_uid
, "/")
159 self
.disk
.copy_in(fr
, to
)
160 except BaseException
as e
:
163 self
.disk
.umount("/")