Skip to content

Commit

Permalink
Merge pull request #6711 from jandubois/spinkube
Browse files Browse the repository at this point in the history
Add --experimental.kubernetes.options.spinkube setting
  • Loading branch information
mook-as authored Apr 17, 2024
2 parents bf727d0 + 1470447 commit 9e414d6
Show file tree
Hide file tree
Showing 22 changed files with 239 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,8 @@ softmmu
someothername
somepaththatshouldnevereverexist
sourced
spinkube
spinoperator
splatform
splunk
ssd
Expand Down
4 changes: 2 additions & 2 deletions e2e/pages/preferences/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class KubernetesNav {
readonly kubernetesToggle: Locator;
readonly kubernetesVersion: Locator;
readonly kubernetesPort: Locator;
readonly traefikToggle: Locator;
readonly kubernetesOptions: Locator;
readonly kubernetesVersionLockedFields: Locator;

constructor(page: Page) {
Expand All @@ -15,7 +15,7 @@ export class KubernetesNav {
this.kubernetesToggle = page.locator('[data-test="kubernetesToggle"]');
this.kubernetesVersion = page.locator('[data-test="kubernetesVersion"]');
this.kubernetesPort = page.locator('[data-test="kubernetesPort"]');
this.traefikToggle = page.locator('[data-test="traefikToggle"]');
this.kubernetesOptions = page.locator('[data-test="kubernetesOptions"]');
this.kubernetesVersionLockedFields = page.locator('[data-test="kubernetesVersion"] > .select-k8s-version > .icon-lock');
}
}
2 changes: 1 addition & 1 deletion e2e/preferences.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ test.describe.serial('Main App Test', () => {
await expect(kubernetes.kubernetesToggle).toBeVisible();
await expect(kubernetes.kubernetesVersion).toBeVisible();
await expect(kubernetes.kubernetesPort).toBeVisible();
await expect(kubernetes.traefikToggle).toBeVisible();
await expect(kubernetes.kubernetesOptions).toBeVisible();
});

test('should navigate to WSL and render network tab', async() => {
Expand Down
2 changes: 2 additions & 0 deletions pkg/rancher-desktop/assets/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ wix: v3.14.1
hostSwitch: 1.2.2
moproxy: 0.5.0
wasmShims: 0.11.1
spinOperator: 0.1.0
certManager: 1.14.4
11 changes: 11 additions & 0 deletions pkg/rancher-desktop/assets/scripts/install-k3s
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,14 @@ fi
ln -s -f "${K3S_DIR}/${K3S}" /usr/local/bin/k3s
# The file system may be readonly (on macOS)
chmod a+x "${K3S_DIR}/${K3S}" || true

# Make sure any old manifests are removed before configuring k3s again
# We need to create the directory before we run `k3s server ...` because
# we install additional manifests that k3s will install during startup.
MANIFESTS=/var/lib/rancher/k3s/server/manifests
rm -rf "$MANIFESTS"
mkdir -p "$MANIFESTS"

STATIC=/var/lib/rancher/k3s/server/static/rancher-desktop
rm -rf "$STATIC"
mkdir -p "$STATIC"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: spin-operator
namespace: kube-system
spec:
chart: "https://%{KUBERNETES_API}%/static/rancher-desktop/spin-operator.tgz"
targetNamespace: spin-operator
createNamespace: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: core.spinoperator.dev/v1alpha1
kind: SpinAppExecutor
metadata:
name: containerd-shim-spin
spec:
createDeployment: true
deploymentConfig:
runtimeClassName: spin
9 changes: 9 additions & 0 deletions pkg/rancher-desktop/assets/specs/command-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,15 @@ components:
enabled:
type: boolean
x-rd-usage: enable support for containerd-wasm shims
kubernetes:
type: object
properties:
options:
type: object
properties:
spinkube:
type: boolean
x-rd-usage: install spin operator
virtualMachine:
type: object
properties:
Expand Down
40 changes: 30 additions & 10 deletions pkg/rancher-desktop/backend/backendHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import yaml from 'yaml';

import INSTALL_CONTAINERD_SHIMS_SCRIPT from '@pkg/assets/scripts/install-containerd-shims';
import CONTAINERD_CONFIG from '@pkg/assets/scripts/k3s-containerd-config.toml';
import SPIN_OPERATOR_HELM_CHART from '@pkg/assets/scripts/spin-operator.helm-chart.yaml';
import SPIN_OPERATOR_SHIM_EXECUTOR from '@pkg/assets/scripts/spin-operator.shim-executor.yaml';
import { BackendSettings, VMExecutor } from '@pkg/backend/backend';
import { LockedFieldError } from '@pkg/config/commandLineOptions';
import { ContainerEngine, Settings } from '@pkg/config/settings';
Expand All @@ -19,8 +21,18 @@ import { showMessageBox } from '@pkg/window';

const CONTAINERD_CONFIG_TOML = '/etc/containerd/config.toml';
const DOCKER_DAEMON_JSON = '/etc/docker/daemon.json';
// Don't use `runtimes.yaml` because k3s may overwrite it.
const MANIFESTS_RUNTIMES_YAML = '/var/lib/rancher/k3s/server/manifests/rd-runtimes.yaml';

const MANIFEST_DIR = '/var/lib/rancher/k3s/server/manifests';
// Manifests are applied in sort order, so use a prefix to load them last, in the required sequence.
// Also: don't use `runtimes.yaml` because k3s may overwrite it.
const MANIFEST_RUNTIMES_YAML = `${ MANIFEST_DIR }/z100-rd-runtimes.yaml`;
const MANIFEST_CERT_MANAGER = `${ MANIFEST_DIR }/z110-cert-manager.yaml`;
const MANIFEST_SPIN_OPERATOR_CRDS = `${ MANIFEST_DIR }/z120-spin-operator.crds.yaml`;
const MANIFEST_SPIN_OPERATOR_SHIM_EXECUTOR = `${ MANIFEST_DIR }/z121-spin-operator.shim-executor.yaml`;
const MANIFEST_SPIN_OPERATOR_CHART = `${ MANIFEST_DIR }/z122-spin-operator.chart.yaml`;

const STATIC_DIR = '/var/lib/rancher/k3s/server/static/rancher-desktop';
const STATIC_SPIN_OPERATOR_CHART = `${ STATIC_DIR }/spin-operator.tgz`;

const console = Logging.kube;

Expand Down Expand Up @@ -269,21 +281,29 @@ export default class BackendHelper {
});
}

await vmx.execCommand({ root: true }, 'mkdir', '-p', path.dirname(MANIFESTS_RUNTIMES_YAML));
// Don't let k3s define runtime classes, only use the ones defined by Rancher Desktop.
await vmx.execCommand({ root: true }, 'touch', `${ path.dirname(MANIFESTS_RUNTIMES_YAML) }/runtimes.yaml.skip`);
await vmx.execCommand({ root: true }, 'touch', `${ MANIFEST_DIR }/runtimes.yaml.skip`);

if (runtimes.length === 0) {
// We delete the manifest file, but we don't actually delete old runtime classes in k3s that no longer exist.
// They won't work though, as the symlinks in /usr/local/bin have been removed.
await vmx.execCommand({ root: true }, 'rm', '-f', MANIFESTS_RUNTIMES_YAML);
} else {
if (runtimes.length > 0) {
const manifest = runtimes.map(r => yaml.stringify(r)).join('---\n');

await vmx.writeFile(MANIFESTS_RUNTIMES_YAML, manifest, 0o644);
await vmx.writeFile(MANIFEST_RUNTIMES_YAML, manifest, 0o644);
}
}

/**
* Write k3s manifests to install cert-manager and spinkube operator
*/
static async configureSpinOperator(vmx: VMExecutor) {
await Promise.all([
vmx.copyFileIn(path.join(paths.resources, 'cert-manager.yaml'), MANIFEST_CERT_MANAGER),
vmx.copyFileIn(path.join(paths.resources, 'spin-operator.crds.yaml'), MANIFEST_SPIN_OPERATOR_CRDS),
vmx.copyFileIn(path.join(paths.resources, 'spin-operator.tgz'), STATIC_SPIN_OPERATOR_CHART),
vmx.writeFile(MANIFEST_SPIN_OPERATOR_SHIM_EXECUTOR, SPIN_OPERATOR_SHIM_EXECUTOR, 0o644),
vmx.writeFile(MANIFEST_SPIN_OPERATOR_CHART, SPIN_OPERATOR_HELM_CHART, 0o644),
]);
}

/**
* Install containerd-wasm shims into /usr/local/containerd-shims (and symlinks into /usr/local/bin).
*/
Expand Down
15 changes: 13 additions & 2 deletions pkg/rancher-desktop/backend/kube/lima.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,19 @@ export default class LimaKubernetesBackend extends events.EventEmitter implement
*/
async install(config: BackendSettings, desiredVersion: semver.SemVer, allowSudo: boolean) {
await this.progressTracker.action('Installing k3s', 50, async() => {
// installK3s removes old config and makes sure the directories are recreated
await this.installK3s(desiredVersion);
await this.writeServiceScript(config, desiredVersion, allowSudo);
await BackendHelper.configureRuntimeClasses(this.vm);

const promises: Promise<void>[] = [];

promises.push(this.writeServiceScript(config, desiredVersion, allowSudo));
if (config.experimental?.containerEngine?.webAssembly?.enabled) {
promises.push(BackendHelper.configureRuntimeClasses(this.vm));
if (config.experimental?.kubernetes?.options?.spinkube) {
promises.push(BackendHelper.configureSpinOperator(this.vm));
}
}
await Promise.all(promises);
});

this.activeVersion = desiredVersion;
Expand Down Expand Up @@ -388,6 +398,7 @@ export default class LimaKubernetesBackend extends events.EventEmitter implement
'containerEngine.allowedImages.enabled': undefined,
'containerEngine.name': undefined,
'experimental.containerEngine.webAssembly.enabled': undefined,
'experimental.kubernetes.options.spinkube': undefined,
'kubernetes.port': undefined,
'kubernetes.enabled': undefined,
'kubernetes.options.traefik': undefined,
Expand Down
12 changes: 11 additions & 1 deletion pkg/rancher-desktop/backend/kube/wsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,16 @@ export default class WSLKubernetesBackend extends events.EventEmitter implements
async install(config: BackendSettings, version: semver.SemVer, allowSudo: boolean) {
await this.vm.runInstallScript(INSTALL_K3S_SCRIPT,
'install-k3s', version.raw, await this.vm.wslify(path.join(paths.cache, 'k3s')));
await BackendHelper.configureRuntimeClasses(this.vm);

if (config.experimental?.containerEngine?.webAssembly?.enabled) {
const promises: Promise<void>[] = [];

promises.push(BackendHelper.configureRuntimeClasses(this.vm));
if (config.experimental?.kubernetes?.options?.spinkube) {
promises.push(BackendHelper.configureSpinOperator(this.vm));
}
await Promise.all(promises);
}
}

async start(config: BackendSettings, activeVersion: semver.SemVer, kubeClient?: () => KubeClient): Promise<string> {
Expand Down Expand Up @@ -295,6 +304,7 @@ export default class WSLKubernetesBackend extends events.EventEmitter implements
'containerEngine.allowedImages.enabled': undefined,
'containerEngine.name': undefined,
'experimental.containerEngine.webAssembly.enabled': undefined,
'experimental.kubernetes.options.spinkube': undefined,
'kubernetes.enabled': undefined,
'kubernetes.ingress.localhostOnly': undefined,
'kubernetes.options.flannel': undefined,
Expand Down
21 changes: 14 additions & 7 deletions pkg/rancher-desktop/backend/lima.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken
return;
}

const workdir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'rd-vmnet-install'));
const workdir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'rd-vmnet-install-'));
const tarPath = path.join(workdir, 'vmnet.tar');
const commands: string[] = [];

Expand Down Expand Up @@ -1557,8 +1557,6 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken
}

protected async configureContainerEngine(): Promise<void> {
const workdir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'rd-containerd-install-'));

try {
const configureWASM = !!this.cfg?.experimental?.containerEngine?.webAssembly?.enabled;

Expand All @@ -1572,8 +1570,6 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken
await BackendHelper.configureContainerEngine(this, configureWASM);
} catch (err) {
console.log(`Error trying to start/update containerd: ${ err }: `, err);
} finally {
await fs.promises.rm(workdir, { recursive: true });
}
}

Expand Down Expand Up @@ -1643,8 +1639,19 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken
}
}

copyFileIn(hostPath: string, vmPath: string): Promise<void> {
return this.lima('copy', hostPath, `${ MACHINE_NAME }:${ vmPath }`);
async copyFileIn(hostPath: string, vmPath: string): Promise<void> {
// TODO This logic is copied from writeFile() above and should be simplified.
const workdir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `rd-${ path.basename(hostPath) }-`));
const tempPath = `/tmp/${ path.basename(workdir) }.${ path.basename(hostPath) }`;

try {
await this.lima('copy', hostPath, `${ MACHINE_NAME }:${ tempPath }`);
await this.execCommand('chmod', '644', tempPath);
await this.execCommand({ root: true }, 'mv', tempPath, vmPath);
} finally {
await fs.promises.rm(workdir, { recursive: true });
await this.execCommand({ root: true }, 'rm', '-f', tempPath);
}
}

copyFileOut(vmPath: string, hostPath: string): Promise<void> {
Expand Down
13 changes: 11 additions & 2 deletions pkg/rancher-desktop/components/Preferences/BodyKubernetes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ export default Vue.extend({
/>
</rd-fieldset>
<rd-fieldset
data-test="traefikToggle"
legend-text="Traefik"
data-test="kubernetesOptions"
legend-text="Options"
>
<rd-checkbox
label="Enable Traefik"
Expand All @@ -172,6 +172,15 @@ export default Vue.extend({
:is-locked="isPreferenceLocked('kubernetes.options.traefik')"
@input="onChange('kubernetes.options.traefik', $event)"
/>
<!-- Don't disable Spinkube option when Wasm is disabled; let validation deal with it -->
<rd-checkbox
label="Install Spin Operator"
:disabled="isKubernetesDisabled"
:value="preferences.experimental.kubernetes.options.spinkube"
:is-locked="isPreferenceLocked('experimental.kubernetes.options.spinkube')"
:is-experimental="true"
@input="onChange('experimental.kubernetes.options.spinkube', $event)"
/>
</rd-fieldset>
</div>
</template>
Expand Down
56 changes: 37 additions & 19 deletions pkg/rancher-desktop/components/form/RdCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
import { Checkbox } from '@rancher/components';
import Vue from 'vue';
import TooltipIcon from '@pkg/components/form/TooltipIcon.vue';
export default Vue.extend({
name: 'rd-checkbox',
components: { Checkbox },
components: { TooltipIcon, Checkbox },
inheritAttrs: false,
props: {
isExperimental: {
type: Boolean,
default: false,
},
isLocked: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -39,25 +45,31 @@ export default Vue.extend({
v-on="$listeners"
>
<template #label>
<t
v-if="labelKey"
:k="labelKey"
:raw="true"
/>
<template v-else-if="label">
{{ label }}
</template>
<i
v-if="tooltipKey"
v-clean-tooltip="t(tooltipKey)"
class="checkbox-info icon icon-info icon-lg"
/>
<i
v-else-if="tooltip"
v-clean-tooltip="tooltip"
class="checkbox-info icon icon-info icon-lg"
/>
<slot name="label">
<t
v-if="labelKey"
:k="labelKey"
:raw="true"
/>
<template v-else-if="label">
{{ label }}
</template>
<i
v-if="tooltipKey"
v-clean-tooltip="t(tooltipKey)"
class="checkbox-info icon icon-info icon-lg"
/>
<i
v-else-if="tooltip"
v-clean-tooltip="tooltip"
class="checkbox-info icon icon-info icon-lg"
/>
</slot>
<slot name="after">
<tooltip-icon
v-if="isExperimental"
class="tooltip-icon"
/>
<i
v-if="isLocked"
v-tooltip="{
Expand All @@ -71,3 +83,9 @@ export default Vue.extend({
</checkbox>
</div>
</template>

<style lang="scss" scoped>
.tooltip-icon {
margin-left: 0.25rem;
}
</style>
4 changes: 3 additions & 1 deletion pkg/rancher-desktop/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,12 @@ export const defaultSettings = {
mutedChecks: {} as Record<string, boolean>,
},
/**
* Experimental settings - there should not be any UI for these.
* Experimental settings
*/
experimental: {
containerEngine: { webAssembly: { enabled: false } },
/** can only be enabled if containerEngine.webAssembly.enabled is true */
kubernetes: { options: { spinkube: false } },
virtualMachine: {
/** can only be set to VMType.VZ on macOS Ventura and later */
type: VMType.QEMU,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe(SettingsValidator, () => {
['application', 'pathManagementStrategy'],
['containerEngine', 'allowedImages', 'locked'],
['containerEngine', 'name'],
['experimental', 'kubernetes', 'options', 'spinkube'],
['experimental', 'virtualMachine', 'mount', '9p', 'cacheMode'],
['experimental', 'virtualMachine', 'mount', '9p', 'msizeInKib'],
['experimental', 'virtualMachine', 'mount', '9p', 'protocolVersion'],
Expand Down
Loading

0 comments on commit 9e414d6

Please sign in to comment.