Skip to content

Commit

Permalink
Introduce virt-xml into disk attachement
Browse files Browse the repository at this point in the history
  • Loading branch information
skobyda committed Sep 30, 2021
1 parent 94f8c9d commit b16aad7
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 100 deletions.
2 changes: 0 additions & 2 deletions src/components/vm/disks/diskAdd.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ export class AddDiskModalBody extends React.Component {
permanent: this.state.permanent,
hotplug: this.state.hotplug,
vmName: vm.name,
vmId: vm.id,
cacheMode: this.state.cacheMode,
busType: this.state.busType
})
Expand Down Expand Up @@ -542,7 +541,6 @@ export class AddDiskModalBody extends React.Component {
permanent: this.state.permanent,
hotplug: this.state.hotplug,
vmName: vm.name,
vmId: vm.id,
cacheMode: this.state.cacheMode,
shareable: volume && volume.format === "raw" && isVolumeUsed[this.state.existingVolumeName],
busType: this.state.busType
Expand Down
7 changes: 6 additions & 1 deletion src/components/vm/disks/vmDisksCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,12 @@ export class VmDisksCard extends React.Component {
columns.push({ title: disk.diskExtras || '' });

const onRemoveDisk = () => {
return domainDetachDisk({ connectionName: vm.connectionName, id: vm.id, name: vm.name, target: disk.target, live: vm.state === 'running', persistent: vm.persistent })
return domainDetachDisk({
connectionName: vm.connectionName,
name: vm.name, target: disk.target,
live: vm.state === 'running',
persistentDisk: vm.persistent && vm.inactiveXML.disks[disk.target]
})
.then(() => {
domainGet({ connectionName: vm.connectionName, id:vm.id });
})
Expand Down
38 changes: 0 additions & 38 deletions src/libvirt-xml-create.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,3 @@
export function getDiskXML(type, file, device, poolName, volumeName, format, target, cacheMode, shareable, busType) {
const doc = document.implementation.createDocument('', '', null);

const diskElem = doc.createElement('disk');
diskElem.setAttribute('type', type);
diskElem.setAttribute('device', device);

const driverElem = doc.createElement('driver');
driverElem.setAttribute('name', 'qemu');
if (format && ['qcow2', 'raw'].includes(format))
driverElem.setAttribute('type', format);
driverElem.setAttribute('cache', cacheMode);
diskElem.appendChild(driverElem);

const sourceElem = doc.createElement('source');
if (type === 'file') {
sourceElem.setAttribute('file', file);
} else {
sourceElem.setAttribute('volume', volumeName);
sourceElem.setAttribute('pool', poolName);
}
diskElem.appendChild(sourceElem);

const targetElem = doc.createElement('target');
targetElem.setAttribute('dev', target);
targetElem.setAttribute('bus', busType);
diskElem.appendChild(targetElem);

if (shareable) {
const shareableElem = doc.createElement('shareable');
diskElem.appendChild(shareableElem);
}

doc.appendChild(diskElem);

return new XMLSerializer().serializeToString(doc.documentElement);
}

export function getNetworkXML({ name, forwardMode, device, ipv4, netmask, ipv6, prefix, ipv4DhcpRangeStart, ipv4DhcpRangeEnd, ipv6DhcpRangeStart, ipv6DhcpRangeEnd }) {
const doc = document.implementation.createDocument('', '', null);

Expand Down
23 changes: 0 additions & 23 deletions src/libvirt-xml-parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,6 @@ import {

const METADATA_NAMESPACE = "https://github.com/cockpit-project/cockpit-machines";

export function getDiskElemByTarget(domxml, targetOriginal) {
const domainElem = getElem(domxml);

if (!domainElem) {
console.warn(`Can't parse dumpxml, input: "${domainElem}"`);
return;
}

const devicesElem = domainElem.getElementsByTagName('devices')[0];
const diskElems = devicesElem.getElementsByTagName('disk');

if (diskElems) {
for (let i = 0; i < diskElems.length; i++) {
const diskElem = diskElems[i];
const targetElem = diskElem.getElementsByTagName('target')[0];
const target = targetElem.getAttribute('dev'); // identifier of the disk, i.e. sda, hdc
if (target === targetOriginal) {
return new XMLSerializer().serializeToString(diskElem);
}
}
}
}

export function getIfaceElemByMac(domxml, mac) {
const domainElem = getElem(domxml);

Expand Down
73 changes: 39 additions & 34 deletions src/libvirtApi/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import {
updateVm,
} from '../actions/store-actions.js';
import {
getDiskXML,
getMemoryBackingXML,
} from '../libvirt-xml-create.js';
import {
Expand All @@ -57,7 +56,6 @@ import {
units,
} from '../helpers.js';
import {
getDiskElemByTarget,
getDoc,
getElem,
getSingleOptionalElem,
Expand Down Expand Up @@ -97,17 +95,6 @@ function buildConsoleVVFile(consoleDetail) {
'fullscreen=0\n';
}

function domainAttachDevice({ connectionName, vmId, permanent, hotplug, xmlDesc }) {
let flags = Enum.VIR_DOMAIN_AFFECT_CURRENT;
if (hotplug)
flags |= Enum.VIR_DOMAIN_AFFECT_LIVE;
if (permanent)
flags |= Enum.VIR_DOMAIN_AFFECT_CONFIG;

// Error handling is done from the calling side
return call(connectionName, vmId, 'org.libvirt.Domain', 'AttachDevice', [xmlDesc, flags], { timeout, type: 'su' });
}

export function getPythonPath() {
return cockpit.spawn(["/bin/sh", "-c", "which /usr/libexec/platform-python 2>/dev/null || which python3 2>/dev/null || which python"]).then(pyexe => { pythonPath = pyexe.trim() });
}
Expand All @@ -121,17 +108,42 @@ export function domainAttachDisk({
volumeName,
format,
target,
vmId,
vmName,
permanent,
hotplug,
cacheMode,
shareable,
busType,
}) {
const xmlDesc = getDiskXML(type, file, device, poolName, volumeName, format, target, cacheMode, shareable, busType);
const options = { err: "message" };
if (connectionName === "system")
options.superuser = "try";

let source = "";
if (type === 'file')
source = `,source.file=${file}`;
else
source = `,source.pool=${poolName},source.volume=${volumeName}`;

let driverType = "";
if (format && ['qcow2', 'raw'].includes(format))
driverType = `,driver.type=${format}`;

const shareableOption = shareable ? "yes" : "no";

const args = [
"virt-xml", "-c", `qemu:///${connectionName}`,
vmName, "--add-device", "--disk",
`type=${type},shareable=${shareableOption},target.bus=${busType},target.dev=${target},driver.name=qemu,cache=${cacheMode},device=${device}${source}${driverType}`
];

if (hotplug) {
args.push("--update");
if (!permanent)
args.push("--no-define");
}

return domainAttachDevice({ connectionName, vmId, permanent, hotplug, xmlDesc });
return cockpit.spawn(args, options);
}

export function domainAttachHostDevice({ connectionName, vmName, live, dev }) {
Expand Down Expand Up @@ -437,30 +449,23 @@ export function domainDesktopConsole({
export function domainDetachDisk({
name,
connectionName,
id: vmPath,
target,
live = false,
persistent
persistentDisk
}) {
let diskXML;
let detachFlags = Enum.VIR_DOMAIN_AFFECT_CURRENT;
if (live)
detachFlags |= Enum.VIR_DOMAIN_AFFECT_LIVE;
const options = { err: "message" };
if (connectionName === "system")
options.superuser = "try";

return call(connectionName, vmPath, 'org.libvirt.Domain', 'GetXMLDesc', [0], { timeout, type: 'u' })
.then(domXml => {
const getXMLFlags = Enum.VIR_DOMAIN_XML_INACTIVE;
diskXML = getDiskElemByTarget(domXml[0], target);
const args = ["virt-xml", "-c", `qemu:///${connectionName}`, name, "--remove-device", "--disk", `target.dev=${target}`];

return call(connectionName, vmPath, 'org.libvirt.Domain', 'GetXMLDesc', [getXMLFlags], { timeout, type: 'u' });
})
.then(domInactiveXml => {
const diskInactiveXML = getDiskElemByTarget(domInactiveXml[0], target);
if (diskInactiveXML && persistent)
detachFlags |= Enum.VIR_DOMAIN_AFFECT_CONFIG;
if (live) {
args.push("--update");
if (!persistentDisk)
args.push("--no-define");
}

return call(connectionName, vmPath, 'org.libvirt.Domain', 'DetachDevice', [diskXML, detachFlags], { timeout, type: 'su' });
});
return cockpit.spawn(args, options);
}

export function domainDetachHostDevice({ connectionName, vmName, live, dev }) {
Expand Down
3 changes: 1 addition & 2 deletions src/libvirtApi/storageVolume.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export function storageVolumeCreateAndAttach({
size,
format,
target,
vmId,
vmName,
permanent,
hotplug,
Expand All @@ -63,7 +62,7 @@ export function storageVolumeCreateAndAttach({
});
})
.then((volPath) => {
return domainAttachDisk({ connectionName, type: "volume", device: "disk", poolName, volumeName, format, target, vmId, permanent, hotplug, cacheMode, busType });
return domainAttachDisk({ connectionName, type: "volume", device: "disk", poolName, volumeName, format, target, vmName, permanent, hotplug, cacheMode, busType });
});
}

Expand Down

0 comments on commit b16aad7

Please sign in to comment.