Skip to content

Commit

Permalink
Merge pull request #4492 from adamkpickering/cherrypick-4773-to-relea…
Browse files Browse the repository at this point in the history
…se-1.9

Cherrypick 4773 workaround to release-1.9 branch
  • Loading branch information
adamkpickering authored Apr 18, 2023
2 parents bbbbbe4 + 2d135a7 commit 4fc5da7
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions pkg/rancher-desktop/backend/containerClient/nerdctlClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ContainerRunClientOptions, ContainerComposePortOptions,
} from './types';

import { VMExecutor } from '@pkg/backend/backend';
import { execOptions, VMExecutor } from '@pkg/backend/backend';
import { spawn, spawnFile } from '@pkg/utils/childProcess';
import Logging, { Log } from '@pkg/utils/logging';
import { executable } from '@pkg/utils/resources';
Expand Down Expand Up @@ -70,6 +70,24 @@ export class NerdctlClient implements ContainerEngineClient {
}
}

/**
* Like running this.vm.execCommand, but retries the command if no output
* is produced. Is a workaround for a strange behavior of this.vm.execCommand:
* sometimes nothing is returned from stdout, as though it did not run at
* all. See https://github.com/rancher-sandbox/rancher-desktop/issues/4473
* for more info.
*/
protected async execCommandWithRetries(options: execOptions & { capture: true }, ...command: string[]): Promise<string> {
const maxRetries = 10;
let result = '';

for (let i = 0; i < maxRetries && !result; i++) {
result = await this.vm.execCommand({ ...options, capture: true }, ...command);
}

return result;
}

/**
* Mount the given image inside the VM.
* @param imageID The ID of the image to mount.
Expand All @@ -84,20 +102,17 @@ export class NerdctlClient implements ContainerEngineClient {

try {
const namespaceArgs = namespace === undefined ? [] : ['--namespace', namespace];
const container = (await this.vm.execCommand({ capture: true },
const container = (await this.execCommandWithRetries({ capture: true },
'/usr/local/bin/nerdctl', ...namespaceArgs, 'create', '--entrypoint=/', imageID)).trim();

if (!container) {
throw new Error(`Failed to create container for ${ imageID }`);
}
cleanups.push(() => this.vm.execCommand(
'/usr/local/bin/nerdctl', ...namespaceArgs, 'rm', '--force', '--volumes', container));

const workdir = (await this.vm.execCommand({ capture: true }, '/bin/mktemp', '-d', '-t', 'rd-nerdctl-cp-XXXXXX')).trim();
const workdir = (await this.execCommandWithRetries({ capture: true }, '/bin/mktemp', '-d', '-t', 'rd-nerdctl-cp-XXXXXX')).trim();

cleanups.push(() => this.vm.execCommand('/bin/rm', '-rf', workdir));

const command = await this.vm.execCommand({ capture: true, root: true },
const command = await this.execCommandWithRetries({ capture: true, root: true },
'/usr/bin/ctr', ...namespaceArgs,
'--address=/run/k3s/containerd/containerd.sock', 'snapshot', 'mounts', workdir, container);

Expand Down Expand Up @@ -142,7 +157,7 @@ export class NerdctlClient implements ContainerEngineClient {

try {
// Archive the file(s) into the VM
const archive = (await this.vm.execCommand({ capture: true }, '/bin/mktemp', '-t', 'rd-nerdctl-cp-XXXXXX')).trim();
const archive = (await this.execCommandWithRetries({ capture: true }, '/bin/mktemp', '-t', 'rd-nerdctl-cp-XXXXXX')).trim();

cleanups.push(() => this.vm.execCommand('/bin/rm', '-f', archive));
let sourceName: string, sourceDir: string;
Expand Down

0 comments on commit 4fc5da7

Please sign in to comment.