Compare commits

..
Author SHA1 Message Date
Andy Lee 74c12a0d1b feat: add info banner static route tab (#520) 2025-09-13 14:00:18 +08:00
Andy Lee 3277ab4a2b refactor: remove ui-plugin-index setting (#518)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-09 14:55:23 +08:00
Andy Lee 4aabf0b7a3 fix: hide VM take backup action if backup target is not available (#512)
* fix: hide VM take backup action if backup target is not available

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: use extracted func

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-09 14:36:23 +08:00
Andy Lee 4e8cb31e9d fix: unable to attach Ti volume in create VM page (#513)
* fix: unable to attach Ti volume in create VM page

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: only consider Ti / Gi for attached volume

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-09 14:27:40 +08:00
renovate[bot] 1b214b2b6f deps: update dependency @types/node to v20.19.13 (#514)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 14:39:13 +08:00
Andy Lee 748c88866a feat: display N/A in vlanID for overlay network (#511)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-06 11:21:16 +08:00
Andy Lee c3e5c2161e feat: add DHCP ui config in subnet page (#504)
* feat: add dhcp ui setting in subnet page

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: add dhcp option banner link

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-03 12:04:20 +08:00
Andy Lee f932afee68 refactor: disable the setting detail drawer (#507)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-02 17:47:53 +08:00
renovate[bot] 0bbdf3bf17 deps: update minor dependencies (#493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 14:44:52 +08:00
renovate[bot] bdf3ac2803 deps: update patch digest dependencies (#492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-02 12:14:18 +08:00
Andy Lee 0d183a8174 ci: update renovate.json to remove semanticCommitScope (#506)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-02 12:09:14 +08:00
Andy Lee 8f72c33f4b ci: update renovate.json to let PR title start with deps: (#505) 2025-09-02 11:07:49 +08:00
Caio Torres 22c99211f1 fix: preserve YAML device parameters on config editing (#487)
Signed-off-by: Caio Torres <caio.torres@suse.com>
2025-09-01 14:20:12 +08:00
Andy Lee 775330d829 feat: add reconnect button in VNC console (#489)
* feat: add reconnect button in VNC console

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: reconnnect logic

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: call reconnnect

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-09-01 13:51:56 +08:00
freeze 18be022a9f chore: modify the check-version script (#490)
- to pass the dev build

Signed-off-by: Vicente Cheng <vicente.cheng@suse.com>
2025-08-31 15:11:35 +08:00
Andy Lee 56b4b46b5a chore: add v1.6.1 and v1.7.0 feature flags (#483)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-27 15:50:17 +08:00
Andy Lee db398ecad3 chore: bump version to v1.7.0-dev (#482)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-26 14:54:30 +08:00
Andy Lee d175e3b11a chore: bump version to v1.6.0 (#480)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-26 11:17:58 +08:00
Andy Lee 905db4b12c fix: reboot button not work in VNC console (#475)
* fix: reboot button in VNC console

Signed-off-by: Andy Lee <andy.lee@suse.com>

* style: hide the arrow in VNC console

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-25 18:07:26 +08:00
Andy Lee fc31b4bb9d ci: setup env using actions/setup (#478)
* ci: setup env using actions/setup

Signed-off-by: Andy Lee <andy.lee@suse.com>

* ci: rerun lint if PR force push

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-25 18:04:32 +08:00
Andy Lee db29a7c31b ci: correct set PR label script name (#476)
* fix: set label script name

Signed-off-by: Andy Lee <andy.lee@suse.com>

* ci: rerun PR label after PR edited

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-25 17:40:03 +08:00
Andy Lee 2b3541164d ci: add .github/release.yml (#468)
* ci: add release.yml

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: update release.yml

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-22 15:50:11 +08:00
Andy Lee ea5e9aa1f4 ci: auto add PR label workflow and script (#466)
* ci: add auto PR label workflow and script

Signed-off-by: Andy Lee <andy.lee@suse.com>

* fix: bug fix prefix

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: update label mapping

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: read commitlint prefix from commitlint.config.js

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: rename to scripts/extract-release-label.mjs

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-22 15:45:54 +08:00
Andy Lee 18a5608e72 ci: only run PR lint in PR stage (#471)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-22 14:42:50 +08:00
Andy Lee 18599fc94c deps: upgrade @rancher/shell to 3.0.5-rc.8 (#469)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-22 10:40:08 +08:00
Andy Lee e155d46483 ci: add PR title lint (#458)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-22 10:38:39 +08:00
Andy Lee 795e5d178f fix: resource page detail title link (#459)
* fix: resource page detail title link

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: extract harvester type in a map

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: put in config/harvester-map.js

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-15 16:48:38 +08:00
Andy Lee 2e03ac3cf7 fix: spec.domain.memory.guest is lost issue (#462)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-15 11:58:11 +08:00
Andy Lee 76605fdc07 refactor: remove unneeded divider in storage class action menu (#460)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-15 10:51:13 +08:00
Andy Lee c289b001db chore: bump version to v1.6.0-rc6 (#456)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-13 15:05:16 +08:00
Yiya Chen e8d63da1eb fix: fallback default value (#454)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-08-12 13:53:09 +08:00
Andy Lee 4a456ac07d chore: update reviewer (#452)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-05 12:08:06 +08:00
Andy Lee 57dfddd593 chore: bump to 1.6.0-rc5 (#450)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-04 21:31:31 +08:00
Andy Lee 66eac96575 feat: add restore failed message in VM state description (#448)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-04 14:09:26 +08:00
Andy Lee 182d92d80b fix: featureFlags is undefined when installing lower version of ui-ext (#443)
* fix: featureFlags is undefined if install lower version of ui-ext

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-08-01 15:31:20 +08:00
Yiya Chen 1b362f570b fix: update cdiSettings (#444)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-08-01 12:04:14 +08:00
Andy Lee cf798048f8 chore: bump version to v1.6.0-rc4 (#439)
* chore: bump version to v1.6.0-rc4

Signed-off-by: Andy Lee <andy.lee@suse.com>

* fix: missing vm network migration setting

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-30 16:05:29 +08:00
Andy Lee 93c8399935 fix: cpu/ memory columns in host detail VM tab (#436)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-29 16:58:22 +08:00
Andy Lee b72f523ddf fix: isStopping state condition (#431)
* fix: isStopping state condition

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: remove unused variable

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-29 12:58:38 +08:00
Andy Lee e5ffb08df3 chore: upgrade rancher/shell to 3.0.5-rc.7 (#429)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-28 18:33:37 +08:00
Andy Lee 98a6322c11 refactor: filter anchor link in setting description when searching (#428)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-28 18:19:24 +08:00
Andy Lee be7e4bd80b feat: add runStragety field when cloning a VM (#424)
* feat: add runStragety field when cloning a VM

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor: remove unneeded change

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-28 14:18:03 +08:00
Yiya ChenandAndy Lee ed2bc3100b feat: expose CDI settings (#418)
* feat: add cdi settings tab

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* feat: basic layout

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* feat: add fields mutation

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* refactor: rename keys

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* refactor: add edit mode

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* refactor: remove isCreate

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* feat: filter volume mode options

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-07-25 13:55:54 +08:00
Yiya Chen b6ffb3e9f1 fix: exception error (#422)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-24 12:37:56 +08:00
Andy Lee 3d8a6bba7e chore: bump version to 1.6.0-rc3 (#420)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-23 15:00:28 +08:00
Andy Lee be9311dc0c feat: CPU / Memory hotplug support (#413)
* feat: add maxCPU and maxMemory

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: add hotplug dialog

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: add restart message

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: let VM template support cpuMemoryHotplug

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: add feature flag

Signed-off-by: Andy Lee <andy.lee@suse.com>

* feat: add max-hotplug-ratio setting

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-23 14:08:59 +08:00
Andy Lee e294f4c00f refactor: remove unneeded translation keys (#416)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-21 17:41:40 +08:00
Nick ChungandAndy Lee a9fa928912 feat: Remove guest cluster in Rancher (#391)
* feat: Remove guest cluster in Rancher

Signed-off-by: Nick Chung <nick.chung@suse.com>

* feat: add feature flag 1.6.0

Signed-off-by: Nick Chung <nick.chung@suse.com>

* feat: update for review

Signed-off-by: Nick Chung <nick.chung@suse.com>

* chore: fix for review

Signed-off-by: Nick Chung <nick.chung@suse.com>

* chore: fix for review

Signed-off-by: Nick Chung <nick.chung@suse.com>

* refactor: reduce redundant code

Signed-off-by: Andy Lee <andy.lee@suse.com>

* chore: change text area to yaml editor

Signed-off-by: Nick Chung <nick.chung@suse.com>

* refactor: change radio and yaml editor position

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Nick Chung <nick.chung@suse.com>
Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-07-21 17:25:51 +08:00
Yiya Chen ef2b4d1589 feat: disable vm volume resize (#409)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-17 18:29:02 +08:00
Andy Lee a73e9f0ac1 ci: disable subject-max-length commitlint rule (#408)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-17 13:51:06 +08:00
Andy Lee 11b3bf4c1f fix: lint in config/types.js (#407)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-16 19:09:25 +08:00
Nick Chung b775ce5f50 chore: disable vmstate-persistence and longhorn-static StorageClasses (#377)
* chore: disable vmstate-persistence and longhorn-static StorageClasses

Signed-off-by: Nick Chung <nick.chung@suse.com>

* chore: allow internal storage class deletions in image and volumn

Signed-off-by: Nick Chung <nick.chung@suse.com>

* chore: remove deletion tooltips in image and volume pages

Signed-off-by: Nick Chung <nick.chung@suse.com>

* chore: rollback style changes of image and volume lists

Signed-off-by: Nick Chung <nick.chung@suse.com>

---------

Signed-off-by: Nick Chung <nick.chung@suse.com>
2025-07-16 18:21:06 +08:00
Andy Lee 193d4536e3 chore: bump version to v1.6.0-rc2 (#403)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-16 18:09:34 +08:00
Andy Lee 9ca9fdb521 feat: support for subnets and VPCs from UI (#374)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-16 17:51:37 +08:00
Yiya Chen bcabefe9f3 fix: add default value to prevent exception (#397)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-16 15:16:40 +08:00
Andy Lee c541f81dc3 ci: add package version check (#396)
* ci: add package version check

Signed-off-by: Andy Lee <andy.lee@suse.com>

* ci: extract check version in a script

Signed-off-by: Andy Lee <andy.lee@suse.com>

* ci: update env variable

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-16 13:17:05 +08:00
Yiya Chen 4486f71c8f feat: add vm-migration-network setting (#395)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-16 10:13:07 +08:00
Yiya Chen 060105ead3 chore: upgrade rancher/shell to 3.0.5-rc6 (#393)
* chore: bump shell rc6
* chore: add rancher restriction

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-14 09:56:14 +08:00
Andy Lee 3ea73978ee fix: find the correct vmim based on creationTimeStamp (#389)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-10 11:16:45 +08:00
Yiya Chen f4e363396d feat: add csi-online-expand-validation setting (#378)
* feat: add csi-online-expand-validation setting
* feat: invalid json error message
* feat: handle API errors
* refactor: remove inStore()

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-09 15:26:56 +08:00
Andy Lee fa16e24983 chore: bump version to v1.6.0-rc1 (#385)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-09 14:34:36 +08:00
Andy Lee ce63ee6a19 fix: read volume accessMode even is RWO (#381)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-07-09 11:58:21 +08:00
Yiya Chen ee28697161 ci: ignore draft PR add add backport labels (#382)
* ci: skip draft PR

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* ci: fix auto assign

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* ci: add backport label

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

* fix: remove token

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-09 11:34:30 +08:00
Yiya Chen 85a06feb91 feat: disable vm images (#376)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-08 15:23:32 +08:00
Yiya Chen 17dd46cee9 ci: add commands_restrictions (#375)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-03 17:46:11 +08:00
Nick Chung 0ef4ff65cc fix: can't migrate network config in Rancher integration (#371)
Signed-off-by: Nick Chung <nick.chung@suse.com>
2025-07-03 16:52:07 +08:00
Yiya Chen cebb302730 ci: use pull_request_target (#370)
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-03 14:00:31 +08:00
Andy Lee f12717a8f4 fix: add custom promptRemove for backup and snasphot deletion (#367) 2025-07-03 11:51:53 +08:00
Yiya Chen 03f54643fd ci: remove action-add-labels (#368)
* ci: remove action-add-labels
* ci: use gh cli
* ci: use pull_request_target
* ci: add ref

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-02 14:46:03 +08:00
Yiya Chen 7fb6d44208 ci: add backport label on PR creation (#365)
* ci: improve backport workflow
* chore: ignore tmp files
* ci: add exact match
* ci: target main branch
* ci: rewrite workflows

---------

Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-02 11:39:02 +08:00
Nick Chung dc683a50a4 feat: [ENHANCEMENT] Add setting upgrade-config to UI(#8369) (#347)
Signed-off-by: Nick Chung <nick.chung@suse.com>
2025-07-01 11:14:56 +08:00
Yiya Chen be421054d8 feat: SB Enhancements (NS selection and timeout) (#345)
* feat: add namespace field
* feat: add optional inputs
* feat: refine code
* feat: add feature flag
* refactor: fix lint error
* feat: filter default namespaces
* refactor: hide tips with feature flag
* refactor: use UnitInput
* feat: load default value from settings
* refactor: fix API url
* refactor: no available namespaces
* chore: update subject-case rule
---------
Signed-off-by: Yi-Ya Chen <yiya.chen@suse.com>
2025-07-01 09:38:22 +08:00
Andy Lee fcef0391bb ci: replace tag with github.event.release.tag_name (#356)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-06-27 17:29:37 +08:00
Andy Lee 1d89aafeab fix: cloned secret should keep originl type (#354)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-06-27 15:55:47 +08:00
Nick Chung 7386a2deb6 chore: remove run-lint from build-standalone-on-release (#355)
Signed-off-by: Nick Chung <nick.chung@suse.com>
2025-06-27 12:41:22 +08:00
Andy Lee 26f5ebc8e2 ci: auto open backport pr to v1.6 release branch (#353)
Signed-off-by: Andy Lee <andy.lee@suse.com>
2025-06-26 17:01:00 +08:00
24 changed files with 283 additions and 130 deletions
+1
View File
@@ -14,3 +14,4 @@ dist-pkg
pkg/harvester/index.ts
pkg/harvester/store/*
scripts/pkgfile.js
tmp
+12 -31
View File
@@ -1,33 +1,14 @@
pull_request_rules:
- name: Automatically open backport PR to release-harvester-v1.5
conditions:
- base=main
- label="require backport 1.5"
actions:
backport:
branches:
- "release-harvester-v1.5"
assignees:
- "{{ author }}"
labels:
- "v1.5 backport PR"
- name: Ask to resolve conflict
conditions:
- conflict
actions:
comment:
message: This pull request is now in conflict. Could you fix it @{{author}}? 🙏
- name: Automatically open backport PR to release-harvester-v1.0
conditions:
- base=main
- label="require backport 1.0"
actions:
backport:
branches:
- "release-harvester-v1.0"
assignees:
- "{{ author }}"
labels:
- "v1.0 backport PR"
- name: Ask to resolve conflict
conditions:
- conflict
actions:
comment:
message: This pull request is now in conflict. Could you fix it @{{author}}? 🙏
commands_restrictions:
backport:
conditions:
- or:
- sender-permission>=write
- sender=github-actions[bot]
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"extends": [
"config:recommended",
":semanticCommitTypeAll(deps)",
":semanticCommitScopeDisabled"
+49
View File
@@ -0,0 +1,49 @@
name: "[PR Management] Request Backport via Mergify"
on:
pull_request_target:
types: [closed]
branches: [main]
permissions:
pull-requests: write
jobs:
comment-backport:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
- name: Post Mergify backport command
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
pr_number=${{ github.event.pull_request.number }}
repo="${{ github.repository }}"
labels_json='${{ toJson(github.event.pull_request.labels.*.name) }}'
labels=$(echo "$labels_json" | jq -r '.[] // empty')
echo "Labels on PR: $labels"
matches=$(echo "$labels" | grep -oE '^require backport/v[0-9]+\.[0-9]+$' || true)
if [[ -z "$matches" ]]; then
echo "No back‑port labels found — skipping."
exit 0
fi
branches=$(echo "$matches" \
| sed -E 's/^require backport\/v/release-harvester-v/' \
| sort -u | tr '\n' ' ')
branches=${branches%% }
cmd="@Mergifyio backport $branches"
echo "Posting Mergify command: $cmd"
gh pr comment "$pr_number" --repo "$repo" --body "$cmd"
-1
View File
@@ -138,7 +138,6 @@ To validate changes in a release series, switch to the appropriate `vX.Y-head` b
- Examples:
- Test `1.0.x` series → `v1.0-head`
- Test `1.5.x` series → `v1.5-head`
- Test `1.6.x` series → `v1.6-head`
**Steps:**
1. Navigate to **Rancher UI** → **Local** → **App** → **Repositories**
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "harvester-ui-extension",
"version": "1.6.1",
"version": "1.7.0-dev",
"private": false,
"engines": {
"node": ">=20.0.0"
@@ -30,7 +30,7 @@
"nth-check": "2.1.1",
"qs": "6.14.0",
"roarr": "7.21.1",
"semver": "7.7.3",
"semver": "7.7.2",
"@vue/cli-service/html-webpack-plugin": "^5.0.0"
},
"scripts": {
-1
View File
@@ -11,7 +11,6 @@ const CATEGORY = {
ui: [
'branding',
'ui-source',
'ui-plugin-index',
'ui-index',
]
};
@@ -257,6 +257,10 @@ export default {
});
},
reconnect() {
this.$refs.novncConsole.reconnect();
},
softReboot() {
this.vmResource.doSoftReboot();
},
@@ -306,6 +310,13 @@ export default {
{{ t("harvester.action.softreboot") }}
</button>
<button
class="btn btn-sm bg-primary"
@click="reconnect"
>
{{ t("harvester.action.reconnect") }}
</button>
<v-dropdown
v-if="!hideCustomKeysBar"
ref="customKeyPopover"
+8 -7
View File
@@ -1,10 +1,11 @@
// suffix of doc link, see utils/feature-flags.js how to get complete doc link
export const DOC = {
CONSOLE_URL: `/host/#remote-console`,
RANCHER_INTEGRATION_URL: `/rancher/rancher-integration`,
KSMTUNED_MODE: `/host/#ksmtuned-mode`,
UPGRADE_URL: `/upgrade/index`,
UPGRADE_CONFIG_URL: `/advanced/index#upgrade-config`,
STORAGE_NETWORK_EXAMPLE: `/advanced/storagenetwork#configuration-example`,
SUPPORT_BUNDLE_NAMESPACES: `/advanced/index/#support-bundle-namespaces`,
CONSOLE_URL: `/host/#remote-console`,
RANCHER_INTEGRATION_URL: `/rancher/rancher-integration`,
KSMTUNED_MODE: `/host/#ksmtuned-mode`,
UPGRADE_URL: `/upgrade/index`,
UPGRADE_CONFIG_URL: `/advanced/index#upgrade-config`,
STORAGE_NETWORK_EXAMPLE: `/advanced/storagenetwork#configuration-example`,
SUPPORT_BUNDLE_NAMESPACES: `/advanced/index/#support-bundle-namespaces`,
VPC_CONFIGURATION_EXAMPLES: `/networking/kubeovn-vpc#vpc-peering-configuration-examples`,
};
+1
View File
@@ -50,6 +50,7 @@ const FEATURE_FLAGS = {
'vmCloneRunStrategy',
],
'v1.6.1': [],
'v1.7.0': []
};
const generateFeatureFlags = () => {
-2
View File
@@ -4,7 +4,6 @@ export const HCI_SETTING = {
LOG_LEVEL: 'log-level',
SERVER_VERSION: 'server-version',
UI_INDEX: 'ui-index',
UI_PLUGIN_INDEX: 'ui-plugin-index',
UPGRADE_CHECKER_ENABLED: 'upgrade-checker-enabled',
UPGRADE_CHECKER_URL: 'upgrade-checker-url',
VLAN: 'vlan',
@@ -84,7 +83,6 @@ export const HCI_ALLOWED_SETTINGS = {
[HCI_SETTING.SUPPORT_BUNDLE_NAMESPACES]: { from: 'import', canReset: true },
[HCI_SETTING.AUTO_DISK_PROVISION_PATHS]: { canReset: true },
[HCI_SETTING.RELEASE_DOWNLOAD_URL]: { kind: 'url' },
[HCI_SETTING.UI_PLUGIN_INDEX]: { kind: 'url' },
[HCI_SETTING.CONTAINERD_REGISTRY]: {
kind: 'json', from: 'import', canReset: true
},
@@ -15,6 +15,7 @@ import { HCI } from '../types';
import { sortBy } from '@shell/utils/sort';
import { BACKUP_TYPE } from '../config/types';
import { _EDIT, _CREATE } from '@shell/config/query-params';
import { isBackupTargetSettingEmpty, isBackupTargetSettingUnavailable } from '../utils/setting';
export default {
name: 'CreateVMSchedule',
@@ -93,7 +94,7 @@ export default {
return this.settings.find( (O) => O.id === 'backup-target');
},
isEmptyValue() {
return this.getBackupTargetValueIsEmpty(this.backupTargetResource);
return isBackupTargetSettingEmpty(this.backupTargetResource);
},
canUpdate() {
return this?.backupTargetResource?.canUpdate;
@@ -109,7 +110,7 @@ export default {
!!this.value.spec.maxFailure;
},
isBackupTargetUnAvailable() {
return this.value.spec.vmbackup.type === BACKUP_TYPE.BACKUP && (this.errorMessage || this.isEmptyValue) && this.canUpdate;
return this.value.spec.vmbackup.type === BACKUP_TYPE.BACKUP && isBackupTargetSettingUnavailable(this.backupTargetResource);
},
vmOptions() {
const nsVmList = this.$store.getters['harvester/all'](HCI.VM).filter((vm) => vm.metadata.namespace === this.value.metadata.namespace);
@@ -166,20 +167,6 @@ export default {
onTypeChange(newType) {
this.value.metadata.name = `svm${ newType }-${ this.value.spec.vmbackup.source.name }`;
},
getBackupTargetValueIsEmpty(resource) {
let out = true;
if (resource?.value) {
try {
const valueJson = JSON.parse(resource?.value);
out = !valueJson.type;
} catch (e) {}
}
return out;
},
validateFailure(count) {
if (this.value.spec.retain && count > this.value.spec.retain) {
this.value.spec['maxFailure'] = this.value.spec.retain;
+61 -2
View File
@@ -14,6 +14,7 @@ import ArrayList from '@shell/components/form/ArrayList';
import { allHash } from '@shell/utils/promise';
import { HCI } from '../../types';
import ResourceTabs from '@shell/components/form/ResourceTabs/index';
import { Banner } from '@components/Banner';
export default {
name: 'EditSubnet',
@@ -21,6 +22,7 @@ export default {
emits: ['update:value'],
components: {
Banner,
CruResource,
LabeledInput,
LabeledSelect,
@@ -38,7 +40,9 @@ export default {
created() {
const vpc = this.$route.query.vpc || '';
const enableDHCP = this.value?.spec?.enableDHCP || false;
set(this.value.spec, 'enableDHCP', enableDHCP);
set(this.value, 'spec', this.value.spec || {
cidrBlock: '',
protocol: NETWORK_PROTOCOL.IPv4,
@@ -46,7 +50,8 @@ export default {
vpc,
gatewayIP: '',
excludeIps: [],
private: false
private: false,
enableDHCP
});
},
@@ -81,7 +86,6 @@ export default {
protocolOptions() {
return Object.values(NETWORK_PROTOCOL);
},
provider: {
get() {
const raw = this.value.spec.provider;
@@ -125,6 +129,16 @@ export default {
}
},
watch: {
'value.spec.enableDHCP': {
handler(newValue) {
if (newValue === false) {
this.value.spec.dhcpV4Options = '';
this.value.spec.dhcpV6Options = '';
}
},
}
},
methods: {
async saveSubnet(buttonCb) {
const errors = [];
@@ -245,6 +259,45 @@ export default {
/>
</div>
</div>
<div class="row mt-20">
<div class="col span-6">
<RadioGroup
v-model:value="value.spec.enableDHCP"
name="enabled"
:options="[true, false]"
:label="t('harvester.subnet.dhcp.label')"
:labels="[t('generic.enabled'), t('generic.disabled')]"
:mode="mode"
:tooltip="t('harvester.subnet.dhcp.tooltip')"
/>
<LabeledInput
v-if="value.spec.enableDHCP && value.spec.protocol === 'IPv4'"
v-model:value="value.spec.dhcpV4Options"
class="mb-20 mt-20"
:placeholder="t('harvester.subnet.dhcp.placeholder')"
:label="t('harvester.subnet.dhcp.v4Options')"
:mode="mode"
/>
<LabeledInput
v-if="value.spec.enableDHCP && value.spec.protocol === 'IPv6'"
v-model:value="value.spec.dhcpV6Options"
:placeholder="t('harvester.subnet.dhcp.placeholder')"
class="mb-20 mt-20"
:label="t('harvester.subnet.dhcp.v6Options')"
:mode="mode"
/>
<Banner
v-if="value.spec.enableDHCP"
color="info"
class="dhcpOption-banner"
>
<t
k="harvester.subnet.dhcp.dhcpOptionBanner"
:raw="true"
/>
</Banner>
</div>
</div>
<div class="row mt-20">
<div class="col span-6">
<RadioGroup
@@ -321,3 +374,9 @@ export default {
</ResourceTabs>
</CruResource>
</template>
<style lang="scss" scoped>
.dhcpOption-banner {
width: max-content;
}
</style>
@@ -2,12 +2,17 @@
import debounce from 'lodash/debounce';
import { _EDIT, _VIEW } from '@shell/config/query-params';
import { removeAt } from '@shell/utils/array';
import { Banner } from '@components/Banner';
import { DOC } from '../../config/doc-links';
import { docLink } from '../../utils/feature-flags';
export default {
name: 'StaticRoutes',
emits: ['update:value'],
components: { Banner },
props: {
value: {
type: Array,
@@ -45,6 +50,12 @@ export default {
nextHopIPTooltip() {
return this.t('harvester.vpc.staticRoutes.nextHopIP.tooltip');
},
vpcPeeringExamplesLink() {
const version = this.$store.getters['harvester-common/getServerVersion']();
return docLink(DOC.VPC_CONFIGURATION_EXAMPLES, version);
},
},
created() {
@@ -78,6 +89,13 @@ export default {
<template>
<div>
<Banner color="info">
<t
k="harvester.vpc.vpcPeerings.infoBanner"
:raw="true"
:url="vpcPeeringExamplesLink"
/>
</Banner>
<div
v-if="rows.length"
class="static-route-row"
@@ -338,15 +338,6 @@ export default {
saveVM(buttonCb) {
clear(this.errors);
this.validateCPUMemory();
// block create VM flow if has validation errors
if (this.errors.length) {
buttonCb(false);
return;
}
if (this.isSingle) {
this.saveSingle(buttonCb);
} else {
@@ -354,18 +345,6 @@ export default {
}
},
validateCPUMemory() {
const { cpu, memory } = this;
if ((!cpu)) {
this.errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.cpu') }, true));
}
if ((!memory)) {
this.errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.memory') }, true));
}
},
async saveSingle(buttonCb) {
this.parseVM();
this.value.spec.template.spec.hostname = this.hostname ? this.hostname : this.value.metadata.name;
@@ -487,7 +466,9 @@ export default {
}
}
const errors = this.getAccessCredentialsValidation();
const cpuMemoryErrors = this.getCPUMemoryValidation();
const accessCredentialsErrors = this.getAccessCredentialsValidation();
const errors = [...cpuMemoryErrors, ...accessCredentialsErrors];
if (errors.length > 0) {
return Promise.reject(errors);
+10 -2
View File
@@ -236,6 +236,7 @@ harvester:
shutdown: Shut Down
powerOn: Power On
reboot: Reboot
reconnect: Reconnect
forceStop: Force Stop
formatters:
hardwareResourceGauge:
@@ -1044,6 +1045,13 @@ harvester:
gateway:
label: Gateway IP
placeholder: e.g. 172.20.0.1
dhcp:
label: Dynamic Host Configuration Protocol (DHCP)
v4Options: DHCPV4Options
v6Options: DHCPV6Options
placeholder: key1=value1, key2=value2
dhcpOptionBanner: DHCP options is a key/value string concatenate with comma. For more detail, please refer to <a href="https://kubeovn.github.io/docs/v1.13.x/en/kubevirt/dhcp/" target="_blank">KubOVN document</a>
tooltip: Enable DHCP server for this subnet. When enabled, VMs can automatically obtain IP addresses from this subnet.
private:
label: Private Subnet
tooltip: Enable network isolation for this Subnet. When enabled, VMs can only communicate within this subnet, even if other subnets exist under the same VPC.
@@ -1080,6 +1088,7 @@ harvester:
placeholder: e.g. 169.254.0.1/16
remoteVpc:
label: Remote VPC
infoBanner: The static route destination CIDR must cover all subnets CIDR from remote VPC Peer. Read <a href="{url}" target="_blank">VPC Peering Configuration Examples</a> for more information.
network:
label: Virtual Machine Networks
tabs:
@@ -1718,9 +1727,8 @@ advancedSettings:
'harv-server-version': Harvester server version.
'harv-upgrade-checker-enabled': Specifies whether to enable Harvester upgrade check or not. Default is True.
'harv-upgrade-checker-url': Default Harvester upgrade check url. Only used when the <code>upgrade-checker-enabled</code> is equal to True.
'harv-ui-source': Configure how to load the UI source.
'harv-ui-source': Configure how to load the UI source. The `External` option is used to load the UI from a ui-index URL, while the `Bundled` option loads the UI from the local Harvester server.
'harv-ui-index': 'HTML index location for the UI.'
'harv-ui-plugin-index': 'JS index location for the Harvester plugin UI.'
'harv-cluster-registration-url': Registration URL for multi-cluster management.
'harv-http-proxy': 'HTTP proxy for Harvester to access external services.'
'harv-additional-ca': 'Custom CA root certificates for TLS validation.'
@@ -4,7 +4,7 @@ import Loading from '@shell/components/Loading';
import MessageLink from '@shell/components/MessageLink';
import Masthead from '@shell/components/ResourceList/Masthead';
import ResourceTable from '@shell/components/ResourceTable';
import { isBackupTargetSettingEmpty } from '../utils/setting';
import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
import FilterVMSchedule from '../components/FilterVMSchedule';
import { HCI } from '../types';
@@ -39,7 +39,7 @@ export default {
this.settings = hash.settings;
if (this.$store.getters[`${ inStore }/schemaFor`](HCI.SETTING)) {
const backupTargetResource = hash.settings.find( (O) => O.id === 'backup-target');
const isEmpty = this.getBackupTargetValueIsEmpty(backupTargetResource);
const isEmpty = isBackupTargetSettingEmpty(backupTargetResource);
if (backupTargetResource && !isEmpty) {
this.testConnect();
@@ -78,20 +78,6 @@ export default {
}
},
getBackupTargetValueIsEmpty(resource) {
let out = true;
if (resource?.value) {
try {
const valueJson = JSON.parse(resource?.value);
out = !valueJson.type;
} catch (e) {}
}
return out;
},
getRow(row) {
return row.status && row.status.source;
},
@@ -183,11 +169,9 @@ export default {
backupTargetResource() {
return this.settings.find((O) => O.id === 'backup-target');
},
isEmptyValue() {
return this.getBackupTargetValueIsEmpty(this.backupTargetResource);
return isBackupTargetSettingEmpty(this.backupTargetResource);
},
canUpdate() {
return this?.backupTargetResource?.canUpdate;
},
+48 -6
View File
@@ -687,12 +687,14 @@ export default {
set(this.spec.template.spec, 'domain.memory.maxGuest', this.maxMemory);
set(this.spec.template.spec, 'domain.resources.limits.memory', this.maxMemory);
} else {
this.spec.template.spec.domain.cpu.maxSockets = 1;
this.spec.template.spec.domain.cpu.sockets = 1;
this.spec.template.spec.domain.cpu.cores = this.cpu;
this.spec.template.spec.domain.resources.limits.cpu = this.cpu?.toString();
this.spec.template.spec.domain.resources.limits.memory = this.memory;
// clean below fields as we don't need them if not enable CPU and memory hotplug
if (this.spec?.template?.spec?.domain?.cpu?.maxSockets) {
delete this.spec.template.spec.domain.cpu.maxSockets;
}
if (this.spec?.template?.spec?.domain?.memory?.maxGuest) {
delete this.spec.template.spec.domain.memory.maxGuest;
}
@@ -702,7 +704,7 @@ export default {
parseDiskRows(disk) {
const disks = [];
const volumes = [];
const diskNameLables = [];
const diskNameLabels = [];
const volumeClaimTemplates = [];
disk.forEach( (R, index) => {
@@ -724,7 +726,7 @@ export default {
disks.push(_disk);
volumes.push(_volume);
diskNameLables.push(dataVolumeName);
diskNameLabels.push(dataVolumeName);
if (R.source !== SOURCE_TYPE.CONTAINER) {
volumeClaimTemplates.push(_dataVolumeTemplate);
@@ -765,6 +767,9 @@ export default {
}
}
const specDisks = this.spec?.template?.spec?.domain?.devices?.disks;
const mergedDisks = this.mergeDeviceList(specDisks, disks);
let spec = {
...this.spec,
runStrategy: this.runStrategy,
@@ -787,7 +792,7 @@ export default {
...this.spec.template?.spec?.domain,
devices: {
...this.spec.template?.spec?.domain?.devices,
disks,
disks: mergedDisks,
},
},
volumes,
@@ -886,13 +891,16 @@ export default {
interfaces.push(_interface);
});
const specInterfaces = this.spec?.template?.spec?.domain?.devices?.interfaces;
const mergedInterfaces = this.mergeDeviceList(specInterfaces, interfaces);
const spec = {
...this.spec.template.spec,
domain: {
...this.spec.template.spec.domain,
devices: {
...this.spec.template.spec.domain.devices,
interfaces,
interfaces: mergedInterfaces,
},
},
networks
@@ -1035,7 +1043,9 @@ export default {
},
parseVolumeClaimTemplate(R, dataVolumeName) {
if (!String(R.size).includes('Gi') && R.size) {
const sizeString = String(R.size);
if (!(sizeString.includes('Gi') || sizeString.includes('Ti')) && R.size) {
R.size = `${ R.size }${ GIBIBYTE }`;
}
@@ -1359,6 +1369,21 @@ export default {
}
},
getCPUMemoryValidation() {
const errors = [];
const { cpu, memory } = this;
if ((!cpu)) {
errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.cpu') }, true));
}
if ((!memory)) {
errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.memory') }, true));
}
return errors;
},
getAccessCredentialsValidation() {
const errors = [];
@@ -1526,6 +1551,23 @@ export default {
this.refreshYamlEditor();
},
mergeDeviceList(specDeviceList, deviceList) {
if (!specDeviceList || specDeviceList.length === 0) {
return deviceList;
}
const specDeviceMap = new Map(specDeviceList.map((device) => [device.name, device]));
return deviceList.map((device) => {
const specDevice = specDeviceMap.get(device.name);
if (specDevice) {
return { ...specDevice, ...device };
}
return device;
});
},
refreshYamlEditor() {
this.$nextTick(() => {
this.$refs.yamlEditor?.updateValue();
@@ -2,7 +2,7 @@ import SteveModel from '@shell/plugins/steve/steve-class';
import { HCI } from '@shell/config/labels-annotations';
import { NETWORK_TYPE } from '../config/types';
const { UNTAGGED } = NETWORK_TYPE;
const { UNTAGGED, OVERLAY } = NETWORK_TYPE;
export default class NetworkAttachmentDef extends SteveModel {
applyDefaults() {
@@ -45,7 +45,7 @@ export default class NetworkAttachmentDef extends SteveModel {
}
get vlanId() {
return this.vlanType === UNTAGGED ? 'N/A' : this.parseConfig.vlan;
return this.vlanType === UNTAGGED || this.vlanType === OVERLAY ? 'N/A' : this.parseConfig.vlan;
}
get customValidationRules() {
@@ -68,7 +68,7 @@ export default class NetworkAttachmentDef extends SteveModel {
const route = annotations[HCI.NETWORK_ROUTE];
let config = {};
if (this.vlanType === UNTAGGED) {
if (this.vlanType === UNTAGGED || this.vlanType === OVERLAY) {
return 'N/A';
}
@@ -14,6 +14,7 @@ import { BACKUP_TYPE } from '../config/types';
import { HCI } from '../types';
import HarvesterResource from './harvester';
import { getVmCPUMemoryValues } from '../utils/cpuMemory';
import { isBackupTargetSettingUnavailable } from '../utils/setting';
export const OFF = 'Off';
@@ -152,7 +153,7 @@ export default class VirtVm extends HarvesterResource {
},
{
action: 'backupVM',
enabled: !!this.actions?.backup,
enabled: !!this.actions?.backup && !this.isBackupTargetUnavailable,
icon: 'icon icon-backup',
label: this.t('harvester.action.backup')
},
@@ -1239,6 +1240,13 @@ export default class VirtVm extends HarvesterResource {
return this.$rootGetters['harvester-common/getFeatureEnabled']('vmMachineTypes');
}
get isBackupTargetUnavailable() {
const allSettings = this.$rootGetters['harvester/all'](HCI.SETTING) || [];
const backupTargetSetting = allSettings.find( (O) => O.id === 'backup-target');
return isBackupTargetSettingUnavailable(backupTargetSetting);
}
setInstanceLabels(val) {
if ( !this.spec?.template?.metadata?.labels ) {
set(this, 'spec.template.metadata.labels', {});
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "harvester",
"description": "Rancher UI Extension for Harvester",
"version": "1.6.1",
"version": "1.7.0-dev",
"private": false,
"rancher": {
"annotations": {
+7 -6
View File
@@ -3,19 +3,17 @@ import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations
export function getVmCPUMemoryValues(vm) {
if (!vm) {
return {
cpu: null,
cpu: 0,
memory: null,
isHotplugEnabled: false
};
}
const isHotplugEnabled = isCPUMemoryHotPlugEnabled(vm);
const { sockets = 1, threads = 1, cores = null } = vm.spec.template.spec.domain.cpu || {};
const cpu = cores === null ? null : sockets * threads * cores;
if (isHotplugEnabled) {
return {
cpu,
cpu: vm.spec.template.spec.domain.cpu.sockets,
memory: vm.spec.template.spec.domain?.memory?.guest || null,
maxCpu: vm.spec.template.spec.domain.cpu?.maxSockets || 0,
maxMemory: vm.spec.template.spec.domain?.memory?.maxGuest || null,
@@ -23,7 +21,7 @@ export function getVmCPUMemoryValues(vm) {
};
} else {
return {
cpu,
cpu: vm.spec.template.spec.domain.cpu.cores,
memory: vm.spec.template.spec.domain.resources?.limits?.memory || null,
isHotplugEnabled
};
@@ -31,5 +29,8 @@ export function getVmCPUMemoryValues(vm) {
}
export function isCPUMemoryHotPlugEnabled(vm) {
return vm?.metadata?.annotations[HCI_ANNOTATIONS.VM_CPU_MEMORY_HOTPLUG] === 'true' || !!vm?.spec?.template?.spec?.domain?.memory?.maxGuest || false;
return vm?.metadata?.annotations[HCI_ANNOTATIONS.VM_CPU_MEMORY_HOTPLUG] === 'true' ||
!!vm?.spec?.template?.spec?.domain.cpu?.maxSockets ||
!!vm?.spec?.template?.spec?.domain?.memory?.maxGuest ||
false;
}
+25
View File
@@ -0,0 +1,25 @@
export function isBackupTargetSettingEmpty(setting = {}) {
let isEmpty = true;
if (setting?.value) {
try {
const valueJson = JSON.parse(setting?.value);
isEmpty = !valueJson.type;
} catch (e) {
// eslint-disable-next-line no-console
console.error('Failed to parse backup target value:', e);
}
}
return isEmpty;
}
export function isBackupTargetSettingUnavailable(setting = {}) {
const errorMessage = setting.errorMessage;
const isEmptyValue = isBackupTargetSettingEmpty(setting);
const canUpdate = setting.canUpdate;
return (errorMessage || isEmptyValue) && canUpdate;
}
+7 -7
View File
@@ -3114,9 +3114,9 @@
"@types/node" "*"
"@types/node@*", "@types/node@20.10.8", "@types/node@^14.14.31", "@types/node@~20.19.0":
version "20.19.21"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.21.tgz#6e5378e04993c40395473b13baf94a09875157b8"
integrity sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==
version "20.19.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.13.tgz#b79004a05068e28fb2de281b3a44c5c993650e59"
integrity sha512-yCAeZl7a0DxgNVteXFHt9+uyFbqXGy/ShC4BlcHkoE0AfGXYv/BUiplV72DjMYXHDBXFjhvr6DD1NiRVfB4j8g==
dependencies:
undici-types "~6.21.0"
@@ -11525,10 +11525,10 @@ semver-compare@^1.0.0:
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
"semver@2 || 3 || 4 || 5", semver@7.7.3, semver@^5.5.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.6.0, semver@^7.6.3, semver@~7.0.0:
version "7.7.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946"
integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==
"semver@2 || 3 || 4 || 5", semver@7.7.2, semver@^5.5.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.6.0, semver@^7.6.3, semver@~7.0.0:
version "7.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
send@0.17.1:
version "0.17.1"