mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-02 20:26:09 +08:00
Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fbe1943d8 | ||
|
|
ec6bc4d639 | ||
|
|
3824a14730 | ||
|
|
0fc8bece02 | ||
|
|
39764af627 | ||
|
|
bdc87bda0e | ||
|
|
e0dc77624b | ||
|
|
c3ba10bd22 | ||
|
|
5b7d54d0a3 | ||
|
|
99a216dfa0 | ||
|
|
e4c85f510e | ||
|
|
f391f018de | ||
|
|
4b2e92ea15 | ||
|
|
2f956d5946 | ||
|
|
5f8d556ea2 | ||
|
|
396ab48f1c | ||
|
|
6b8c079018 | ||
|
|
7f638e86c8 | ||
|
|
0c4955a766 | ||
|
|
3f4ff30275 | ||
|
|
8e0332a364 | ||
|
|
6700b2055e | ||
|
|
e486852f7a | ||
|
|
c19341bec9 | ||
|
|
8cbb9d6b18 | ||
|
|
00f0953592 | ||
|
|
58507f0b2e | ||
|
|
7785d7f469 | ||
|
|
2c043e0a8e |
@@ -7,8 +7,7 @@
|
||||
],
|
||||
"baseBranches": [
|
||||
"main",
|
||||
"release-harvester-v1.7",
|
||||
"release-harvester-v1.8"
|
||||
"/^release-harvester-v\\d+\\.\\d+$/"
|
||||
],
|
||||
"automergeMajor": false,
|
||||
"semanticCommits": "enabled",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
name: FOSSA Scanning
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main", "release-harvester-v*"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
fossa-scanning:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
||||
|
||||
# The FOSSA token is shared between all repos in Harvester's GH org. It can
|
||||
# be used directly and there is no need to request specific access to EIO.
|
||||
- name: Read FOSSA token
|
||||
uses: rancher-eio/read-vault-secrets@main
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/org/harvester/fossa/credentials token | FOSSA_API_KEY_PUSH_ONLY
|
||||
|
||||
- name: FOSSA scan
|
||||
uses: fossas/fossa-action@main
|
||||
with:
|
||||
api-key: ${{ env.FOSSA_API_KEY_PUSH_ONLY }}
|
||||
# Only runs the scan and do not provide/returns any results back to the
|
||||
# pipeline.
|
||||
run-tests: false
|
||||
@@ -163,7 +163,7 @@ If you want to contribute, start by reading this document, then visit our [Getti
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014-2026 [SUSE, LLC.](https://www.suse.com/)
|
||||
Copyright (c) 2014-2025 [SUSE, LLC.](https://www.suse.com/)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harvester-ui-extension",
|
||||
"version": "1.8.0-dev",
|
||||
"version": "1.7.0",
|
||||
"private": false,
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
@@ -24,11 +24,11 @@
|
||||
"glob": "7.2.3",
|
||||
"glob-parent": "6.0.2",
|
||||
"json5": "2.2.3",
|
||||
"@types/lodash": "4.17.23",
|
||||
"@types/lodash": "4.17.21",
|
||||
"merge": "2.1.1",
|
||||
"node-forge": "1.3.3",
|
||||
"nth-check": "2.1.1",
|
||||
"qs": "6.14.1",
|
||||
"qs": "6.14.0",
|
||||
"roarr": "7.21.2",
|
||||
"semver": "7.7.3",
|
||||
"@vue/cli-service/html-webpack-plugin": "^5.0.0"
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
# harvester-ui-extension
|
||||
|
||||
The Harvester UI Extension is a Rancher extension that provides the user interface for [Harvester](https://harvesterhci.io) within the [Rancher Dashboard](https://github.com/rancher/dashboard).
|
||||
|
||||
> **Note:**
|
||||
> This extension is available starting from **Rancher 2.10.0**. Ensure your Rancher version is **2.10.0 or later** to access Harvester integration.
|
||||
|
||||
## Installation
|
||||
|
||||
For detailed installation instructions, please refer to the [official Harvester documentation](https://docs.harvesterhci.io/v1.5/rancher/harvester-ui-extension#installation-on-rancher-210).
|
||||
|
||||
|
||||
## Development Setup
|
||||
|
||||
Ensure **Node.js v20 or later** is installed for development and debugging.
|
||||
|
||||
### Standalone Mode
|
||||
|
||||
Run the extension standalone with hot reload at `https://localhost:8005`.
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
yarn install
|
||||
|
||||
# Start the development server
|
||||
RANCHER_ENV=harvester API=https://your-harvester-ip yarn dev
|
||||
|
||||
# Example with specific server version
|
||||
RANCHER_ENV=harvester VUE_APP_SERVER_VERSION=v1.5.0 API=https://192.168.1.123 yarn dev
|
||||
```
|
||||
|
||||
You may also define environment variables in a `.env` file:
|
||||
|
||||
```env
|
||||
RANCHER_ENV=harvester
|
||||
VUE_APP_SERVER_VERSION=v1.5.0
|
||||
API=https://192.168.1.123
|
||||
```
|
||||
|
||||
### Rancher Integration Mode
|
||||
|
||||
To run as a Rancher extension, follow the [Rancher UI Extension Guide](https://extensions.rancher.io/extensions/next/extensions-getting-started#running-the-app).
|
||||
|
||||
```bash
|
||||
API=https://your-rancher-ip yarn dev
|
||||
```
|
||||
|
||||
## Commit Message Guidelines
|
||||
|
||||
This project uses [commit-lint](https://commitlint.js.org/) with [Conventional Commits](https://www.conventionalcommits.org/) to ensure consistent and meaningful commit messages.
|
||||
|
||||
### Commit Message Format
|
||||
|
||||
All commit messages must follow the conventional commit format:
|
||||
|
||||
```
|
||||
<type>[optional scope]: <description>
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer(s)]
|
||||
```
|
||||
|
||||
### Supported Types
|
||||
|
||||
- **feat**: New features
|
||||
- **fix**: Bug fixes
|
||||
- **docs**: Documentation changes
|
||||
- **style**: Code style changes (formatting, missing semicolons, etc.)
|
||||
- **refactor**: Code refactoring
|
||||
- **perf**: Performance improvements
|
||||
- **test**: Adding or updating tests
|
||||
- **build**: Build system or external dependencies
|
||||
- **ci**: CI/CD changes
|
||||
- **chore**: Other changes that don't modify src or test files
|
||||
- **revert**: Reverts a previous commit
|
||||
- **wip**: Work in progress
|
||||
- **deps**: Dependency updates
|
||||
- **security**: Security fixes
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Feature
|
||||
git commit -m "feat: add new virtual machine creation wizard"
|
||||
|
||||
# Bug fix
|
||||
git commit -m "fix: resolve memory leak in VM console"
|
||||
|
||||
# Documentation
|
||||
git commit -m "docs: update installation instructions"
|
||||
|
||||
# Breaking change
|
||||
git commit -m "feat!: change API endpoint structure
|
||||
|
||||
BREAKING CHANGE: The /api/v1/vms endpoint has been replaced with /api/v2/vms"
|
||||
```
|
||||
|
||||
### Git Hooks
|
||||
|
||||
The project uses [Husky](https://typicode.github.io/husky/) to automatically validate commit messages and run linting before commits:
|
||||
|
||||
- **pre-commit**: Runs ESLint to ensure code quality
|
||||
- **commit-msg**: Validates commit message format using commit-lint
|
||||
|
||||
These hooks are automatically installed when you run `yarn install`.
|
||||
|
||||
### Manual Validation
|
||||
|
||||
You can manually validate commit messages:
|
||||
|
||||
```bash
|
||||
# Validate the last commit
|
||||
yarn commitlint
|
||||
|
||||
# Validate a specific commit
|
||||
npx commitlint --from <commit-hash>
|
||||
|
||||
# Validate a range of commits
|
||||
npx commitlint --from <start-hash> --to <end-hash>
|
||||
```
|
||||
|
||||
## Branch Structure
|
||||
|
||||
- **`main`** – Main development branch
|
||||
- **`release-harvester-vX.Y`** – Stable release branches per version series
|
||||
- **`vX.Y-head`** – Testing branches for ongoing changes to extension builds in each release series
|
||||
|
||||
> **Note:**
|
||||
> The `vX.Y-head` branches are auto-generated and kept in sync with release branches. Use these for testing the latest changes in each version series.
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
### UI Extension Testing
|
||||
|
||||
To validate changes in a release series, switch to the appropriate `vX.Y-head` branch. For main branch testing, use `main-head`.
|
||||
|
||||
- Examples:
|
||||
- Test `1.0.x` series → `v1.0-head`
|
||||
- Test `1.5.x` series → `v1.5-head`
|
||||
|
||||
**Steps:**
|
||||
1. Navigate to **Rancher UI** → **Local** → **App** → **Repositories**
|
||||
2. Refresh the Harvester repository using the target `vX.Y-head` branch
|
||||
3. Go to the **Extensions** page and install the desired version
|
||||
|
||||
### Standalone Mode Testing
|
||||
|
||||
To test the standalone UI, configure Harvester to load the UI from an external source.
|
||||
|
||||
- Examples of `ui-index`:
|
||||
- Main branch → `https://releases.rancher.com/harvester-ui/dashboard/latest/index.html`
|
||||
- Release series `1.5.x` → `https://releases.rancher.com/harvester-ui/dashboard/release-harvester-v1.5/index.html`
|
||||
|
||||
**Steps:**
|
||||
1. Go to **Harvester UI** → **Advanced** → **Settings** → **UI**
|
||||
2. Set **ui-source** to `External`
|
||||
3. Set **ui-index** to the desired URL
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to contribute, start by reading this document, then visit our [Getting Started guide](https://extensions.rancher.io/extensions/next/extensions-getting-started) to learn how to develop and submit changes.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014-2026 [SUSE, LLC.](https://www.suse.com/)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -77,5 +77,4 @@ export const HCI = {
|
||||
CLONE_STRATEGY: 'cdi.harvesterhci.io/storageProfileCloneStrategy',
|
||||
VOLUME_MODE_ACCESS_MODES: 'cdi.harvesterhci.io/storageProfileVolumeModeAccessModes',
|
||||
VOLUME_SNAPSHOT_CLASS: 'cdi.harvesterhci.io/storageProfileVolumeSnapshotClass',
|
||||
MAC_ADDRESS: 'harvesterhci.io/mac-address',
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col span-6 mb-20">
|
||||
<LabelValue
|
||||
:name="t('harvester.schedule.cron.label')"
|
||||
:name="t('harvester.schedule.cron')"
|
||||
:value="cronExpression"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { RadioGroup } from '@components/Form/Radio';
|
||||
import { Banner } from '@components/Banner';
|
||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
@@ -17,7 +16,6 @@ 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';
|
||||
import CronExpressionEditorModal from '@shell/components/Cron/CronExpressionEditorModal.vue';
|
||||
|
||||
export default {
|
||||
name: 'CreateVMSchedule',
|
||||
@@ -30,7 +28,6 @@ export default {
|
||||
LabeledSelect,
|
||||
MessageLink,
|
||||
Banner,
|
||||
CronExpressionEditorModal
|
||||
},
|
||||
|
||||
mixins: [CreateEditView],
|
||||
@@ -89,12 +86,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
return { settings: [], showModel: false };
|
||||
return { settings: [] };
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({ t: 'i18n/t' }),
|
||||
|
||||
backupTargetResource() {
|
||||
return this.settings.find( (O) => O.id === 'backup-target');
|
||||
},
|
||||
@@ -177,9 +172,6 @@ export default {
|
||||
this.value.spec['maxFailure'] = this.value.spec.retain;
|
||||
}
|
||||
},
|
||||
openModal() {
|
||||
this.showModel = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -264,28 +256,16 @@ export default {
|
||||
:weight="99"
|
||||
class="bordered-table"
|
||||
>
|
||||
<div class="cronEditor">
|
||||
<LabeledInput
|
||||
v-model:value="value.spec.cron"
|
||||
class="mb-30"
|
||||
type="cron"
|
||||
required
|
||||
:mode="mode"
|
||||
:label="t('harvester.schedule.cron.label')"
|
||||
placeholder="0 * * * *"
|
||||
:disabled="isBackupTargetUnAvailable || isView"
|
||||
/>
|
||||
<button
|
||||
class="editCronBtn btn role-primary"
|
||||
@click="openModal"
|
||||
>
|
||||
{{ t('harvester.schedule.cron.editButton') }}
|
||||
</button>
|
||||
<CronExpressionEditorModal
|
||||
v-model:show="showModel"
|
||||
v-model:cron-expression="value.spec.cron"
|
||||
/>
|
||||
</div>
|
||||
<LabeledInput
|
||||
v-model:value="value.spec.cron"
|
||||
class="mb-30"
|
||||
type="cron"
|
||||
required
|
||||
:mode="mode"
|
||||
:label="t('harvester.schedule.cron')"
|
||||
placeholder="0 * * * *"
|
||||
:disabled="isBackupTargetUnAvailable || isView"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value.number="value.spec.retain"
|
||||
class="mb-30"
|
||||
@@ -312,16 +292,3 @@ export default {
|
||||
</Tabbed>
|
||||
</CruResource>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cronEditor {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.editCronBtn {
|
||||
margin-bottom: 30px;
|
||||
margin-left: 10px;
|
||||
height: 60px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -254,7 +254,6 @@ export default {
|
||||
return volume;
|
||||
});
|
||||
|
||||
delete cloneVersionVM.metadata.annotations[HCI_ANNOTATIONS.MAC_ADDRESS];
|
||||
cloneVersionVM.metadata.annotations[HCI_ANNOTATIONS.VOLUME_CLAIM_TEMPLATE] = JSON.stringify(deleteDataSource);
|
||||
|
||||
// Update instance labels, labels and annotations
|
||||
|
||||
@@ -983,9 +983,7 @@ harvester:
|
||||
createTitle: Create Schedule
|
||||
createButtonText: Create Schedule
|
||||
scheduleType: Virtual Machine Schedule Type
|
||||
cron:
|
||||
label: Cron Schedule
|
||||
editButton: Edit
|
||||
cron: Cron Schedule
|
||||
detail:
|
||||
namespace: Namespace
|
||||
sourceVM: Source Virtual Machine
|
||||
|
||||
@@ -690,6 +690,7 @@ 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();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "harvester",
|
||||
"description": "Rancher UI Extension for Harvester",
|
||||
"version": "1.8.0-dev",
|
||||
"version": "1.7.0",
|
||||
"private": false,
|
||||
"rancher": {
|
||||
"annotations": {
|
||||
|
||||
@@ -3430,10 +3430,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/lodash@4.17.23":
|
||||
version "4.17.23"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.23.tgz#c1bb06db218acc8fc232da0447473fc2fb9d9841"
|
||||
integrity sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==
|
||||
"@types/lodash@4.17.21":
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.21.tgz#b806831543d696b14f8112db600ea9d3a1df6ea4"
|
||||
integrity sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==
|
||||
|
||||
"@types/mime@^1":
|
||||
version "1.3.5"
|
||||
@@ -3453,9 +3453,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@20.10.8", "@types/node@^14.14.31", "@types/node@~20.19.0":
|
||||
version "20.19.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.28.tgz#d968c492e405e4a572f5c27e4f5efc24f0eb9937"
|
||||
integrity sha512-VyKBr25BuFDzBFCK5sUM6ZXiWfqgCTwTAOK8qzGV/m9FCirXYDlmczJ+d5dXBAQALGCdRRdbteKYfJ84NGEusw==
|
||||
version "20.19.27"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.27.tgz#d51333f77953a5e4e71d3b5aefa83ec5297fbb80"
|
||||
integrity sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==
|
||||
dependencies:
|
||||
undici-types "~6.21.0"
|
||||
|
||||
@@ -11387,10 +11387,10 @@ punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
qs@6.11.0, qs@6.14.1, qs@6.7.0, qs@^6.12.3, qs@~6.10.3:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159"
|
||||
integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==
|
||||
qs@6.11.0, qs@6.14.0, qs@6.7.0, qs@^6.12.3, qs@~6.10.3:
|
||||
version "6.14.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
|
||||
integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user