mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-04 21:26:08 +08:00
Compare commits
49
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f03fc0805 | ||
|
|
6d4a7cd1b1 | ||
|
|
f69d445ef7 | ||
|
|
d358a0a618 | ||
|
|
47841e49b1 | ||
|
|
57c7f0f856 | ||
|
|
161adde1da | ||
|
|
28ece801d5 | ||
|
|
a8cf6f5947 | ||
|
|
28e4991bd0 | ||
|
|
0d94e66b8f | ||
|
|
871ad2e88d | ||
|
|
03d1174d8e | ||
|
|
e236ab2d5f | ||
|
|
0b6569ff64 | ||
|
|
259988f230 | ||
|
|
bbbdd1a881 | ||
|
|
83edd23ada | ||
|
|
a6f2301498 | ||
|
|
0171f70b36 | ||
|
|
578fb72cbb | ||
|
|
45773987f3 | ||
|
|
f2b98b851d | ||
|
|
42d793b50e | ||
|
|
e2474ebf8d | ||
|
|
ad37d502f7 | ||
|
|
666fe7b3b8 | ||
|
|
81f1a56434 | ||
|
|
d6bf6f1b55 | ||
|
|
2774b1c30c | ||
|
|
8b35ea1eaa | ||
|
|
e86df77224 | ||
|
|
6d0ed11057 | ||
|
|
7d17baf774 | ||
|
|
69e257d41c | ||
|
|
e5d4d0556d | ||
|
|
e2773f8c69 | ||
|
|
b7b259c699 | ||
|
|
687943ae92 | ||
|
|
4d48e75447 | ||
|
|
94429d6b64 | ||
|
|
990c06ba98 | ||
|
|
a207ec078b | ||
|
|
8d4524c4c6 | ||
|
|
f04c0c6c9b | ||
|
|
ab77b21aa8 | ||
|
|
c86b4b0466 | ||
|
|
59aec78631 | ||
|
|
e42610ca6d |
@@ -13,3 +13,4 @@ dist-pkg
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
pkg/harvester/index.ts
|
pkg/harvester/index.ts
|
||||||
pkg/harvester/store/*
|
pkg/harvester/store/*
|
||||||
|
scripts/pkgfile.js
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
pull_request_rules:
|
||||||
|
- name: Automatically open backport PR to release-harvester-v1.5
|
||||||
|
conditions:
|
||||||
|
- base=main
|
||||||
|
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}}? 🙏
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
name: Build Dashboard (Branch)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- 'release-harvester-v*'
|
||||||
|
- '*-dev'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- 'release-harvester-v*'
|
||||||
|
- '*-dev'
|
||||||
|
types:
|
||||||
|
- merged
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-validation:
|
||||||
|
name: Build Test
|
||||||
|
uses: ./.github/workflows/test.yaml
|
||||||
|
build:
|
||||||
|
name: Build and Upload Package
|
||||||
|
uses: ./.github/workflows/build-and-upload.yaml
|
||||||
|
needs:
|
||||||
|
- build-validation
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
id-token: write
|
||||||
|
with:
|
||||||
|
CI_BRANCH: ${{github.ref_name}}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
name: Build Dashboard (Release)
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v[1-9].*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-validation:
|
||||||
|
name: Build Test
|
||||||
|
uses: ./.github/workflows/test.yaml
|
||||||
|
build:
|
||||||
|
name: Build and Upload Package
|
||||||
|
uses: ./.github/workflows/build-and-upload.yaml
|
||||||
|
needs:
|
||||||
|
- build-validation
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
id-token: write
|
||||||
|
with:
|
||||||
|
CI_BUILD_TAG: ${{github.ref_name}}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
name: Build Harvester Dashboard and Upload
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
CI_BRANCH:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
CI_BUILD_TAG:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
GOOGLE_AUTH: ''
|
||||||
|
DOCKER_USERNAME: ''
|
||||||
|
DOCKER_PASSWORD: ''
|
||||||
|
CI_BUILD_TAG: ${{inputs.CI_BUILD_TAG}}
|
||||||
|
CI_BRANCH: ${{inputs.CI_BRANCH}}
|
||||||
|
GIT_REPO: ${{github.repository}}
|
||||||
|
GIT_COMMIT: ${{github.sha}}
|
||||||
|
REPO: ${{github.event.repository.name || ''}}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-upload-hosted:
|
||||||
|
name: Build & Upload Hosted
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
# Note - Cannot use the setup action here as it uses a different yarn install arg
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'yarn'
|
||||||
|
|
||||||
|
# Build a directory containing the dashboard that can be used with ui-dashboard-index
|
||||||
|
- id: build-hosted
|
||||||
|
name: Build Hosted
|
||||||
|
run: ./scripts/build-hosted
|
||||||
|
|
||||||
|
- id: upload-gate
|
||||||
|
name: Upload Gate (superseded by a newer build?)
|
||||||
|
run: ./scripts/build-upload-gate
|
||||||
|
|
||||||
|
- name: Get gcs auth
|
||||||
|
uses: rancher-eio/read-vault-secrets@main
|
||||||
|
with:
|
||||||
|
secrets: |
|
||||||
|
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||||
|
|
||||||
|
- name: Apply gcs auth
|
||||||
|
# https://github.com/google-github-actions/auth
|
||||||
|
uses: 'google-github-actions/auth@v2'
|
||||||
|
with:
|
||||||
|
credentials_json: "${{ env.GOOGLE_AUTH }}"
|
||||||
|
|
||||||
|
- name: Upload build
|
||||||
|
uses: 'google-github-actions/upload-cloud-storage@v2'
|
||||||
|
# https://github.com/google-github-actions/upload-cloud-storage
|
||||||
|
with:
|
||||||
|
path: ${{steps.build-hosted.outputs.BUILD_HOSTED_DIR}}
|
||||||
|
destination: releases.rancher.com/harvester-ui/dashboard/${{ steps.build-hosted.outputs.BUILD_HOSTED_LOCATION }}
|
||||||
|
parent: false
|
||||||
|
headers: |-
|
||||||
|
cache-control: no-cache,must-revalidate
|
||||||
|
process_gcloudignore: false
|
||||||
|
|
||||||
|
build-and-upload-embedded:
|
||||||
|
name: Build & Upload Embedded
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
# Note - Cannot use the setup action here as it uses a different yarn install arg
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'yarn'
|
||||||
|
|
||||||
|
# Build a tar that will be picked up by rancher builds and embedded into it
|
||||||
|
- id: build-embedded
|
||||||
|
name: Build Embedded
|
||||||
|
run: ./scripts/build-embedded
|
||||||
|
env:
|
||||||
|
DISABLED_EMBED_PKG: https://releases.rancher.com/harvester-ui/plugin/harvester-1.0.3.tar.gz
|
||||||
|
|
||||||
|
- name: Get gcs auth
|
||||||
|
uses: rancher-eio/read-vault-secrets@main
|
||||||
|
with:
|
||||||
|
secrets: |
|
||||||
|
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||||
|
|
||||||
|
- name: Apply gcs auth
|
||||||
|
# https://github.com/google-github-actions/auth
|
||||||
|
uses: 'google-github-actions/auth@v2'
|
||||||
|
with:
|
||||||
|
credentials_json: "${{ env.GOOGLE_AUTH }}"
|
||||||
|
|
||||||
|
- name: Upload tar
|
||||||
|
uses: 'google-github-actions/upload-cloud-storage@v2'
|
||||||
|
with:
|
||||||
|
path: ${{steps.build-embedded.outputs.BUILD_EMBEDED_TGZ}}
|
||||||
|
destination: releases.rancher.com/harvester-ui/dashboard
|
||||||
|
parent: false
|
||||||
|
headers: |-
|
||||||
|
cache-control: no-cache,must-revalidate
|
||||||
|
process_gcloudignore: false
|
||||||
|
|
||||||
|
build-and-upload-harvester-plugin:
|
||||||
|
name: Build & Upload Plugin
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
# Note - Cannot use the setup action here as it uses a different yarn install arg
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'yarn'
|
||||||
|
|
||||||
|
- id: ci-build-pkg
|
||||||
|
name: Build pkg
|
||||||
|
run: ./scripts/ci-build-pkg.sh harvester
|
||||||
|
|
||||||
|
- id: upload-gate
|
||||||
|
name: Upload Gate
|
||||||
|
run: ./scripts/build-upload-gate
|
||||||
|
|
||||||
|
- name: Get gcs auth
|
||||||
|
uses: rancher-eio/read-vault-secrets@main
|
||||||
|
with:
|
||||||
|
secrets: |
|
||||||
|
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||||
|
|
||||||
|
- name: Apply gcs auth
|
||||||
|
# https://github.com/google-github-actions/auth
|
||||||
|
uses: 'google-github-actions/auth@v2'
|
||||||
|
with:
|
||||||
|
credentials_json: "${{ env.GOOGLE_AUTH }}"
|
||||||
|
|
||||||
|
- name: Upload plugin tar
|
||||||
|
uses: 'google-github-actions/upload-cloud-storage@v2'
|
||||||
|
with:
|
||||||
|
path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_TARBALL}}
|
||||||
|
destination: releases.rancher.com/harvester-ui/plugin
|
||||||
|
parent: false
|
||||||
|
headers: |-
|
||||||
|
cache-control: no-cache,must-revalidate
|
||||||
|
process_gcloudignore: false
|
||||||
|
|
||||||
|
- name: Upload plugin directory
|
||||||
|
uses: 'google-github-actions/upload-cloud-storage@v2'
|
||||||
|
with:
|
||||||
|
path: dist-pkg/${{steps.ci-build-pkg.outputs.PKG_NAME}}
|
||||||
|
destination: releases.rancher.com/harvester-ui/plugin/${{steps.ci-build-pkg.outputs.PKG_NAME}}
|
||||||
|
parent: false
|
||||||
|
headers: |-
|
||||||
|
cache-control: no-cache,must-revalidate
|
||||||
|
process_gcloudignore: false
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
name: Tests
|
name: Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_call: # This tells GH that the workflow is reusable
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rancher/shell": "3.0.1-rc.3",
|
"@rancher/shell": "3.0.1-rc.4",
|
||||||
"cache-loader": "^4.1.0",
|
"cache-loader": "^4.1.0",
|
||||||
"color": "4.2.3",
|
"color": "4.2.3",
|
||||||
"ip": "2.0.1",
|
"ip": "2.0.1",
|
||||||
|
|||||||
@@ -192,7 +192,8 @@ export default {
|
|||||||
|
|
||||||
<div v-if="openVlan">
|
<div v-if="openVlan">
|
||||||
<LabeledInput
|
<LabeledInput
|
||||||
v-model.number="parsedDefaultValue.vlan"
|
v-model:value.number="parsedDefaultValue.vlan"
|
||||||
|
type="number"
|
||||||
class="mb-20"
|
class="mb-20"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
required
|
required
|
||||||
|
|||||||
@@ -17,12 +17,7 @@ const featuresV132 = [
|
|||||||
'improveMaintenanceMode',
|
'improveMaintenanceMode',
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: change to https://github.com/harvester/dashboard/releases/tag/v1.4.0 after v1.4.0 release
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.0
|
||||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc5
|
|
||||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc4
|
|
||||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc3
|
|
||||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc2
|
|
||||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0-rc1
|
|
||||||
const featuresV140 = [
|
const featuresV140 = [
|
||||||
...featuresV132,
|
...featuresV132,
|
||||||
'cpuPinning',
|
'cpuPinning',
|
||||||
@@ -34,9 +29,16 @@ const featuresV140 = [
|
|||||||
'improveMaintenanceMode',
|
'improveMaintenanceMode',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// TODO: add v1.4.1 official release note
|
||||||
|
// https://github.com/harvester/dashboard/releases/tag/v1.4.1-rc1
|
||||||
|
const featuresV141 = [
|
||||||
|
...featuresV140
|
||||||
|
];
|
||||||
|
|
||||||
export const RELEASE_FEATURES = {
|
export const RELEASE_FEATURES = {
|
||||||
'v1.3.0': featuresV130,
|
'v1.3.0': featuresV130,
|
||||||
'v1.3.1': featuresV131,
|
'v1.3.1': featuresV131,
|
||||||
'v1.3.2': featuresV132,
|
'v1.3.2': featuresV132,
|
||||||
'v1.4.0': featuresV140,
|
'v1.4.0': featuresV140,
|
||||||
|
'v1.4.1': featuresV141,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ export default {
|
|||||||
if (this.isCreate) {
|
if (this.isCreate) {
|
||||||
this.value.metadata.namespace = 'default';
|
this.value.metadata.namespace = 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
set(this.value, 'spec', this.value.spec || {});
|
set(this.value, 'spec', this.value.spec || {});
|
||||||
|
|
||||||
const providers = PROVIDERS.map((provider) => ({
|
const providers = PROVIDERS.map((provider) => ({
|
||||||
@@ -83,14 +82,6 @@ export default {
|
|||||||
label: this.t(provider.labelKey)
|
label: this.t(provider.labelKey)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (this.mode !== _VIEW) {
|
|
||||||
this.value['spec'] = this.value.spec || {};
|
|
||||||
|
|
||||||
providers.forEach((provider) => {
|
|
||||||
this.value.spec[provider.name] = this.value.spec[provider.name] || clone(provider.default);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedProviders = providers.filter((provider) => {
|
const selectedProviders = providers.filter((provider) => {
|
||||||
const specProvider = this.value.spec[provider.name];
|
const specProvider = this.value.spec[provider.name];
|
||||||
const correctedSpecProvider = provider.name === 'forward' ? specProvider?.servers?.[0] || {} : specProvider;
|
const correctedSpecProvider = provider.name === 'forward' ? specProvider?.servers?.[0] || {} : specProvider;
|
||||||
@@ -98,7 +89,12 @@ export default {
|
|||||||
return !isEmpty(correctedSpecProvider) && !isEqual(correctedSpecProvider, provider.default);
|
return !isEmpty(correctedSpecProvider) && !isEqual(correctedSpecProvider, provider.default);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedProvider = selectedProviders?.[0]?.value || providers[0].value;
|
const selectedProvider = selectedProviders?.[0]?.value || providers[0].value; // selected provider name
|
||||||
|
const selectedProviderDefault = providers.find((p) => p.name === selectedProvider)?.default || providers[0].default;
|
||||||
|
|
||||||
|
if (this.mode !== _VIEW) {
|
||||||
|
this.$set(this.value.spec, selectedProvider, this.value.spec[selectedProvider] || clone(selectedProviderDefault));
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bufferYaml: '',
|
bufferYaml: '',
|
||||||
@@ -129,6 +125,18 @@ export default {
|
|||||||
outputTypeOptions() {
|
outputTypeOptions() {
|
||||||
return OUTPUT_TYPE;
|
return OUTPUT_TYPE;
|
||||||
},
|
},
|
||||||
|
outputProvider: {
|
||||||
|
get() {
|
||||||
|
return this.selectedProvider;
|
||||||
|
},
|
||||||
|
|
||||||
|
set(newProvider) {
|
||||||
|
this.selectedProvider = newProvider;
|
||||||
|
const providerDefaultSpec = this.providers.find((p) => p.name === newProvider)?.default || {};
|
||||||
|
|
||||||
|
this.value.spec = { [newProvider]: this.value.spec[newProvider] || clone(providerDefaultSpec) };
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
@@ -142,8 +150,6 @@ export default {
|
|||||||
this.$refs.tabbed.select(provider.name);
|
this.$refs.tabbed.select(provider.name);
|
||||||
},
|
},
|
||||||
willSave() {
|
willSave() {
|
||||||
this.value.spec = { [this.selectedProvider]: this.value.spec[this.selectedProvider] };
|
|
||||||
|
|
||||||
const bufferJson = jsyaml.load(this.bufferYaml);
|
const bufferJson = jsyaml.load(this.bufferYaml);
|
||||||
|
|
||||||
if (!isEmpty(bufferJson)) {
|
if (!isEmpty(bufferJson)) {
|
||||||
@@ -236,7 +242,7 @@ export default {
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<LabeledSelect
|
<LabeledSelect
|
||||||
v-model:value="selectedProvider"
|
v-model:value="outputProvider"
|
||||||
label="Output"
|
label="Output"
|
||||||
:options="providers"
|
:options="providers"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
|
|||||||
@@ -10,17 +10,6 @@ import { clone } from '@shell/utils/object';
|
|||||||
import { uniq } from '@shell/utils/array';
|
import { uniq } from '@shell/utils/array';
|
||||||
import { DATA_ENGINE_V1 } from '../../../models/harvester/persistentvolumeclaim';
|
import { DATA_ENGINE_V1 } from '../../../models/harvester/persistentvolumeclaim';
|
||||||
|
|
||||||
// UI components for Longhorn storage class parameters
|
|
||||||
const DEFAULT_PARAMETERS = [
|
|
||||||
'numberOfReplicas',
|
|
||||||
'staleReplicaTimeout',
|
|
||||||
'diskSelector',
|
|
||||||
'nodeSelector',
|
|
||||||
'migratable',
|
|
||||||
'encrypted',
|
|
||||||
'dataEngine',
|
|
||||||
];
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
CSI_PROVISIONER_SECRET_NAME,
|
CSI_PROVISIONER_SECRET_NAME,
|
||||||
CSI_PROVISIONER_SECRET_NAMESPACE,
|
CSI_PROVISIONER_SECRET_NAMESPACE,
|
||||||
@@ -141,11 +130,17 @@ export default {
|
|||||||
get() {
|
get() {
|
||||||
const parameters = clone(this.value?.parameters) || {};
|
const parameters = clone(this.value?.parameters) || {};
|
||||||
|
|
||||||
DEFAULT_PARAMETERS.forEach((key) => {
|
// UI components for Longhorn storage class parameters
|
||||||
delete parameters[key];
|
const defaultParameters = [
|
||||||
});
|
'numberOfReplicas',
|
||||||
|
'staleReplicaTimeout',
|
||||||
|
'diskSelector',
|
||||||
|
'nodeSelector',
|
||||||
|
'migratable',
|
||||||
|
...(this.value.volumeEncryptionFeatureEnabled ? ['encrypted', 'dataEngine'] : []),
|
||||||
|
];
|
||||||
|
|
||||||
Object.values(CSI_SECRETS).forEach((key) => {
|
[...defaultParameters, ...Object.values(CSI_SECRETS)].forEach((key) => {
|
||||||
delete parameters[key];
|
delete parameters[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -311,16 +306,16 @@ export default {
|
|||||||
</LabeledSelect>
|
</LabeledSelect>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mt-20">
|
||||||
|
<RadioGroup
|
||||||
|
v-model:value="value.parameters.migratable"
|
||||||
|
name="layer3NetworkMode"
|
||||||
|
:label="t('harvester.storage.parameters.migratable.label')"
|
||||||
|
:mode="mode"
|
||||||
|
:options="migratableOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<template v-if="value.volumeEncryptionFeatureEnabled">
|
<template v-if="value.volumeEncryptionFeatureEnabled">
|
||||||
<div class="row mt-20">
|
|
||||||
<RadioGroup
|
|
||||||
v-model:value="value.parameters.migratable"
|
|
||||||
name="layer3NetworkMode"
|
|
||||||
:label="t('harvester.storage.parameters.migratable.label')"
|
|
||||||
:mode="mode"
|
|
||||||
:options="migratableOptions"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="row mt-20">
|
<div class="row mt-20">
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
v-model:value="volumeEncryption"
|
v-model:value="volumeEncryption"
|
||||||
|
|||||||
@@ -245,6 +245,8 @@ export default {
|
|||||||
async saveImage(buttonCb) {
|
async saveImage(buttonCb) {
|
||||||
this.value.spec.displayName = (this.value.spec.displayName || '').trim();
|
this.value.spec.displayName = (this.value.spec.displayName || '').trim();
|
||||||
|
|
||||||
|
if (this.isEdit) return await this.handleEditImage(buttonCb);
|
||||||
|
|
||||||
if (this.value.spec.sourceType === UPLOAD && this.isCreate) {
|
if (this.value.spec.sourceType === UPLOAD && this.isCreate) {
|
||||||
try {
|
try {
|
||||||
this.value.spec.url = '';
|
this.value.spec.url = '';
|
||||||
@@ -269,6 +271,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async handleEditImage(buttonCb) {
|
||||||
|
try {
|
||||||
|
const data = [{
|
||||||
|
op: 'replace', path: '/metadata/labels', value: this.value.metadata.labels
|
||||||
|
}, {
|
||||||
|
op: 'replace', path: '/metadata/annotations', value: this.value.metadata.annotations
|
||||||
|
}];
|
||||||
|
|
||||||
|
await this.value.patch(data);
|
||||||
|
buttonCb(true);
|
||||||
|
this.done();
|
||||||
|
} catch (e) {
|
||||||
|
this.errors = exceptionToErrorsArray(e);
|
||||||
|
buttonCb(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setImageLabels(str) {
|
setImageLabels(str) {
|
||||||
const suffixName = str?.split('/')?.pop() || str;
|
const suffixName = str?.split('/')?.pop() || str;
|
||||||
|
|
||||||
@@ -530,6 +549,7 @@ export default {
|
|||||||
:mode="mode"
|
:mode="mode"
|
||||||
:pad-left="false"
|
:pad-left="false"
|
||||||
:read-allowed="false"
|
:read-allowed="false"
|
||||||
|
:value-can-be-empty="true"
|
||||||
@focusKey="focusKey"
|
@focusKey="focusKey"
|
||||||
@update:value="value.setLabels($event)"
|
@update:value="value.setLabels($event)"
|
||||||
>
|
>
|
||||||
@@ -552,7 +572,7 @@ export default {
|
|||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@update:value="queueUpdate"
|
@input="queueUpdate"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</KeyValue>
|
</KeyValue>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import SSHKey from './kubevirt.io.virtualmachine/VirtualMachineSSHKey';
|
|||||||
export default {
|
export default {
|
||||||
name: 'HarvesterEditVMTemplate',
|
name: 'HarvesterEditVMTemplate',
|
||||||
|
|
||||||
emits: ['update:value'],
|
emits: ['update:templateValue'],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Tab,
|
Tab,
|
||||||
@@ -205,7 +205,7 @@ export default {
|
|||||||
if (tab.name === 'advanced') {
|
if (tab.name === 'advanced') {
|
||||||
this.$refs.yamlEditor?.refresh();
|
this.$refs.yamlEditor?.refresh();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -222,11 +222,11 @@ export default {
|
|||||||
@finish="saveVMT"
|
@finish="saveVMT"
|
||||||
>
|
>
|
||||||
<NameNsDescription
|
<NameNsDescription
|
||||||
:value="value"
|
:value="templateValue"
|
||||||
:mode="realTemplateMode"
|
:mode="realTemplateMode"
|
||||||
name-label="harvester.vmTemplate.nameNsDescription.name"
|
name-label="harvester.vmTemplate.nameNsDescription.name"
|
||||||
:namespaced="true"
|
:namespaced="true"
|
||||||
@update:value="$emit('update:value', $event)"
|
@update:value="$emit('update:templateValue', $event)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
+5
-1
@@ -95,7 +95,11 @@ export default {
|
|||||||
devices: {
|
devices: {
|
||||||
handler(v) {
|
handler(v) {
|
||||||
this.rows = v;
|
this.rows = v;
|
||||||
this.filterRows = this.rows;
|
if (this.parentSriov) {
|
||||||
|
this.filterRows = this.rows.filter((row) => row.labels[this.parentSriovLabel] === this.parentSriov);
|
||||||
|
} else {
|
||||||
|
this.filterRows = this.rows;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -72,17 +72,23 @@ export default {
|
|||||||
return stats;
|
return stats;
|
||||||
},
|
},
|
||||||
|
|
||||||
units() {
|
allocatedUnits() {
|
||||||
|
const exponent = exponentNeeded(this.storageStats.total, 1024);
|
||||||
|
|
||||||
|
return `${ UNITS[exponent] }iB`;
|
||||||
|
},
|
||||||
|
|
||||||
|
usedUnits() {
|
||||||
const exponent = exponentNeeded(this.storageStats.maximum, 1024);
|
const exponent = exponentNeeded(this.storageStats.maximum, 1024);
|
||||||
|
|
||||||
return `${ UNITS[exponent] }iB`;
|
return `${ UNITS[exponent] }iB`;
|
||||||
},
|
},
|
||||||
|
|
||||||
used() {
|
formatUsed() {
|
||||||
let out = this.formatter(this.storageStats.used);
|
let out = this.formatter(this.storageStats.used);
|
||||||
|
|
||||||
if (!Number.parseFloat(out) > 0) {
|
if (!Number.parseFloat(out) > 0) {
|
||||||
out = this.formatter(this.storageStats.used, { canRoundToZero: false });
|
out = this.formatter(this.storageStats.used, { canRoundToZero: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -92,7 +98,7 @@ export default {
|
|||||||
let out = this.formatter(this.storageStats.scheduled);
|
let out = this.formatter(this.storageStats.scheduled);
|
||||||
|
|
||||||
if (!Number.parseFloat(out) > 0) {
|
if (!Number.parseFloat(out) > 0) {
|
||||||
out = this.formatter(this.storageStats.scheduled, { canRoundToZero: false });
|
out = this.formatter(this.storageStats.scheduled, { canRoundToZero: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -100,9 +106,9 @@ export default {
|
|||||||
|
|
||||||
usedAmountTemplateValues() {
|
usedAmountTemplateValues() {
|
||||||
return {
|
return {
|
||||||
used: this.used,
|
used: this.formatUsed,
|
||||||
total: this.formatter(this.storageStats.maximum),
|
total: this.formatter(this.storageStats.maximum),
|
||||||
unit: this.units,
|
unit: this.usedUnits,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -110,7 +116,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
used: this.formatAllocated,
|
used: this.formatAllocated,
|
||||||
total: this.formatter(this.storageStats.total),
|
total: this.formatter(this.storageStats.total),
|
||||||
unit: this.units,
|
unit: this.allocatedUnits,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -141,7 +147,7 @@ export default {
|
|||||||
<ConsumptionGauge
|
<ConsumptionGauge
|
||||||
:capacity="storageStats.total"
|
:capacity="storageStats.total"
|
||||||
:used="storageStats.scheduled"
|
:used="storageStats.scheduled"
|
||||||
:units="units"
|
:units="allocatedUnits"
|
||||||
:number-formatter="formatter"
|
:number-formatter="formatter"
|
||||||
:resource-name="resourceName"
|
:resource-name="resourceName"
|
||||||
>
|
>
|
||||||
@@ -161,7 +167,7 @@ export default {
|
|||||||
<ConsumptionGauge
|
<ConsumptionGauge
|
||||||
:capacity="storageStats.maximum"
|
:capacity="storageStats.maximum"
|
||||||
:used="storageStats.used"
|
:used="storageStats.used"
|
||||||
:units="units"
|
:units="usedUnits"
|
||||||
:number-formatter="formatter"
|
:number-formatter="formatter"
|
||||||
:resource-name="showAllocated ? '' : resourceName"
|
:resource-name="showAllocated ? '' : resourceName"
|
||||||
:class="{
|
:class="{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "harvester",
|
"name": "harvester",
|
||||||
"description": "Rancher UI Extension for Harvester",
|
"description": "Rancher UI Extension for Harvester",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"rancher": {
|
"rancher": {
|
||||||
"annotations": {
|
"annotations": {
|
||||||
|
|||||||
@@ -14,16 +14,35 @@ export function getVersion(v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// v1.4.1-rc.1 => v1.4.1, v1.4.1-dev-20241222 => v1.4.1
|
||||||
return `v${ semver.major(v) }.${ semver.minor(v) }.${ semver.patch(v) }`;
|
return `v${ semver.major(v) }.${ semver.minor(v) }.${ semver.patch(v) }`;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// fallback to the latest version
|
// fallback to the latest version
|
||||||
return Object.keys(RELEASE_FEATURES).sort((a, b) => semver.compare(a, b)).pop();
|
return latestVersion(Object.keys(RELEASE_FEATURES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function latestVersion(versions) {
|
||||||
|
return versions.sort((a, b) => semver.compare(a, b)).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// v1.3.3 => latest v1.3.x, v1.4.2 => latest v1.4.x
|
||||||
|
function latestMinorVersion(v) {
|
||||||
|
const minor = `v${ semver.major(v) }.${ semver.minor(v) }`;
|
||||||
|
const minorVersions = Object.keys(RELEASE_FEATURES).filter((version) => version.startsWith(minor));
|
||||||
|
|
||||||
|
return latestVersion(minorVersions);
|
||||||
|
}
|
||||||
|
|
||||||
export const featureEnabled = (featureKey, serverVersion) => {
|
export const featureEnabled = (featureKey, serverVersion) => {
|
||||||
const version = getVersion(serverVersion);
|
const version = getVersion(serverVersion);
|
||||||
const releasedFeatures = RELEASE_FEATURES[version] || [];
|
let releasedFeatures = RELEASE_FEATURES[version];
|
||||||
|
|
||||||
|
if (!releasedFeatures) {
|
||||||
|
const fallback = latestMinorVersion(version);
|
||||||
|
|
||||||
|
releasedFeatures = RELEASE_FEATURES[fallback];
|
||||||
|
}
|
||||||
|
|
||||||
return releasedFeatures.includes(featureKey);
|
return releasedFeatures.includes(featureKey);
|
||||||
};
|
};
|
||||||
|
|||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
BUILD_DEBUG="${BUILD_DEBUG:-}"
|
||||||
|
if [[ -n "${BUILD_DEBUG}" ]]; then
|
||||||
|
set -x
|
||||||
|
env
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
|
echo "Bootstrapping..."
|
||||||
|
yarn --pure-lockfile install
|
||||||
|
|
||||||
|
source scripts/version
|
||||||
|
echo "BRANCH: ${COMMIT_BRANCH:-<none>}"
|
||||||
|
echo "TAG: ${GIT_TAG:-<none>}"
|
||||||
|
DIR=${GIT_TAG:-$COMMIT_BRANCH}
|
||||||
|
|
||||||
|
if [[ "${DIR}" == "main" ]]; then
|
||||||
|
DIR="latest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
OUTPUT_DIR=dist/${DIR}-embedded
|
||||||
|
|
||||||
|
echo "Building..."
|
||||||
|
COMMIT=${COMMIT} VERSION=${VERSION} OUTPUT_DIR=$OUTPUT_DIR ROUTER_BASE='/dashboard/' RESOURCE_BASE='/dashboard/' RANCHER_ENV=harvester yarn run build
|
||||||
|
|
||||||
|
if [ -v EMBED_PKG ]; then
|
||||||
|
echo "Build and embed plugin from: $EMBED_PKG"
|
||||||
|
PKG_FILE_NAME=${EMBED_PKG##*/}
|
||||||
|
echo PKG_FILE_NAME: $PKG_FILE_NAME
|
||||||
|
|
||||||
|
PKG_NAME="${PKG_FILE_NAME/.tar.gz/""}"
|
||||||
|
echo "Plugin name: '$PKG_NAME'"
|
||||||
|
|
||||||
|
# Fetch file, unpack and move to dist
|
||||||
|
curl $EMBED_PKG --output $PKG_FILE_NAME
|
||||||
|
OUTPUT_DIR_PKG=$OUTPUT_DIR/$PKG_NAME
|
||||||
|
mkdir -p $OUTPUT_DIR_PKG
|
||||||
|
tar xvfz $PKG_FILE_NAME -C $OUTPUT_DIR/$PKG_NAME
|
||||||
|
echo "Plugin contents that will be served from $PKG_NAME"
|
||||||
|
ls -alR $OUTPUT_DIR/$PKG_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Destroying..."
|
||||||
|
find $OUTPUT_DIR -name "index.html" -mindepth 2 -exec rm {} \;
|
||||||
|
find $OUTPUT_DIR -type d -empty -depth -exec rmdir {} \;
|
||||||
|
|
||||||
|
TARBALL=${DIR}.tar.gz
|
||||||
|
TARBALL_FILE_PATH=dist/${TARBALL}
|
||||||
|
|
||||||
|
ENV_OUTPUT="${GITHUB_OUTPUT:-"temp-env"}"
|
||||||
|
echo "BUILD_EMBEDED_TGZ=${TARBALL_FILE_PATH}" >> "$ENV_OUTPUT"
|
||||||
|
|
||||||
|
echo "Compressing to ${TARBALL}..."
|
||||||
|
tar -czf ${TARBALL_FILE_PATH} $OUTPUT_DIR/
|
||||||
|
|
||||||
|
echo "Cleaning up..."
|
||||||
|
rm -r $OUTPUT_DIR
|
||||||
|
|
||||||
|
ls -alR dist/
|
||||||
Executable
+34
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DEBUG="${BUILD_DEBUG:-}"
|
||||||
|
if [[ -n "${BUILD_DEBUG}" ]]; then
|
||||||
|
set -x
|
||||||
|
env
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
|
echo "Bootstrapping..."
|
||||||
|
yarn --pure-lockfile install
|
||||||
|
|
||||||
|
source scripts/version
|
||||||
|
echo "BRANCH: ${COMMIT_BRANCH:-<none>}"
|
||||||
|
echo "TAG: ${GIT_TAG:-<none>}"
|
||||||
|
DIR=${GIT_TAG:-$COMMIT_BRANCH}
|
||||||
|
|
||||||
|
if [[ "${DIR}" == "main" ]]; then
|
||||||
|
DIR="latest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
BASE=${BASE:-https://releases.rancher.com/harvester-ui/dashboard/${DIR}}
|
||||||
|
|
||||||
|
echo "Building for ${BASE}..."
|
||||||
|
|
||||||
|
OUTPUT_DIR=dist/${DIR}
|
||||||
|
|
||||||
|
ENV_OUTPUT="${GITHUB_OUTPUT:-"temp-env"}"
|
||||||
|
echo "BUILD_HOSTED_DIR=${OUTPUT_DIR}" >> "$ENV_OUTPUT"
|
||||||
|
echo "BUILD_HOSTED_LOCATION=${DIR}" >> "$ENV_OUTPUT"
|
||||||
|
|
||||||
|
COMMIT=${COMMIT} VERSION=${VERSION} OUTPUT_DIR=${OUTPUT_DIR} ROUTER_BASE="/dashboard/" RESOURCE_BASE="${BASE}" RANCHER_ENV=harvester yarn run build
|
||||||
Executable
+102
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
BASE_DIR="$( cd $SCRIPT_DIR && cd ../.. & pwd)"
|
||||||
|
SHELL_DIR=$BASE_DIR/shell/
|
||||||
|
EXIT_CODE=0
|
||||||
|
FORMATS="umd-min"
|
||||||
|
|
||||||
|
while getopts "df:" opt; do
|
||||||
|
case $opt in
|
||||||
|
d)
|
||||||
|
FORMATS="umd"
|
||||||
|
;;
|
||||||
|
f)
|
||||||
|
FORMATS=$OPTARG
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
# Use shell folder in node modules when we have @rancher/shell installed as a node module
|
||||||
|
# rather than the use-case of the mono-repo with the shell folder at the top-level
|
||||||
|
if [ ! -d ${SHELL_DIR} ]; then
|
||||||
|
SHELL_DIR=$BASE_DIR/node_modules/@rancher/shell/
|
||||||
|
SHELL_DIR=$(cd -P ${SHELL_DIR} && pwd)
|
||||||
|
fi
|
||||||
|
|
||||||
|
CREATE_TARBALL=${2}
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
VERSION=$(cd pkg/$1; node -p -e "require('./package.json').version")
|
||||||
|
fi
|
||||||
|
|
||||||
|
NAME=${1}-${VERSION}
|
||||||
|
PKG_DIST=${BASE_DIR}/dist-pkg/${NAME}
|
||||||
|
|
||||||
|
if [ -d "${BASE_DIR}/pkg/${1}" ]; then
|
||||||
|
echo "Building UI Package $1"
|
||||||
|
echo " Package name: ${NAME}"
|
||||||
|
echo " Package version: ${VERSION}"
|
||||||
|
echo " Output formats: ${FORMATS}"
|
||||||
|
echo " Output directory: ${PKG_DIST}"
|
||||||
|
rm -rf ${PKG_DIST}
|
||||||
|
mkdir -p ${PKG_DIST}
|
||||||
|
|
||||||
|
pushd pkg/${1}
|
||||||
|
|
||||||
|
# Check that the .shell link exists and points to the correct place
|
||||||
|
if [ -e ".shell" ]; then
|
||||||
|
LINK=$(readlink .shell)
|
||||||
|
if [ "${LINK}" != "${SHELL_DIR}" ]; then
|
||||||
|
echo ".shell symlink exists but does not point to expected location - please check and fix"
|
||||||
|
popd
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ln -s ${SHELL_DIR} .shell
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE=index.js
|
||||||
|
if [ -f ./index.ts ]; then
|
||||||
|
FILE=index.ts
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$COMMIT" ]; then
|
||||||
|
echo ${COMMIT} > ${PKG_DIST}/version
|
||||||
|
fi
|
||||||
|
|
||||||
|
${BASE_DIR}/node_modules/.bin/vue-cli-service build --name ${NAME} --target lib ${FILE} --dest ${PKG_DIST} --formats ${FORMATS} --filename ${NAME}
|
||||||
|
EXIT_CODE=$?
|
||||||
|
cp -f ./package.json ${PKG_DIST}/package.json
|
||||||
|
node ${SCRIPT_DIR}/pkgfile.js ${PKG_DIST}/package.json
|
||||||
|
rm -rf ${PKG_DIST}/*.bak
|
||||||
|
rm .shell
|
||||||
|
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $EXIT_CODE -ne 0 ]; then
|
||||||
|
exit $EXIT_CODE
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "${CREATE_TARBALL}" ]; then
|
||||||
|
echo $COMMIT $COMMIT_BRANCH > ${PKG_DIST}/version-commit.txt
|
||||||
|
|
||||||
|
TARBALL=${NAME}.tar.gz
|
||||||
|
|
||||||
|
pushd ${PKG_DIST}
|
||||||
|
|
||||||
|
rm -f ../$TARBALL
|
||||||
|
|
||||||
|
echo "Compressing to ${TARBALL}..."
|
||||||
|
|
||||||
|
tar -czf ../${TARBALL} .
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
|
BUILD_DEBUG="${BUILD_DEBUG:-}"
|
||||||
|
if [[ -n "${BUILD_DEBUG}" ]]; then
|
||||||
|
set -x
|
||||||
|
env
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$CI_BUILD_TAG" ]]; then
|
||||||
|
echo "Build has been triggered by a tag. Skipping gate"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$CI_BRANCH" ]]; then
|
||||||
|
echo "No branch detected. Skipping gate"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$GIT_REPO" ]]; then
|
||||||
|
echo "No repository detected. Unable to gate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$GIT_COMMIT" ]]; then
|
||||||
|
echo "No commit detected. Unable to gate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Repo: $GIT_REPO"
|
||||||
|
echo "Branch: $CI_BRANCH"
|
||||||
|
echo "Build Commit: $GIT_COMMIT"
|
||||||
|
|
||||||
|
tmp=$(mktemp -u)
|
||||||
|
STATUS_CODE=$(curl -w "%{http_code}" -s -o $tmp https://api.github.com/repos/$GIT_REPO/branches/$CI_BRANCH)
|
||||||
|
|
||||||
|
if [ "$STATUS_CODE" == "403" ]; then
|
||||||
|
RATE_LIMIT_REMAINING=$(curl -s https://api.github.com/rate_limit | ./scripts/jq-nano - rate remaining)
|
||||||
|
echo "Remaining GITHUB requests available: $RATE_LIMIT_REMAINING"
|
||||||
|
RATE_LIMIT_REMAINING=${RATE_LIMIT_REMAINING:-0}
|
||||||
|
if ((RATE_LIMIT_REMAINING < 1)); then
|
||||||
|
echo "Github Rate Limit has been hit, skipping gate"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
# Fall through to the normal path like any other failed status code
|
||||||
|
fi
|
||||||
|
|
||||||
|
LATEST_BRANCH_COMMIT=$(cat $tmp | ./scripts/jq-nano - commit sha)
|
||||||
|
rm $tmp
|
||||||
|
echo "Latest Branch Commit: $LATEST_BRANCH_COMMIT"
|
||||||
|
if [ -z "$LATEST_BRANCH_COMMIT" ]; then
|
||||||
|
echo "Unable to determine latest commit, failing gate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$LATEST_BRANCH_COMMIT" == "$GIT_COMMIT" ]; then
|
||||||
|
echo "Build was created from latest commit, passed upload gate"
|
||||||
|
else
|
||||||
|
echo "Build was not created from latest commit, failing gate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
yarn --pure-lockfile install
|
||||||
|
|
||||||
|
source scripts/version
|
||||||
|
|
||||||
|
if [[ $COMMIT_BRANCH == "main" ]]; then
|
||||||
|
VERSION="latest"
|
||||||
|
else
|
||||||
|
VERSION=$COMMIT_BRANCH
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "CI_BUILD_TAG: ${CI_BUILD_TAG}"
|
||||||
|
echo "GIT_TAG: ${GIT_TAG}"
|
||||||
|
echo "TAG_VERSION: ${TAG_VERSION}"
|
||||||
|
|
||||||
|
echo "CI Build Args"
|
||||||
|
echo "COMMIT: ${COMMIT}"
|
||||||
|
echo "COMMIT_BRANCH: ${COMMIT_BRANCH}"
|
||||||
|
echo "VERSION: ${VERSION}"
|
||||||
|
|
||||||
|
if [ -n "$GIT_TAG" ]; then
|
||||||
|
COMMIT=$COMMIT COMMIT_BRANCH=$COMMIT_BRANCH VERSION=$CI_BUILD_TAG ./scripts/build-pkg.sh ${1} "true"
|
||||||
|
else
|
||||||
|
COMMIT=$COMMIT COMMIT_BRANCH=$COMMIT_BRANCH VERSION=$VERSION ./scripts/build-pkg.sh ${1} "true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
|
if [ -n "$GIT_TAG" ]; then
|
||||||
|
export PKG_NAME=${1}-${CI_BUILD_TAG}
|
||||||
|
export PKG_TARBALL=${PKG_NAME}.tar.gz
|
||||||
|
else
|
||||||
|
export PKG_NAME=${1}-${VERSION} # harvester-release-harvester-v1.5 or harvester-latest
|
||||||
|
export PKG_TARBALL=${PKG_NAME}.tar.gz # harvester-release-harvester-v1.5.tar.gz or harvester-latest.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "CI Build Artifacts"
|
||||||
|
echo "Package Directory: ${PKG_NAME}"
|
||||||
|
echo "Package Tarball: ${PKG_TARBALL}"
|
||||||
|
|
||||||
|
ENV_OUTPUT="${GITHUB_OUTPUT:-"temp-env"}"
|
||||||
|
echo "PKG_TARBALL=${PKG_TARBALL}" >> "$ENV_OUTPUT"
|
||||||
|
echo "PKG_NAME=${PKG_NAME}" >> "$ENV_OUTPUT"
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const readline = require('readline');
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const file = args.shift();
|
||||||
|
|
||||||
|
let text;
|
||||||
|
|
||||||
|
if ( file === '-' ) {
|
||||||
|
process.stdin.resume();
|
||||||
|
text = fs.readFileSync(0, "utf8");
|
||||||
|
} else {
|
||||||
|
text = fs.readFileSync(file, "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(text);
|
||||||
|
|
||||||
|
let out = data;
|
||||||
|
while ( args.length ) {
|
||||||
|
out = out[args.shift()];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(out);
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
console.log('Updating package file'); // eslint-disable-line no-console
|
||||||
|
|
||||||
|
if (process.argv.length !== 3) {
|
||||||
|
console.error('No enough args'); // eslint-disable-line no-console
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pkgFilepath = process.argv[process.argv.length - 1];
|
||||||
|
const pkg = require(pkgFilepath);
|
||||||
|
|
||||||
|
// Ensure we have the keys we need
|
||||||
|
|
||||||
|
pkg.files = ['**/*'];
|
||||||
|
pkg.rancher = true;
|
||||||
|
pkg.main = `${ pkg.name }-${ pkg.version }.umd.min.js`;
|
||||||
|
|
||||||
|
delete pkg.scripts;
|
||||||
|
delete pkg.browserslist;
|
||||||
|
|
||||||
|
|
||||||
|
fs.writeFileSync(pkgFilepath, JSON.stringify(pkg, null, 2));
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
shopt -s extglob
|
||||||
|
|
||||||
|
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
||||||
|
DIRTY="-dirty"
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMMIT=$(git rev-parse --short HEAD)
|
||||||
|
COMMIT_DATE=$(git --no-pager log -1 --format='%ct')
|
||||||
|
COMMIT_BRANCH=$(git rev-parse --abbrev-ref HEAD | sed -E 's/[^a-zA-Z0-9.-]+/-/g')
|
||||||
|
GIT_TAG=${CI_BUILD_TAG:-$(git tag -l --contains HEAD | head -n 1)}
|
||||||
|
LAST_TAG=${GIT_TAG:-'v0.0.0'}
|
||||||
|
|
||||||
|
if [[ -z "$DIRTY" && -n "$GIT_TAG" ]]; then
|
||||||
|
# human readable version used on rancher dashboard about page
|
||||||
|
export DASHBOARD_VERSION=$GIT_TAG
|
||||||
|
# computer readable version
|
||||||
|
VERSION=$GIT_TAG
|
||||||
|
else
|
||||||
|
# human readable version used on rancher dashboard about page
|
||||||
|
export DASHBOARD_VERSION="${COMMIT_BRANCH} ${COMMIT}"
|
||||||
|
# computer readable version
|
||||||
|
VERSION="${COMMIT}${DIRTY}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Chart tag.
|
||||||
|
if [[ -z "${DIRTY}" && -n "${GIT_TAG}" ]]; then
|
||||||
|
CHART_VERSION="${GIT_TAG}"
|
||||||
|
elif [[ "$DIRTY" ]]; then
|
||||||
|
CHART_VERSION="${LAST_TAG}${DIRTY}.${COMMIT}"
|
||||||
|
else
|
||||||
|
CHART_VERSION="${LAST_TAG}-${COMMIT_DATE}.${COMMIT}.${COMMIT_BRANCH}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Drop the v prefix for Chart Version to follow existing pattern.
|
||||||
|
CHART_VERSION="$(echo ${CHART_VERSION} | sed -E 's/^v//' | sed -e 's/^\(.\{55\}\).*/\1/')"
|
||||||
|
|
||||||
|
# Chart Repo - Target Repo for releases.
|
||||||
|
case $CHART_VERSION in
|
||||||
|
*-alpha*) # All alpha tags
|
||||||
|
CHART_REPO="alpha" ;;
|
||||||
|
*-rc*) # All rc tags
|
||||||
|
CHART_REPO="latest" ;;
|
||||||
|
+([0-9]).+([0-9]).+([0-9])) # All release tags
|
||||||
|
CHART_REPO="latest" ;;
|
||||||
|
*) # Anything else - Future use
|
||||||
|
CHART_REPO="dev" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$ARCH" ]; then
|
||||||
|
ARCH=amd64
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ARCH: $ARCH"
|
||||||
|
echo "CHART_REPO: $CHART_REPO"
|
||||||
|
echo "CHART_VERSION: $CHART_VERSION"
|
||||||
|
echo "VERSION: $VERSION"
|
||||||
@@ -2940,10 +2940,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@rancher/icons/-/icons-2.0.29.tgz#6546d69768c706bebd66bfa73b36aef3d105987a"
|
resolved "https://registry.yarnpkg.com/@rancher/icons/-/icons-2.0.29.tgz#6546d69768c706bebd66bfa73b36aef3d105987a"
|
||||||
integrity sha512-qBBqfazS9y5VjV7fJDPNXmxd9AP/2uiE05mKFWP41kpbO+tEb62RnUBXCm14XLeScDZQcOuiAKVHMmvCFzF0BA==
|
integrity sha512-qBBqfazS9y5VjV7fJDPNXmxd9AP/2uiE05mKFWP41kpbO+tEb62RnUBXCm14XLeScDZQcOuiAKVHMmvCFzF0BA==
|
||||||
|
|
||||||
"@rancher/shell@3.0.1-rc.3":
|
"@rancher/shell@3.0.1-rc.4":
|
||||||
version "3.0.1-rc.3"
|
version "3.0.1-rc.4"
|
||||||
resolved "https://registry.yarnpkg.com/@rancher/shell/-/shell-3.0.1-rc.3.tgz#0c6d68ec77c659f954dd1a302c3ef40369b56f37"
|
resolved "https://registry.yarnpkg.com/@rancher/shell/-/shell-3.0.1-rc.4.tgz#d5b57a0184a89be09e7d4d21472545b3306d23d5"
|
||||||
integrity sha512-05jGdQxJHbNmP6VoukhQ1WqY326irGOgrv6oVSm3FoTPST2zHH3F8WbEuHtlG4rhU/siV4MfXPOHE9Zozgw7jQ==
|
integrity sha512-cTBLjn7iysSi86XgptWDi8ErarVyPh6yRrRfBefQrxhMeCJNy3aH40neO37zJO/0e99/YBe4bRsr6Z2NV9TqBA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@aws-sdk/client-ec2" "3.658.1"
|
"@aws-sdk/client-ec2" "3.658.1"
|
||||||
"@aws-sdk/client-eks" "3.1.0"
|
"@aws-sdk/client-eks" "3.1.0"
|
||||||
@@ -3049,7 +3049,6 @@
|
|||||||
vue-router "4.4.3"
|
vue-router "4.4.3"
|
||||||
vue-select "4.0.0-beta.6"
|
vue-select "4.0.0-beta.6"
|
||||||
vue-server-renderer "2.7.16"
|
vue-server-renderer "2.7.16"
|
||||||
vue-template-compiler "2.7.16"
|
|
||||||
vue3-resize "0.2.0"
|
vue3-resize "0.2.0"
|
||||||
vue3-virtual-scroll-list "0.2.1"
|
vue3-virtual-scroll-list "0.2.1"
|
||||||
vuedraggable "4.1.0"
|
vuedraggable "4.1.0"
|
||||||
@@ -7107,11 +7106,6 @@ dayjs@^1.10.4, dayjs@^1.11.3:
|
|||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
|
||||||
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
||||||
|
|
||||||
de-indent@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
|
||||||
integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
|
|
||||||
|
|
||||||
debounce@^1.2.1:
|
debounce@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
|
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
|
||||||
@@ -13889,14 +13883,6 @@ vue-style-loader@^4.1.0, vue-style-loader@^4.1.3:
|
|||||||
hash-sum "^1.0.2"
|
hash-sum "^1.0.2"
|
||||||
loader-utils "^1.0.2"
|
loader-utils "^1.0.2"
|
||||||
|
|
||||||
vue-template-compiler@2.7.16:
|
|
||||||
version "2.7.16"
|
|
||||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz#c81b2d47753264c77ac03b9966a46637482bb03b"
|
|
||||||
integrity sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==
|
|
||||||
dependencies:
|
|
||||||
de-indent "^1.0.2"
|
|
||||||
he "^1.2.0"
|
|
||||||
|
|
||||||
vue-template-es2015-compiler@^1.9.0:
|
vue-template-es2015-compiler@^1.9.0:
|
||||||
version "1.9.1"
|
version "1.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
||||||
|
|||||||
Reference in New Issue
Block a user