Can attach multiple ISOs to the same domain at the same time
This commit is contained in:
		@@ -87,8 +87,8 @@ pub struct VMInfo {
 | 
			
		||||
    pub number_vcpu: usize,
 | 
			
		||||
    /// Enable VNC access through admin console
 | 
			
		||||
    pub vnc_access: bool,
 | 
			
		||||
    /// Attach an ISO file
 | 
			
		||||
    pub iso_file: Option<String>,
 | 
			
		||||
    /// Attach ISO file(s)
 | 
			
		||||
    pub iso_files: Vec<String>,
 | 
			
		||||
    /// Storage - https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-virtualized_block_devices-adding_storage_devices_to_guests#sect-Virtualization-Adding_storage_devices_to_guests-Adding_file_based_storage_to_a_guest
 | 
			
		||||
    pub disks: Vec<Disk>,
 | 
			
		||||
    /// Network cards
 | 
			
		||||
@@ -133,7 +133,7 @@ impl VMInfo {
 | 
			
		||||
 | 
			
		||||
        let mut disks = vec![];
 | 
			
		||||
 | 
			
		||||
        if let Some(iso_file) = &self.iso_file {
 | 
			
		||||
        for iso_file in &self.iso_files {
 | 
			
		||||
            if !files_utils::check_file_name(iso_file) {
 | 
			
		||||
                return Err(StructureExtraction("ISO filename is invalid!").into());
 | 
			
		||||
            }
 | 
			
		||||
@@ -156,12 +156,15 @@ impl VMInfo {
 | 
			
		||||
                    file: path.to_string_lossy().to_string(),
 | 
			
		||||
                },
 | 
			
		||||
                target: DiskTargetXML {
 | 
			
		||||
                    dev: "hdc".to_string(),
 | 
			
		||||
                    dev: format!(
 | 
			
		||||
                        "hd{}",
 | 
			
		||||
                        ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"][disks.len()]
 | 
			
		||||
                    ),
 | 
			
		||||
                    bus: "usb".to_string(),
 | 
			
		||||
                },
 | 
			
		||||
                readonly: Some(DiskReadOnlyXML {}),
 | 
			
		||||
                boot: DiskBootXML {
 | 
			
		||||
                    order: "1".to_string(),
 | 
			
		||||
                    order: (disks.len() + 1).to_string(),
 | 
			
		||||
                },
 | 
			
		||||
                address: None,
 | 
			
		||||
            })
 | 
			
		||||
@@ -182,7 +185,7 @@ impl VMInfo {
 | 
			
		||||
        // Check disks name for duplicates
 | 
			
		||||
        for disk in &self.disks {
 | 
			
		||||
            if self.disks.iter().filter(|d| d.name == disk.name).count() > 1 {
 | 
			
		||||
                return Err(StructureExtraction("Two differents disks have the same name!").into());
 | 
			
		||||
                return Err(StructureExtraction("Two different disks have the same name!").into());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -328,12 +331,13 @@ impl VMInfo {
 | 
			
		||||
            number_vcpu: domain.vcpu.body,
 | 
			
		||||
            memory: convert_to_mb(&domain.memory.unit, domain.memory.memory)?,
 | 
			
		||||
            vnc_access: domain.devices.graphics.is_some(),
 | 
			
		||||
            iso_file: domain
 | 
			
		||||
            iso_files: domain
 | 
			
		||||
                .devices
 | 
			
		||||
                .disks
 | 
			
		||||
                .iter()
 | 
			
		||||
                .find(|d| d.device == "cdrom")
 | 
			
		||||
                .map(|d| d.source.file.rsplit_once('/').unwrap().1.to_string()),
 | 
			
		||||
                .filter(|d| d.device == "cdrom")
 | 
			
		||||
                .map(|d| d.source.file.rsplit_once('/').unwrap().1.to_string())
 | 
			
		||||
                .collect(),
 | 
			
		||||
 | 
			
		||||
            disks: domain
 | 
			
		||||
                .devices
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ interface VMInfoInterface {
 | 
			
		||||
  memory: number;
 | 
			
		||||
  number_vcpu: number;
 | 
			
		||||
  vnc_access: boolean;
 | 
			
		||||
  iso_file?: string;
 | 
			
		||||
  iso_files: string[];
 | 
			
		||||
  disks: VMDisk[];
 | 
			
		||||
  networks: VMNetInterface[];
 | 
			
		||||
}
 | 
			
		||||
@@ -68,7 +68,7 @@ export class VMInfo implements VMInfoInterface {
 | 
			
		||||
  number_vcpu: number;
 | 
			
		||||
  memory: number;
 | 
			
		||||
  vnc_access: boolean;
 | 
			
		||||
  iso_file?: string;
 | 
			
		||||
  iso_files: string[];
 | 
			
		||||
  disks: VMDisk[];
 | 
			
		||||
  networks: VMNetInterface[];
 | 
			
		||||
 | 
			
		||||
@@ -83,7 +83,7 @@ export class VMInfo implements VMInfoInterface {
 | 
			
		||||
    this.number_vcpu = int.number_vcpu;
 | 
			
		||||
    this.memory = int.memory;
 | 
			
		||||
    this.vnc_access = int.vnc_access;
 | 
			
		||||
    this.iso_file = int.iso_file;
 | 
			
		||||
    this.iso_files = int.iso_files;
 | 
			
		||||
    this.disks = int.disks;
 | 
			
		||||
    this.networks = int.networks;
 | 
			
		||||
  }
 | 
			
		||||
@@ -96,6 +96,7 @@ export class VMInfo implements VMInfoInterface {
 | 
			
		||||
      memory: 1024,
 | 
			
		||||
      number_vcpu: 1,
 | 
			
		||||
      vnc_access: true,
 | 
			
		||||
      iso_files: [],
 | 
			
		||||
      disks: [],
 | 
			
		||||
      networks: [],
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -16,22 +16,47 @@ import Icon from "@mdi/react";
 | 
			
		||||
export function VMSelectIsoInput(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  isoList: IsoFile[];
 | 
			
		||||
  value?: string;
 | 
			
		||||
  onChange: (newVal?: string) => void;
 | 
			
		||||
  attachedISOs: string[];
 | 
			
		||||
  onChange: (newVal: string[]) => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  if (!p.value && !p.editable) return <></>;
 | 
			
		||||
  if (!p.attachedISOs && !p.editable) return <></>;
 | 
			
		||||
 | 
			
		||||
  if (p.value) {
 | 
			
		||||
    const iso = p.isoList.find((d) => d.filename === p.value);
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <SelectInput
 | 
			
		||||
        label="Attach an ISO file"
 | 
			
		||||
        editable={p.editable}
 | 
			
		||||
        value={undefined}
 | 
			
		||||
        onValueChange={(v) => {
 | 
			
		||||
          if (v) {
 | 
			
		||||
            p.attachedISOs.push(v);
 | 
			
		||||
            p.onChange(p.attachedISOs);
 | 
			
		||||
          }
 | 
			
		||||
        }}
 | 
			
		||||
        options={[
 | 
			
		||||
          { label: "None", value: undefined },
 | 
			
		||||
          ...p.isoList.map((i) => {
 | 
			
		||||
            return {
 | 
			
		||||
              label: `${i.filename} ${filesize(i.size)}`,
 | 
			
		||||
              value: i.filename,
 | 
			
		||||
            };
 | 
			
		||||
          }),
 | 
			
		||||
        ]}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      {p.attachedISOs.map((isoName, num) => {
 | 
			
		||||
        const iso = p.isoList.find((d) => d.filename === isoName);
 | 
			
		||||
        return (
 | 
			
		||||
          <ListItem
 | 
			
		||||
            key={num}
 | 
			
		||||
            secondaryAction={
 | 
			
		||||
              p.editable && (
 | 
			
		||||
                <IconButton
 | 
			
		||||
                  edge="end"
 | 
			
		||||
              aria-label="detach iso file"
 | 
			
		||||
                  aria-label="Detach iso file"
 | 
			
		||||
                  onClick={() => {
 | 
			
		||||
                p.onChange(undefined);
 | 
			
		||||
                    p.attachedISOs.splice(num, 1);
 | 
			
		||||
                    p.onChange(p.attachedISOs);
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  <Tooltip title="Detach ISO file">
 | 
			
		||||
@@ -52,23 +77,7 @@ export function VMSelectIsoInput(p: {
 | 
			
		||||
            />
 | 
			
		||||
          </ListItem>
 | 
			
		||||
        );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SelectInput
 | 
			
		||||
      label="ISO file"
 | 
			
		||||
      editable={p.editable}
 | 
			
		||||
      value={p.value}
 | 
			
		||||
      onValueChange={p.onChange}
 | 
			
		||||
      options={[
 | 
			
		||||
        { label: "None", value: undefined },
 | 
			
		||||
        ...p.isoList.map((i) => {
 | 
			
		||||
          return {
 | 
			
		||||
            label: `${i.filename} ${filesize(i.size)}`,
 | 
			
		||||
            value: i.filename,
 | 
			
		||||
          };
 | 
			
		||||
        }),
 | 
			
		||||
      ]}
 | 
			
		||||
    />
 | 
			
		||||
      })}
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -203,9 +203,9 @@ function VMDetailsInner(
 | 
			
		||||
        <VMSelectIsoInput
 | 
			
		||||
          editable={p.editable}
 | 
			
		||||
          isoList={p.isoList}
 | 
			
		||||
          value={p.vm.iso_file}
 | 
			
		||||
          attachedISOs={p.vm.iso_files}
 | 
			
		||||
          onChange={(v) => {
 | 
			
		||||
            p.vm.iso_file = v;
 | 
			
		||||
            p.vm.iso_files = v;
 | 
			
		||||
            p.onChange?.();
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user