Visitar URL original
Comparing main...4.22 · apache/cloudstack · GitHub
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: apache/cloudstack
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: apache/cloudstack
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4.22
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 20 commits
  • 58 files changed
  • 25 contributors

Commits on Sep 11, 2026

  1. KVM: assign the hot-plugged NIC the next PCI slot above existing NICs…

    … (monotonic interface naming) (#12826)
    
    * KVM: assign explicit PCI slot when hot-plugging NIC to ensure sequential naming
    
    When hot-plugging a NIC to a running VM, libvirt auto-assigns the next
    free PCI slot. Since non-NIC devices (virtio-serial, disk, balloon,
    watchdog) occupy slots immediately after existing NICs, the hot-plugged
    NIC gets a much higher slot number (e.g. 0x09 instead of 0x05), causing
    the guest to see non-sequential interface names (ens9 instead of ens5).
    
    This fix queries the domain XML to find all used PCI slots and assigns
    the next free slot after the highest existing NIC slot. This matches
    the approach already used by LibvirtReplugNicCommandWrapper which
    preserves PCI slots during re-plug operations.
    
    Fixes #12825
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(kvm): NPE in PlugNic when libvirt domain XML is unavailable
    
    LibvirtPlugNicCommandWrapper.findNextAvailablePciSlot calls
    vm.getXMLDesc(0) and pipes the result straight into Pattern.matcher,
    which NPEs if libvirt returned null (or, in the
    LibvirtComputingResourceTest.testPlugNicCommandNoMatchMack unit test,
    when the Domain mock isn't stubbed for getXMLDesc). Reported by
    @DaanHoogland after the SL packaging run on #12826.
    
    Defensive null check returns null from findNextAvailablePciSlot when
    the domain XML can't be parsed, which falls through to libvirt's
    auto-assignment of the PCI slot — same behaviour as before this PR
    when nextSlot is null.
    
    Also stubs Domain.getXMLDesc(0) in testPlugNicCommandNoMatchMack with
    a minimal <domain> XML that exercises the parser path (rather than
    just relying on the null-fallback), so the test continues to cover
    the happy path of the new logic.
    
    * address review (#12826): parse PCI addresses with an XML parser, split slot selection into helpers, add unit tests
    
    - getUsedPciSlots() parses the domain XML with the safer DocumentBuilderFactory
      and only considers <address type='pci'> elements, replacing the regex.
    - getHighestNicSlot() and getFirstFreeSlotAbove() are separate methods.
    - The javadoc now states the guarantee precisely: deterministic and monotonic
      after the last NIC, not contiguous when other devices sit in between.
    - LibvirtPlugNicCommandWrapperTest covers parsing, selection and the fallbacks.
    
    Signed-off-by: James Peru <jmsperu@gmail.com>
    
    ---------
    
    Signed-off-by: James Peru <jmsperu@gmail.com>
    Co-authored-by: James Peru <jamesperu@Jamess-Mac-mini.local>
    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
    Co-authored-by: jmsperu <jmsperu@users.noreply.github.com>
    4 people authored Sep 11, 2026
    Configuration menu
    Copy the full SHA
    a4d3c66 View commit details
    Browse the repository at this point in the history
  2. ui: fix info card showing invalid template, iso link (#13199)

    Template/ISO for a VM could be in deleted state therefore links should not be shown for them in the VM info-card.
    
    Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
    shwstppr authored Sep 11, 2026
    Configuration menu
    Copy the full SHA
    8261bec View commit details
    Browse the repository at this point in the history

Commits on Sep 14, 2026

  1. Configuration menu
    Copy the full SHA
    8eeccdb View commit details
    Browse the repository at this point in the history

Commits on Sep 19, 2026

  1. Fix importVM for use with dummy template (#14195)

    findByID will fail for dummy template as it is stored in the deleted state.
    abh1sar authored Sep 19, 2026
    Configuration menu
    Copy the full SHA
    273b2ea View commit details
    Browse the repository at this point in the history
  2. importVM improvements: RBD support, volume format, and cluster select…

    …ion (#14162)
    
    * kvm: allow importVm importsource=shared from an RBD pool
    
    The CheckVolumeCommand wrapper on the KVM agent only accepted file based
    pools, so importing a root disk straight from Ceph failed on the agent
    with "Unsupported Storage Pool" and surfaced as "Disk not found or is
    invalid" on the management server. Add RBD to the supported pool types,
    take the virtual size from the disk libvirt resolved (qemu-img cannot
    open a bare RBD image name), skip the QCOW2 header check for raw RBD
    images, and build the rbd: URI when running qemu-img info, the same way
    LibvirtGetVolumesOnStorageCommandWrapper already does for
    listVolumesForImport.
    
    * kvm: record the real image format on an imported volume
    
    importVolume and updateImportedVolume both stamped the cluster default
    format for the hypervisor, so a volume imported from an RBD pool was
    recorded as QCOW2 while a natively deployed volume on the same pool is
    RAW. This affected both entry points: importVm importsource=shared for a
    root disk, and importVolume for a data disk.
    
    Pass the format the hypervisor reported for the existing image, from the
    check answer for a root disk and from the volume listed on the pool for
    a data disk, and fall back to the hypervisor default only when no format
    is reported. This also corrects a raw image imported from a file based
    pool.
    
    * vm import: plan the instance inside the pod and cluster of the requested pool
    
    importKVMInstanceFromDiskImage planned with the pod and cluster unset, so
    the planner was free to pick any host in the zone by capacity. When it
    picked a host in a cluster that cannot see the pool the caller named, the
    volume check ran against whichever pool that cluster does have, and the
    import failed with "Disk not found or is invalid" although the image was
    fine.
    
    Take the pod and cluster from the pool the caller passed, the same way
    importVolume already derives its host from the pool's scope
    
    * verify qemu is able to read the rbd image since check can not be done on a raw file
    
    * use computed volumeDetails in success path as well.
    
    * ui: do not call the imported disk a QCOW2 image
    
    The import wizard for local and shared storage described the disk as a
    QCOW2 image. An image on an RBD pool is raw, and a raw image on a file
    based pool can be imported as well, so the wording is wrong for both.
    Call it a disk image instead.
    
    Only the English strings are changed; the other locales come from
    Transifex.
    abh1sar authored Sep 19, 2026
    Configuration menu
    Copy the full SHA
    ac8d69c View commit details
    Browse the repository at this point in the history

Commits on Sep 24, 2026

  1. core: introduce a set of type adapters (#13624)

    * There is a set of TO classes with renamed fields, which makes impossible to correctly communicate between Management Servers and Agents
    
    * fix logger
    
    * Apply suggestion from Daman
    
    * Apply suggestion from Daman 2
    
    * Fix nested TO renaming, log redaction and cleanup in compat TypeAdaptors
    
    AbstractTOAdaptor built its own private Gson to run the pre-rename
    serialization step through, which meant it never honoured the
    LoggingExclusionStrategy the enclosing Gson (GsonHelper's logging
    instance) was configured with, so fields marked @loglevel(Off) (e.g.
    VirtualMachineTO.vncPassword) leaked in plaintext when logged. It also
    had no adapters for the sibling compat TOs, so nested TOs (disks/nics
    inside a VirtualMachineTO, or a VirtualMachineTO inside a
    MigrateCommand) kept their new field names instead of being renamed
    for backward compatibility with older Agents.
    
    AbstractTOAdaptor no longer owns a Gson at all: it takes one via
    initGson(), mirroring the existing InterfaceTypeAdaptor pattern.
    GsonHelper.setDefaultGsonConfig now wires each compat adaptor's
    delegate Gson incrementally off the same builder, snapshotting it via
    builder.create() right before each adaptor registers itself, so every
    adaptor's delegate carries its sibling adaptors (for correct nested
    renaming) without ever routing back into itself and recursing
    forever. NetworkTO is now registered via registerTypeHierarchyAdapter
    since VirtualMachineTO.nics is declared as NicTO[] (a NetworkTO
    subclass) and was never matched by the previous exact-type
    registration.
    
    This also removes AbstractTOAdaptor's now-unused loggerBuilder/LOGGER
    and its duplicate copy of GsonHelper.setDefaultGsonConfig, and
    replaces a dead null check (getAsJsonObject() never returns null) with
    a real isJsonObject() check.
    
    Added RequestTest#testCompatFieldRenamingNestedTOs covering a
    StartCommand and a MigrateCommand with nested disks/nics, asserting
    old field names appear at every nesting level on the wire and that
    vncPassword never appears in the logging serialization.
    
    * fix logger
    
    * fix build error RequestTest
    
    * fix unit test failures RequestTest.java
    
    ---------
    
    Co-authored-by: mprokopchuk <mprokopchuk@gmail.com>
    Co-authored-by: Daman Arora <damans227@gmail.com>
    3 people authored Sep 24, 2026
    Configuration menu
    Copy the full SHA
    f23766d View commit details
    Browse the repository at this point in the history

Commits on Sep 28, 2026

  1. Configuration menu
    Copy the full SHA
    51c5249 View commit details
    Browse the repository at this point in the history

Commits on Sep 29, 2026

  1. linstor: escape dashes in the LVM volume group name of snapshot paths (…

    …#14066)
    
    Device-mapper doubles every dash in both the volume group and the
    logical volume name. getSnapshotPath only escaped the resource and
    snapshot name, so on a VG like "linstor_pool-lvm-thin" the computed
    /dev/mapper path did not exist and backing up a snapshot to secondary
    storage failed with "qemu-img: Could not open".
    
    Fixes #14011
    rp- authored Sep 29, 2026
    Configuration menu
    Copy the full SHA
    31b6855 View commit details
    Browse the repository at this point in the history
  2. Escape snapshot names in libvirt XML (#14201)

    Co-authored-by: mprokopchuk <mprokopchuk@apple.com>
    sureshanaparti and mprokopchuk authored Sep 29, 2026
    Configuration menu
    Copy the full SHA
    250695e View commit details
    Browse the repository at this point in the history

Commits on Sep 30, 2026

  1. Configuration menu
    Copy the full SHA
    730d11f View commit details
    Browse the repository at this point in the history
  2. CKS/CSI: fix PVC deletion script to avoid '(standard input)' and use …

    …kubectl -o name/jsonpath (#11968)
    Pearl1594 authored Sep 30, 2026
    Configuration menu
    Copy the full SHA
    a772e8d View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    2e63c60 View commit details
    Browse the repository at this point in the history
  4. Improve date/timestamp handling performance in GenericDaoBase and Dat…

    …eUtil (#13809)
    
    * Improve date/timestamp handling performance in GenericDaoBase and DateUtil
    
    * address review comment
    sudo87 authored Sep 30, 2026
    Configuration menu
    Copy the full SHA
    5deb6a9 View commit details
    Browse the repository at this point in the history

Commits on Oct 1, 2026

  1. Configuration menu
    Copy the full SHA
    4b2d387 View commit details
    Browse the repository at this point in the history

Commits on Oct 5, 2026

  1. Merge branch '4.20' into 4.22

    Daan Hoogland
    Daan Hoogland committed Oct 5, 2026
    Configuration menu
    Copy the full SHA
    cdd03d7 View commit details
    Browse the repository at this point in the history

Commits on Oct 6, 2026

  1. Fix overly broad classpath scanning in ReflectUtil.getClassesWithAnno…

    …tation() (#13427)
    
    * Fix overly broad classpath scanning in ReflectUtil.getClassesWithAnnotation()
    
    Production logs show a recurring WARN at startup:
      "could not get type for name org.conscrypt.AllocatedBuffer"
      (org.reflections.ReflectionsException / ClassNotFoundException)
    
    Root cause: ReflectUtil.getClassesWithAnnotation() uses
    ClasspathHelper.forPackage() to collect URLs to scan, but this
    returns all classpath entries (JARs/directories), not just those
    containing the target package. The Reflections library then scans
    every .class file in every JAR — including Netty's
    ConscryptAlpnSslEngine$BufferAdapter which references the optional
    org.conscrypt.AllocatedBuffer type. During expandSuperTypes(),
    Reflections tries Class.forName() on that type and fails because
    Conscrypt is not (and need not be) on the classpath.
    
    The fix adds a FilterBuilder that restricts bytecode scanning to
    only classes whose fully-qualified names match the requested
    packages. This prevents Reflections from processing unrelated
    classes (e.g., io.netty.handler.ssl.*), eliminating the warning
    and reducing startup time by skipping thousands of irrelevant
    class files.
    
    Signed-off-by: Ganesh Maharaj Mahalingam <g.mahalingam@apple.com>
    
    * Add missing API command packages to ApiXmlDocWriter's classpath scan list
    
    ---------
    
    Signed-off-by: Ganesh Maharaj Mahalingam <g.mahalingam@apple.com>
    Co-authored-by: Ganesh Maharaj Mahalingam <g.mahalingam@apple.com>
    vishesh92 and Ganesh Maharaj Mahalingam authored Oct 6, 2026
    Configuration menu
    Copy the full SHA
    d4f5dff View commit details
    Browse the repository at this point in the history
  2. Ensure the detail value is not null when updating the vnc access deta…

    …ils of the vms with failed migrations on host maintenance (#13492)
    
    - Fixes the Constraint error Column 'value' cannot be null
    sureshanaparti authored Oct 6, 2026
    Configuration menu
    Copy the full SHA
    4e679ad View commit details
    Browse the repository at this point in the history
  3. Ensure compliance with storage access groups when mounting disabled s…

    …torage pools (#13990)
    
    - connect to only storage pools with empty tags when access group is empty
    
    Co-authored-by: Sachin R Doddaguni <s_rudrappadoddagu@apple.com>
    sureshanaparti and Sachin R Doddaguni authored Oct 6, 2026
    Configuration menu
    Copy the full SHA
    cc2f74f View commit details
    Browse the repository at this point in the history
  4. Make worker and API thread pool size configurable (#13565)

    * Make worker and API thread pool size configurable
    
    The AsyncJobManager's API and Worker executor thread pool sizes are
    currently derived solely from db.cloud.maxActive (maxActive/2 and
    maxActive*2/3 respectively). This coupling doesn't account for
    environments with predominantly I/O-bound workers, where threads are
    held waiting on external responses for extended periods and higher
    pool sizes may be needed independently of the DB connection count.
    
    This adds two global config keys:
    - api.job.pool.size (default: 50)
    - work.job.pool.size (default: 50)
    
    The actual pool size is Math.max(configured value, db-derived
    default), preserving existing behavior by default while allowing
    operators to increase pool sizes when workloads require it. Pool
    sizes and their derivation are logged at startup for observability.
    
    * Replace synthetic pool size tests with real configure() executor assertions
    
    The previous unit tests for the api.job.pool.size/work.job.pool.size
    config keys only re-ran Math.max() on local hardcoded values, or
    checked ConfigKey plumbing directly, without ever calling
    AsyncJobManagerImpl.configure() itself. That meant a regression in the
    actual pool-sizing logic wouldn't have been caught.
    
    These tests now invoke configure() directly and assert on the real
    core pool size of the created _apiJobExecutor/_workerJobExecutor via
    reflection, with @Before/@after hooks to stub db.properties and reset
    config/executor state between tests.
    
    ---------
    
    Co-authored-by: Sachin R <32716246+sachindoddaguni@users.noreply.github.com>
    Co-authored-by: mprokopchuk <mprokopchuk@apple.com>
    3 people authored Oct 6, 2026
    Configuration menu
    Copy the full SHA
    2974af8 View commit details
    Browse the repository at this point in the history

Commits on Oct 8, 2026

  1. ui: add the missing label for the backup resource limit (#14163)

    The Resource Limits tab derives each label from the resource type name
    returned by listResourceLimits:
    
        $t('label.max' + item.resourcetypename.replace('_', ''))
    
    Resource.ResourceType declares backup("backup", 12), so the key looked up
    for that row is label.maxbackup, which exists in no locale. en.json has
    label.maxbackups, a different string used by the backup schedule form for
    how many backups to retain, and label.maxbackupstorage, which is resource
    type 13. With fallbackLocale 'en' and silentTranslationWarn enabled, the
    miss is silent and vue-i18n renders the key itself, so the row reads
    "label.maxbackup".
    
    The same key is used for the tagged-limit validation message, which shows
    the raw key for the same reason.
    
    Backup was the only one of the 17 ResourceType values without a label; the
    other 16 already resolve.
    stag7824 authored Oct 8, 2026
    Configuration menu
    Copy the full SHA
    437adc8 View commit details
    Browse the repository at this point in the history
Loading