mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-06 22:26:05 +08:00
Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "harvester-ui-extension",
|
"name": "harvester-ui-extension",
|
||||||
"version": "1.8.0-dev",
|
"version": "1.7.0-rc6",
|
||||||
"private": false,
|
"private": false,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"merge": "2.1.1",
|
"merge": "2.1.1",
|
||||||
"node-forge": "1.3.3",
|
"node-forge": "1.3.3",
|
||||||
"nth-check": "2.1.1",
|
"nth-check": "2.1.1",
|
||||||
"qs": "6.14.1",
|
"qs": "6.14.0",
|
||||||
"roarr": "7.21.2",
|
"roarr": "7.21.2",
|
||||||
"semver": "7.7.3",
|
"semver": "7.7.3",
|
||||||
"@vue/cli-service/html-webpack-plugin": "^5.0.0"
|
"@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-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.
|
|
||||||
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',
|
CLONE_STRATEGY: 'cdi.harvesterhci.io/storageProfileCloneStrategy',
|
||||||
VOLUME_MODE_ACCESS_MODES: 'cdi.harvesterhci.io/storageProfileVolumeModeAccessModes',
|
VOLUME_MODE_ACCESS_MODES: 'cdi.harvesterhci.io/storageProfileVolumeModeAccessModes',
|
||||||
VOLUME_SNAPSHOT_CLASS: 'cdi.harvesterhci.io/storageProfileVolumeSnapshotClass',
|
VOLUME_SNAPSHOT_CLASS: 'cdi.harvesterhci.io/storageProfileVolumeSnapshotClass',
|
||||||
MAC_ADDRESS: 'harvesterhci.io/mac-address',
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default {
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col span-6 mb-20">
|
<div class="col span-6 mb-20">
|
||||||
<LabelValue
|
<LabelValue
|
||||||
:name="t('harvester.schedule.cron.label')"
|
:name="t('harvester.schedule.cron')"
|
||||||
:value="cronExpression"
|
:value="cronExpression"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
|
||||||
import { RadioGroup } from '@components/Form/Radio';
|
import { RadioGroup } from '@components/Form/Radio';
|
||||||
import { Banner } from '@components/Banner';
|
import { Banner } from '@components/Banner';
|
||||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||||
@@ -17,7 +16,6 @@ import { sortBy } from '@shell/utils/sort';
|
|||||||
import { BACKUP_TYPE } from '../config/types';
|
import { BACKUP_TYPE } from '../config/types';
|
||||||
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
||||||
import { isBackupTargetSettingEmpty, isBackupTargetSettingUnavailable } from '../utils/setting';
|
import { isBackupTargetSettingEmpty, isBackupTargetSettingUnavailable } from '../utils/setting';
|
||||||
import CronExpressionEditorModal from '@shell/components/Cron/CronExpressionEditorModal.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreateVMSchedule',
|
name: 'CreateVMSchedule',
|
||||||
@@ -30,7 +28,6 @@ export default {
|
|||||||
LabeledSelect,
|
LabeledSelect,
|
||||||
MessageLink,
|
MessageLink,
|
||||||
Banner,
|
Banner,
|
||||||
CronExpressionEditorModal
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [CreateEditView],
|
mixins: [CreateEditView],
|
||||||
@@ -89,12 +86,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { settings: [], showModel: false };
|
return { settings: [] };
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({ t: 'i18n/t' }),
|
|
||||||
|
|
||||||
backupTargetResource() {
|
backupTargetResource() {
|
||||||
return this.settings.find( (O) => O.id === 'backup-target');
|
return this.settings.find( (O) => O.id === 'backup-target');
|
||||||
},
|
},
|
||||||
@@ -177,9 +172,6 @@ export default {
|
|||||||
this.value.spec['maxFailure'] = this.value.spec.retain;
|
this.value.spec['maxFailure'] = this.value.spec.retain;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openModal() {
|
|
||||||
this.showModel = true;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -264,28 +256,16 @@ export default {
|
|||||||
:weight="99"
|
:weight="99"
|
||||||
class="bordered-table"
|
class="bordered-table"
|
||||||
>
|
>
|
||||||
<div class="cronEditor">
|
<LabeledInput
|
||||||
<LabeledInput
|
v-model:value="value.spec.cron"
|
||||||
v-model:value="value.spec.cron"
|
class="mb-30"
|
||||||
class="mb-30"
|
type="cron"
|
||||||
type="cron"
|
required
|
||||||
required
|
:mode="mode"
|
||||||
:mode="mode"
|
:label="t('harvester.schedule.cron')"
|
||||||
:label="t('harvester.schedule.cron.label')"
|
placeholder="0 * * * *"
|
||||||
placeholder="0 * * * *"
|
:disabled="isBackupTargetUnAvailable || isView"
|
||||||
: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
|
<LabeledInput
|
||||||
v-model:value.number="value.spec.retain"
|
v-model:value.number="value.spec.retain"
|
||||||
class="mb-30"
|
class="mb-30"
|
||||||
@@ -312,16 +292,3 @@ export default {
|
|||||||
</Tabbed>
|
</Tabbed>
|
||||||
</CruResource>
|
</CruResource>
|
||||||
</template>
|
</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;
|
return volume;
|
||||||
});
|
});
|
||||||
|
|
||||||
delete cloneVersionVM.metadata.annotations[HCI_ANNOTATIONS.MAC_ADDRESS];
|
|
||||||
cloneVersionVM.metadata.annotations[HCI_ANNOTATIONS.VOLUME_CLAIM_TEMPLATE] = JSON.stringify(deleteDataSource);
|
cloneVersionVM.metadata.annotations[HCI_ANNOTATIONS.VOLUME_CLAIM_TEMPLATE] = JSON.stringify(deleteDataSource);
|
||||||
|
|
||||||
// Update instance labels, labels and annotations
|
// Update instance labels, labels and annotations
|
||||||
|
|||||||
@@ -983,9 +983,7 @@ harvester:
|
|||||||
createTitle: Create Schedule
|
createTitle: Create Schedule
|
||||||
createButtonText: Create Schedule
|
createButtonText: Create Schedule
|
||||||
scheduleType: Virtual Machine Schedule Type
|
scheduleType: Virtual Machine Schedule Type
|
||||||
cron:
|
cron: Cron Schedule
|
||||||
label: Cron Schedule
|
|
||||||
editButton: Edit
|
|
||||||
detail:
|
detail:
|
||||||
namespace: Namespace
|
namespace: Namespace
|
||||||
sourceVM: Source Virtual Machine
|
sourceVM: Source Virtual Machine
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "harvester",
|
"name": "harvester",
|
||||||
"description": "Rancher UI Extension for Harvester",
|
"description": "Rancher UI Extension for Harvester",
|
||||||
"version": "1.8.0-dev",
|
"version": "1.7.0-rc6",
|
||||||
"private": false,
|
"private": false,
|
||||||
"rancher": {
|
"rancher": {
|
||||||
"annotations": {
|
"annotations": {
|
||||||
|
|||||||
@@ -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"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
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:
|
qs@6.11.0, qs@6.14.0, qs@6.7.0, qs@^6.12.3, qs@~6.10.3:
|
||||||
version "6.14.1"
|
version "6.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
|
||||||
integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==
|
integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel "^1.1.0"
|
side-channel "^1.1.0"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user