Skip to content

Commit 6e413b8

Browse files
Merge apache/main into cks-rolling-update
Resolve the conflict in schema-42300to2400.sql: main's nic_network_map, disk_offering error_policy and FlashArray rename hunk and this branch's per-node-type root disk size columns are independent additions; keep both, with this branch's columns after main's. Signed-off-by: Brad House <bhouse@nexthop.ai>
2 parents 124ecf2 + c5bd11a commit 6e413b8

279 files changed

Lines changed: 19267 additions & 2109 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/sbom.yml‎

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,18 @@ jobs:
3535
with:
3636
persist-credentials: false
3737

38+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
39+
with:
40+
node-version: 24
41+
3842
- name: Generate UI SBOM
39-
uses: sbomify/sbomify-action@master
40-
env:
41-
LOCK_FILE: ui/package-lock.json
42-
OUTPUT_FILE: sbom.ui.cdx.json
43-
COMPONENT_NAME: cloudstack-ui
44-
COMPONENT_VERSION: ${{ github.ref_name }}
45-
UPLOAD: false
46-
ENRICH: true
43+
# the generator is installed outside the checkout without lifecycle scripts;
44+
# dev dependencies are build tooling and are not shipped in the UI bundle
45+
run: |
46+
npm install --no-save --no-audit --no-fund --ignore-scripts \
47+
--prefix "$RUNNER_TEMP/cdx" @cyclonedx/cyclonedx-npm@6.0.1
48+
"$RUNNER_TEMP/cdx/node_modules/.bin/cyclonedx-npm" --package-lock-only --omit dev \
49+
--spec-version 1.6 --output-format JSON --output-file sbom.ui.cdx.json ui/package.json
4750
4851
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
4952
with:
@@ -62,7 +65,7 @@ jobs:
6265
uses: ./.github/actions/setup-env
6366

6467
- name: Generate Java SBOM
65-
run: mvn -B -ntp -Dnoredist org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom
68+
run: mvn -B -ntp -Dnoredist -Psbom org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom
6669

6770
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
6871
with:
@@ -100,17 +103,14 @@ jobs:
100103
" > marvin-install-requires.txt
101104
python3 -m venv marvin-venv
102105
marvin-venv/bin/pip install --quiet -r marvin-install-requires.txt
103-
marvin-venv/bin/pip freeze > marvin-requirements.txt
104106
105107
- name: Generate marvin SBOM
106-
uses: sbomify/sbomify-action@master
107-
env:
108-
LOCK_FILE: marvin-requirements.txt
109-
OUTPUT_FILE: sbom.marvin.cdx.json
110-
COMPONENT_NAME: cloudstack-marvin
111-
COMPONENT_VERSION: ${{ github.ref_name }}
112-
UPLOAD: false
113-
ENRICH: true
108+
# the generator gets its own venv so it doesn't end up in marvin's SBOM
109+
run: |
110+
python3 -m venv sbom-venv
111+
sbom-venv/bin/pip install --quiet cyclonedx-bom==7.5.0
112+
sbom-venv/bin/cyclonedx-py environment --spec-version 1.6 --output-format JSON \
113+
--output-file sbom.marvin.cdx.json marvin-venv/bin/python
114114
115115
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
116116
with:

‎PendingReleaseNotes‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,36 @@ example.ver.1 > example.ver.2:
9191
no device-mapper multipath configuration is required. A new
9292
Storage.StoragePoolType.NVMeTCP + MultipathNVMeOFAdapterBase /
9393
NVMeTCPAdapter on the KVM side back the new pool type.
94+
95+
* New VM allocation algorithm 'balancedweighted' for vm.allocation.algorithm. Existing
96+
algorithms and the default are unchanged; the new one is opt-in.
97+
98+
Existing algorithms rank hosts on allocated capacity alone. Under a large overprovisioning
99+
factor that reads badly: allocation is measured against a total that has already been
100+
multiplied by the factor, so a host under real strain can still report a low percentage and
101+
keep attracting new VMs. Concurrent deployments make it worse, since they all read the same
102+
figures before any of them is accounted for.
103+
104+
'balancedweighted' ranks hosts on a blend of allocated CPU and memory, measured CPU and
105+
memory utilisation, VM count, and how many VMs started on the host recently. It holds back
106+
hosts that are measurably too busy, and chooses at random from among the best scoring hosts
107+
so that simultaneous deployments do not all pick the same one.
108+
109+
It also holds back hosts that already have host.weighted.starting.vms.threshold VMs sitting
110+
in the Starting state, so that a burst of deployments does not queue up behind itself on one
111+
host. This is the only signal that reacts within a single deployment: capacity is not charged
112+
until a VM reaches Starting and a utilisation average is a sample interval behind, so neither
113+
notices a burst until it is over. Set the threshold to 0 to disable it.
114+
115+
Held-back hosts are never excluded, only moved to the back of the list, so no threshold can
116+
turn a deployment that would have succeeded into an InsufficientServerCapacity failure.
117+
118+
Tuned with the host.weighted.* settings, most of which are cluster scoped. Measured
119+
utilisation comes from a moving average configured with host.load.sample.interval and
120+
host.load.half.life. Until a management server has collected samples, ranking falls back to
121+
allocation figures alone.
122+
123+
KVM console:
124+
* Added the global setting `consoleproxy.kvm.multiple.viewers.enabled` to allow
125+
multiple users to simultaneously access the console of the same KVM user VM.
126+
The setting defaults to false to preserve the existing single-viewer behavior.

‎agent/conf/agent.properties‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,80 @@ iscsi.session.cleanup.enabled=false
318318
# This parameter specifies if the host must be rebooted when something goes wrong with the heartbeat.
319319
#reboot.host.and.alert.management.on.heartbeat.timeout=false
320320

321+
# Action taken by kvmheartbeat.sh / kvmspheartbeat.sh / kvmsmpheartbeat.sh when a storage heartbeat
322+
# write fails persistently. Only consulted when fencing is enabled, i.e.
323+
# 'reboot.host.and.alert.management.on.heartbeat.timeout' is true: that boolean remains
324+
# the global on/off switch for fencing, this setting only chooses WHAT the fence does.
325+
#
326+
# Allowed values:
327+
# hard-reboot - immediate sysrq-trigger reboot (default).
328+
# Required default for setups where a stale NFSv3 mount can prevent
329+
# a graceful shutdown from completing.
330+
# graceful-reboot - 'systemctl reboot' instead of sysrq; allows VMs to stop cleanly.
331+
# Use only if a stale storage mount cannot block shutdown.
332+
# restart-agent - stop every VM on the host, then restart cloudstack-agent; the
333+
# host itself stays up. If it already fired within
334+
# kvm.heartbeat.fence.restart.agent.cooldown, hard-reboot instead.
335+
# log-only - stop every VM on the host, then only write a message to the
336+
# host's syslog (no reboot, no agent restart, no management server
337+
# alert). The operator must watch syslog and investigate.
338+
#
339+
# Any other value falls back to hard-reboot. restart-agent and graceful-reboot need
340+
# systemctl; if it is missing or the systemctl call fails, the fence hard-reboots.
341+
#
342+
# restart-agent and log-only stop the VMs because, once the heartbeat is stale, the
343+
# management server may declare the host Down and HA may start the same VMs on another
344+
# host; two copies would then write to the same disks. If any VM cannot be stopped,
345+
# the fence falls back to hard-reboot.
346+
#
347+
# The non-default values are recommended for setups using LINSTOR/DRBD or any local
348+
# storage with replication, where transient I/O contention can cause a heartbeat
349+
# write to time out without the host actually being unhealthy.
350+
#kvm.heartbeat.fence.action=hard-reboot
351+
352+
# Set to true to let restart-agent and log-only leave the VMs running. This is only
353+
# safe when no VM on this host can be started on another host by HA (VM HA off for all
354+
# of them and host HA not enabled). Otherwise a host the management server declares
355+
# Down can end up with the same VM running twice and corrupting its disks.
356+
# Has no effect on hard-reboot and graceful-reboot.
357+
# This is the master opt-out: when true, nothing is stopped and
358+
# kvm.heartbeat.fence.include.system.vms is ignored (the syslog warning says so).
359+
#kvm.heartbeat.fence.keep.vms.running=false
360+
361+
# Whether restart-agent and log-only also stop system VMs (virtual routers, console
362+
# proxy, secondary storage and internal LB VMs, recognised by their r-, v-, s- and b-
363+
# instance names). With true (default) every VM on the host is stopped. With false
364+
# only user VMs are stopped; system VMs keep running and a system VM that is still
365+
# running does not trigger the hard-reboot fallback.
366+
# Risk of false: if the management server declares this host Down it restarts the
367+
# system VMs on another host, so a virtual router could run twice with the same IP
368+
# and MAC addresses on the guest network, and a second console proxy or secondary
369+
# storage VM could run with the same addresses. Only set false if you accept that.
370+
# Ignored when kvm.heartbeat.fence.keep.vms.running is true. Has no effect on
371+
# hard-reboot and graceful-reboot.
372+
#kvm.heartbeat.fence.include.system.vms=true
373+
374+
# Seconds restart-agent and log-only may spend stopping VMs before the host is
375+
# hard-rebooted instead. Before stopping any VM the fence arms a detached deadman that
376+
# keeps running even if the agent kills the heartbeat script when
377+
# heartbeat.update.timeout runs out (stopping a VM can block for a long time on hung
378+
# storage). If the VMs are not all confirmed stopped within this budget, the deadman
379+
# hard-reboots the host. Each virsh call is also limited to 10 seconds (or this value
380+
# if lower) when coreutils timeout is installed. Keep it below heartbeat.update.timeout
381+
# (60 seconds by default). A value that is not a positive integer means 30.
382+
# Has no effect on hard-reboot and graceful-reboot, or when
383+
# kvm.heartbeat.fence.keep.vms.running is true.
384+
#kvm.heartbeat.fence.stop.vms.timeout=30
385+
386+
# Loop guard for restart-agent, in seconds. While storage keeps failing, the restarted
387+
# agent runs the heartbeat again, it fails again and restart-agent would restart the
388+
# agent again, over and over. Each restart-agent fence records its time under /run
389+
# (kept across agent restarts, cleared by a reboot); if restart-agent already fired less
390+
# than this many seconds ago, the fence hard-reboots the host instead. 0 turns the guard
391+
# off. A value that is not a whole number of seconds means 600.
392+
# Has no effect on hard-reboot, graceful-reboot and log-only.
393+
#kvm.heartbeat.fence.restart.agent.cooldown=600
394+
321395
# Enables manually setting CPU's topology on KVM's VM.
322396
#enable.manually.setting.cpu.topology.on.kvm.vm=true
323397

‎agent/src/main/java/com/cloud/agent/dao/impl/PropertiesStorage.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Map;
2424
import java.util.Properties;
2525

26+
import com.cloud.agent.properties.AgentPropertiesFileHandler;
2627
import org.apache.commons.io.IOUtils;
2728
import org.apache.logging.log4j.Logger;
2829
import org.apache.logging.log4j.LogManager;
@@ -59,6 +60,8 @@ public synchronized void persist(String key, String value) {
5960
_properties.store(output, _name);
6061
output.flush();
6162
output.close();
63+
AgentPropertiesFileHandler.clearCache();
64+
logger.debug("Cleared agent properties cache after persisting key: {}", key);
6265
} catch (IOException e) {
6366
logger.error("Uh-oh: ", e);
6467
} finally {

‎agent/src/main/java/com/cloud/agent/properties/AgentProperties.java‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,96 @@ public class AgentProperties{
622622
public static final Property<Boolean> REBOOT_HOST_AND_ALERT_MANAGEMENT_ON_HEARTBEAT_TIMEOUT
623623
= new Property<>("reboot.host.and.alert.management.on.heartbeat.timeout", false);
624624

625+
/**
626+
* Action taken by the KVM agent's storage heartbeat scripts (kvmheartbeat.sh, kvmspheartbeat.sh
627+
* and kvmsmpheartbeat.sh) when a heartbeat write fails persistently. Only consulted when
628+
* {@link #REBOOT_HOST_AND_ALERT_MANAGEMENT_ON_HEARTBEAT_TIMEOUT} is true: that boolean remains the
629+
* on/off switch for fencing, this setting only chooses what the fence does. Allowed values:
630+
* <ul>
631+
* <li>{@code hard-reboot} (default): immediate sysrq-trigger reboot. Required default for setups
632+
* where a stale NFSv3 mount can prevent a graceful shutdown from completing.</li>
633+
* <li>{@code graceful-reboot}: {@code systemctl reboot} instead of sysrq; allows VMs
634+
* to stop cleanly. Use only if a stale storage mount cannot block shutdown.</li>
635+
* <li>{@code restart-agent}: stop every VM on the host, then restart cloudstack-agent; the host stays up. If it
636+
* already fired within {@link #KVM_HEARTBEAT_FENCE_RESTART_AGENT_COOLDOWN}, hard-reboot instead.</li>
637+
* <li>{@code log-only}: stop every VM on the host, then only write a message to the host's syslog (no
638+
* reboot, no agent restart, no management server alert); the operator must investigate.</li>
639+
* </ul>
640+
* Any other value falls back to {@code hard-reboot}. {@code restart-agent} and {@code graceful-reboot} need
641+
* systemctl; if it is missing or the systemctl call fails, the fence hard-reboots.<br>
642+
* {@code restart-agent} and {@code log-only} stop the VMs because, once the heartbeat is stale, the management
643+
* server may declare the host Down and HA may start the same VMs on another host, where both copies would write
644+
* to the same disks. If any VM cannot be stopped the fence falls back to {@code hard-reboot}. See
645+
* {@link #KVM_HEARTBEAT_FENCE_KEEP_VMS_RUNNING}.<br>
646+
* The non-default values are recommended for setups using LINSTOR/DRBD or other replicated
647+
* local storage, where transient I/O contention can cause a heartbeat write to time out
648+
* without the host actually being unhealthy.<br>
649+
* Read by the heartbeat shell scripts directly from agent.properties.<br>
650+
* Data type: String.<br>
651+
* Default value: {@code hard-reboot}
652+
*/
653+
public static final Property<String> KVM_HEARTBEAT_FENCE_ACTION
654+
= new Property<>("kvm.heartbeat.fence.action", "hard-reboot");
655+
656+
/**
657+
* When true, the {@code restart-agent} and {@code log-only} fence actions leave the host's VMs running instead of
658+
* stopping them first. Only safe when no VM on the host can be started on another host by HA (VM HA off for all
659+
* of them and host HA not enabled); otherwise a host the management server declares Down can end up with the
660+
* same VM running twice, writing to the same disks. No effect on {@code hard-reboot} and {@code graceful-reboot}.
661+
* This is the master opt-out: when true nothing is stopped and {@link #KVM_HEARTBEAT_FENCE_INCLUDE_SYSTEM_VMS}
662+
* is ignored.<br>
663+
* Read by the heartbeat shell scripts directly from agent.properties.<br>
664+
* Data type: Boolean.<br>
665+
* Default value: <code>false</code>
666+
*/
667+
public static final Property<Boolean> KVM_HEARTBEAT_FENCE_KEEP_VMS_RUNNING
668+
= new Property<>("kvm.heartbeat.fence.keep.vms.running", false);
669+
670+
/**
671+
* Whether the {@code restart-agent} and {@code log-only} fence actions also stop system VMs (virtual routers,
672+
* console proxy, secondary storage and internal LB VMs, recognised by their {@code r-}, {@code v-}, {@code s-} and
673+
* {@code b-} instance names). When true every VM on the host is stopped. When false only user VMs are stopped;
674+
* system VMs keep running and do not trigger the {@code hard-reboot} fallback. Risk of false: if the management
675+
* server declares the host Down it restarts the system VMs on another host, so a virtual router could run twice
676+
* with the same IP and MAC addresses. Ignored when {@link #KVM_HEARTBEAT_FENCE_KEEP_VMS_RUNNING} is true. No
677+
* effect on {@code hard-reboot} and {@code graceful-reboot}.
678+
* Read by the heartbeat shell scripts directly from agent.properties.<br>
679+
* Data type: Boolean.<br>
680+
* Default value: <code>true</code>
681+
*/
682+
public static final Property<Boolean> KVM_HEARTBEAT_FENCE_INCLUDE_SYSTEM_VMS
683+
= new Property<>("kvm.heartbeat.fence.include.system.vms", true);
684+
685+
/**
686+
* Seconds the {@code restart-agent} and {@code log-only} fence actions may spend stopping VMs before the host is
687+
* hard-rebooted instead. Before stopping any VM the fence arms a detached deadman that keeps running even if the
688+
* agent kills the heartbeat script when {@link #HEARTBEAT_UPDATE_TIMEOUT} runs out (stopping a VM can block for a
689+
* long time on hung storage). If the VMs are not all confirmed stopped within this budget, the deadman
690+
* hard-reboots the host. Each virsh call is also limited to 10 seconds, or this value if lower, when coreutils
691+
* {@code timeout} is installed. Keep it below {@link #HEARTBEAT_UPDATE_TIMEOUT}. A value that is not a positive
692+
* integer falls back to the default. No effect on {@code hard-reboot} and {@code graceful-reboot}, or when
693+
* {@link #KVM_HEARTBEAT_FENCE_KEEP_VMS_RUNNING} is true.<br>
694+
* Read by the heartbeat shell scripts directly from agent.properties.<br>
695+
* Data type: Integer.<br>
696+
* Default value: <code>30</code>
697+
*/
698+
public static final Property<Integer> KVM_HEARTBEAT_FENCE_STOP_VMS_TIMEOUT
699+
= new Property<>("kvm.heartbeat.fence.stop.vms.timeout", 30);
700+
701+
/**
702+
* Loop guard for the {@code restart-agent} fence action, in seconds. While storage keeps failing, the restarted
703+
* agent runs the heartbeat again, it fails again and {@code restart-agent} would restart the agent again, over and
704+
* over. Each {@code restart-agent} fence records its time under /run (kept across agent restarts, cleared by a
705+
* reboot); if {@code restart-agent} already fired less than this many seconds ago, the fence hard-reboots the host
706+
* instead. 0 turns the guard off. A value that is not a whole number of seconds falls back to the default. No
707+
* effect on {@code hard-reboot}, {@code graceful-reboot} and {@code log-only}.<br>
708+
* Read by the heartbeat shell scripts directly from agent.properties.<br>
709+
* Data type: Integer.<br>
710+
* Default value: <code>600</code>
711+
*/
712+
public static final Property<Integer> KVM_HEARTBEAT_FENCE_RESTART_AGENT_COOLDOWN
713+
= new Property<>("kvm.heartbeat.fence.restart.agent.cooldown", 600);
714+
625715
/**
626716
* Enables manually setting CPU's topology on KVM's VM. <br>
627717
* Data type: Boolean.<br>

0 commit comments

Comments
 (0)