Added generation of full xml to define a sandbox
This commit is contained in:
parent
29a129f2b8
commit
9508b6ca28
@ -10,6 +10,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
#include "xml.h"
|
||||||
|
|
||||||
#define ALIAS(...) \
|
#define ALIAS(...) \
|
||||||
(const char*[]) { __VA_ARGS__, NULL }
|
(const char*[]) { __VA_ARGS__, NULL }
|
||||||
|
230
src/xml.c
230
src/xml.c
@ -1,20 +1,228 @@
|
|||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
|
||||||
|
#include "pci.h"
|
||||||
|
#include "container.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pcis, char** iso_paths, int vnc_port, char* vnc_password) {
|
||||||
|
// Initialize the output parameters
|
||||||
|
*_xml = NULL;
|
||||||
|
|
||||||
|
// Generate the PCI XML
|
||||||
|
char* pci_xml;
|
||||||
|
result_t result = generate_multi_pci_xml(&pci_xml, pcis);
|
||||||
|
if (result != success())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// Generate the ISO XML
|
||||||
|
char* iso_xml;
|
||||||
|
result = generate_multi_iso_xml(&iso_xml, iso_paths);
|
||||||
|
if (result != success()) {
|
||||||
|
free(pci_xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the VNC XML
|
||||||
|
char* vnc_xml;
|
||||||
|
result = generate_vnc_xml(&vnc_xml, vnc_port, vnc_password);
|
||||||
|
if (result != success()) {
|
||||||
|
free(pci_xml);
|
||||||
|
free(iso_xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the container path
|
||||||
|
char* container_path;
|
||||||
|
result = get_container_path(&container_path, container);
|
||||||
|
if (result != success()) {
|
||||||
|
free(pci_xml);
|
||||||
|
free(iso_xml);
|
||||||
|
free(vnc_xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the XML
|
||||||
|
result = format(_xml, "<domain type='kvm'>\n"
|
||||||
|
"<name>sandbox</name>\n"
|
||||||
|
"\n<!-- Resources -->\n"
|
||||||
|
"<memory unit='B'>%llu</memory>\n"
|
||||||
|
"<vcpu placement='static'>%d</vcpu>\n"
|
||||||
|
"<cpu mode='host-passthrough'/>\n"
|
||||||
|
"\n<!-- OS -->\n"
|
||||||
|
"<os>\n"
|
||||||
|
"<type arch='x86_64' machine='q35'>hvm</type>\n"
|
||||||
|
"<bootmenu enable='no'/>\n"
|
||||||
|
"</os>\n"
|
||||||
|
"\n<!-- Features -->\n"
|
||||||
|
"<features>\n"
|
||||||
|
"<acpi/>\n"
|
||||||
|
"<apic/>\n"
|
||||||
|
"</features>\n"
|
||||||
|
"\n<!-- Clock -->\n"
|
||||||
|
"<clock offset='utc'>\n"
|
||||||
|
"<timer name='rtc' tickpolicy='catchup'/>\n"
|
||||||
|
"<timer name='pit' tickpolicy='delay'/>\n"
|
||||||
|
"<timer name='hpet' present='no'/>\n"
|
||||||
|
"</clock>\n"
|
||||||
|
"\n<!-- Behavior -->\n"
|
||||||
|
"<on_poweroff>destroy</on_poweroff>\n"
|
||||||
|
"<on_reboot>destroy</on_reboot>\n"
|
||||||
|
"<on_crash>destroy</on_crash>\n"
|
||||||
|
"<pm>\n"
|
||||||
|
"<suspend-to-mem enabled='yes'/>\n"
|
||||||
|
"<suspend-to-disk enabled='yes'/>\n"
|
||||||
|
"</pm>\n"
|
||||||
|
"\n<!-- Devices -->\n"
|
||||||
|
"<devices>\n"
|
||||||
|
"<emulator>/usr/bin/qemu-system-x86_64</emulator>\n"
|
||||||
|
"\n<!-- Disks -->\n"
|
||||||
|
"<disk type='file' device='disk'>\n"
|
||||||
|
"<driver name='qemu' type='qcow2'/>\n"
|
||||||
|
"<source file='%s'/>\n"
|
||||||
|
"<target dev='sda' bus='sata'/>\n"
|
||||||
|
"<boot order='1'/>\n"
|
||||||
|
"</disk>\n"
|
||||||
|
"\n<!-- ISOs -->\n"
|
||||||
|
"%s"
|
||||||
|
"\n<!-- VNC -->\n"
|
||||||
|
"%s"
|
||||||
|
"\n<!-- PCIs -->\n"
|
||||||
|
"%s"
|
||||||
|
"\n<!-- Misc -->\n"
|
||||||
|
"<watchdog model='itco' action='poweroff'/>\n"
|
||||||
|
"<memballoon model='none'/>\n"
|
||||||
|
"</devices>\n"
|
||||||
|
"</domain>\n",
|
||||||
|
memory, cpu, container_path, iso_xml, vnc_xml, pci_xml);
|
||||||
|
|
||||||
|
// Free the PCI, ISO, and VNC XML
|
||||||
|
free(pci_xml);
|
||||||
|
free(iso_xml);
|
||||||
|
free(vnc_xml);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result_t generate_iso_xml(char** _xml, char* iso_path, int index) {
|
result_t generate_iso_xml(char** _xml, char* iso_path, int index) {
|
||||||
// Initialize the output parameters
|
// Initialize the output parameters
|
||||||
*_xml = NULL;
|
*_xml = NULL;
|
||||||
|
|
||||||
if (index > 25)
|
if (index >= 26)
|
||||||
return failure("Too many ISO images");
|
return failure("Too many ISO images");
|
||||||
|
|
||||||
// Generate the XML
|
// Generate the XML
|
||||||
return format(_xml, "<disk type='file' device='cdrom'>"
|
return format(_xml, "<disk type='file' device='cdrom'>\n"
|
||||||
" <driver name='qemu' type='raw'/>"
|
"<driver name='qemu' type='raw'/>\n"
|
||||||
" <source file='%s'/>"
|
"<source file='%s'/>\n"
|
||||||
" <target dev='sd%c' bus='sata'/>"
|
"<target dev='sd%c' bus='sata'/>\n"
|
||||||
" <readonly/>"
|
"<boot order='%d'/>\n"
|
||||||
"</disk>",
|
"<readonly/>\n"
|
||||||
iso_path, 'a' + index);
|
"</disk>\n",
|
||||||
|
iso_path, 'b' + index, index + 2); // sda is reserved for the hard drive
|
||||||
|
}
|
||||||
|
|
||||||
|
result_t generate_multi_iso_xml(char** _xml, char** iso_paths) {
|
||||||
|
// Initialize the output parameters
|
||||||
|
*_xml = NULL;
|
||||||
|
|
||||||
|
char* xml = strdup("");
|
||||||
|
if (xml == NULL)
|
||||||
|
return failure("Failed to allocate memory for XML");
|
||||||
|
|
||||||
|
// For each ISO path, generate the XML and append it to the result
|
||||||
|
for (int i = 0; iso_paths[i] != NULL; i++) {
|
||||||
|
// Generate the XML for the ISO
|
||||||
|
char* iso_xml;
|
||||||
|
result_t result = generate_iso_xml(&iso_xml, iso_paths[i], i);
|
||||||
|
if (result != success()) {
|
||||||
|
free(xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the ISO XML to the result
|
||||||
|
char* new_xml;
|
||||||
|
result = format(&new_xml, "%s%s", xml == NULL ? "" : xml, iso_xml);
|
||||||
|
|
||||||
|
free(iso_xml);
|
||||||
|
|
||||||
|
// Check that the append operation was successful
|
||||||
|
if (result != success()) {
|
||||||
|
free(xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap the XML strings
|
||||||
|
free(xml);
|
||||||
|
xml = new_xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_xml = xml;
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
|
||||||
|
result_t generate_pci_xml(char** _xml, char* pci) {
|
||||||
|
// Initialize the output parameters
|
||||||
|
*_xml = NULL;
|
||||||
|
|
||||||
|
// Check that the PCI address is valid
|
||||||
|
result_t result = check_pci_address(pci);
|
||||||
|
if (result != success())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// Split the PCI address into its components
|
||||||
|
long domain = 0;
|
||||||
|
long bus = 0;
|
||||||
|
long slot = 0;
|
||||||
|
long function = 0;
|
||||||
|
|
||||||
|
// Generate the XML
|
||||||
|
return format(_xml, "<hostdev mode='subsystem' type='pci' managed='yes'>\n"
|
||||||
|
"<source>\n"
|
||||||
|
"<address domain='0x%04lx' bus='0x%02lx' slot='0x%02lx' function='0x%01lx'/>\n"
|
||||||
|
"</source>\n"
|
||||||
|
"</hostdev>\n",
|
||||||
|
domain, bus, slot, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
result_t generate_multi_pci_xml(char** _xml, char** pcis) {
|
||||||
|
// Initialize the output parameters
|
||||||
|
*_xml = NULL;
|
||||||
|
|
||||||
|
char* xml = strdup("");
|
||||||
|
if (xml == NULL)
|
||||||
|
return failure("Failed to allocate memory for XML");
|
||||||
|
|
||||||
|
// For each PCI address, generate the XML and append it to the result
|
||||||
|
for (int i = 0; pcis[i] != NULL; i++) {
|
||||||
|
// Generate the XML for the PCI address
|
||||||
|
char* pci_xml;
|
||||||
|
result_t result = generate_pci_xml(&pci_xml, pcis[i]);
|
||||||
|
if (result != success()) {
|
||||||
|
free(xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the PCI XML to the result
|
||||||
|
char* new_xml;
|
||||||
|
result = format(&new_xml, "%s%s", xml == NULL ? "" : xml, pci_xml);
|
||||||
|
|
||||||
|
free(pci_xml);
|
||||||
|
|
||||||
|
// Check that the append operation was successful
|
||||||
|
if (result != success()) {
|
||||||
|
free(xml);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap the XML strings
|
||||||
|
free(xml);
|
||||||
|
xml = new_xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_xml = xml;
|
||||||
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t generate_vnc_xml(char** _xml, int vnc_port, char* password) {
|
result_t generate_vnc_xml(char** _xml, int vnc_port, char* password) {
|
||||||
@ -22,8 +230,8 @@ result_t generate_vnc_xml(char** _xml, int vnc_port, char* password) {
|
|||||||
*_xml = NULL;
|
*_xml = NULL;
|
||||||
|
|
||||||
// Generate the XML
|
// Generate the XML
|
||||||
if (vnc_port == -1)
|
if (vnc_port != -1)
|
||||||
return format(_xml, "<graphics type='none'/>");
|
return format(_xml, "<graphics type='vnc' port='%d' autoport='no' listen='0.0.0.0' passwd='%s'/>\n", vnc_port, password);
|
||||||
else
|
else
|
||||||
return format(_xml, "<graphics type='vnc' port='%d' autoport='no' listen='0.0.0.0' passwd='%s'/>", vnc_port, password);
|
return format(_xml, "");
|
||||||
}
|
}
|
||||||
|
26
src/xml.h
26
src/xml.h
@ -7,12 +7,12 @@
|
|||||||
/// @param container The container to generate the XML for.
|
/// @param container The container to generate the XML for.
|
||||||
/// @param cpu The number of CPUs to allocate to the container.
|
/// @param cpu The number of CPUs to allocate to the container.
|
||||||
/// @param memory The amount of memory to allocate to the container, in bytes.
|
/// @param memory The amount of memory to allocate to the container, in bytes.
|
||||||
/// @param pci A null-terminated array of PCI devices to pass through to the container.
|
/// @param pcis A null-terminated array of PCI devices to pass through to the container.
|
||||||
/// @param iso_path A null-terminated array of ISO image paths to attach to the container.
|
/// @param iso_paths A null-terminated array of ISO image paths to attach to the container.
|
||||||
/// @param vnc_port The VNC port to use for the container. If -1, no VNC server will be started.
|
/// @param vnc_port The VNC port to use for the container. If -1, no VNC server will be started.
|
||||||
/// @param vnc_password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
/// @param vnc_password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pci, char** iso_path, int vnc_port, char* vnc_password);
|
result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t memory, char** pcis, char** iso_paths, int vnc_port, char* vnc_password);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to attach an ISO image to a container.
|
/// @brief Generate the libvirt XML used to attach an ISO image to a container.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML in.
|
||||||
@ -21,15 +21,27 @@ result_t generate_container_xml(char** _xml, char* container, int cpu, uint64_t
|
|||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_iso_xml(char** _xml, char* iso_path, int index);
|
result_t generate_iso_xml(char** _xml, char* iso_path, int index);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to start a VNC server for a container.
|
/// @brief Generate the libvirt XML used to attach multiple ISO images to a container.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML in.
|
||||||
/// @param vnc_port The VNC port to use for the container.
|
/// @param iso_paths The paths to the ISO images to attach.
|
||||||
/// @param password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_vnc_xml(char** _xml, int vnc_port, char* password);
|
result_t generate_multi_iso_xml(char** _xml, char** iso_paths);
|
||||||
|
|
||||||
/// @brief Generate the libvirt XML used to pass through a PCI device to a container.
|
/// @brief Generate the libvirt XML used to pass through a PCI device to a container.
|
||||||
/// @param _xml The string pointer to store the resulting XML in.
|
/// @param _xml The string pointer to store the resulting XML in.
|
||||||
/// @param pci The PCI device to generate the XML for.
|
/// @param pci The PCI device to generate the XML for.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
result_t generate_pci_xml(char** _xml, char* pci);
|
result_t generate_pci_xml(char** _xml, char* pci);
|
||||||
|
|
||||||
|
/// @brief Generate the libvirt XML used to pass through multiple PCI devices to a container.
|
||||||
|
/// @param _xml The string pointer to store the resulting XML in.
|
||||||
|
/// @param pcis The PCI devices to generate the XML for.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t generate_multi_pci_xml(char** _xml, char** pcis);
|
||||||
|
|
||||||
|
/// @brief Generate the libvirt XML used to start a VNC server for a container.
|
||||||
|
/// @param _xml The string pointer to store the resulting XML in.
|
||||||
|
/// @param vnc_port The VNC port to use for the container.
|
||||||
|
/// @param password The password to use for the VNC server. This parameter is ignored if VNC is not enabled.
|
||||||
|
/// @return The result of the operation.
|
||||||
|
result_t generate_vnc_xml(char** _xml, int vnc_port, char* password);
|
||||||
|
Loading…
Reference in New Issue
Block a user