diff --git a/common/global.d.ts b/common/global.d.ts index 8a392758f..85723261f 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -48,6 +48,7 @@ declare global { interface IGlobalInstanceDockerConfig { containerName?: string; + pullPolicy?: boolean; image?: string; memory?: number; ports?: string[]; diff --git a/daemon/src/entity/commands/docker/docker_pull.ts b/daemon/src/entity/commands/docker/docker_pull.ts index 3f1bda09a..775cb28d3 100644 --- a/daemon/src/entity/commands/docker/docker_pull.ts +++ b/daemon/src/entity/commands/docker/docker_pull.ts @@ -50,28 +50,32 @@ export default class DockerPullCommand extends InstanceCommand { async exec(instance: Instance) { const imageName = instance.config.docker.image; + const pullPolicy = instance.config.docker.pullPolicy; if (!imageName) throw new Error(t("TXT_CODE_17be5f70")); const cachedStartCount = instance.startCount; // If the image exists, there is no need to pull again. - if (await checkImage(imageName)) return; + if(pullPolicy === false ) { + if (await checkImage(imageName)) return; + } else { - try { - const docker = new DefaultDocker(); - instance.println("CONTAINER", t("TXT_CODE_2fa46b8c") + imageName); - instance.asynchronousTask = this; + try { + const docker = new DefaultDocker(); + instance.println("CONTAINER", t("TXT_CODE_2fa46b8c") + imageName); + instance.asynchronousTask = this; - await docker.pull(imageName, {}); + await docker.pull(imageName, {}); - await this.awaitImageDone(instance, imageName); - if (cachedStartCount !== instance.startCount) return; - instance.println("CONTAINER", t("TXT_CODE_c68b0bef")); - } catch (err: any) { - if (cachedStartCount !== instance.startCount) return; - throw new Error([t("TXT_CODE_db37b7f9"), err?.message].join("\n")); - } finally { - this.stopped(instance); - } + await this.awaitImageDone(instance, imageName); + if (cachedStartCount !== instance.startCount) return; + instance.println("CONTAINER", t("TXT_CODE_c68b0bef")); + } catch (err: any) { + if (cachedStartCount !== instance.startCount) return; + throw new Error([t("TXT_CODE_db37b7f9"), err?.message].join("\n")); + } finally { + this.stopped(instance); + } } +} async stop(instance: Instance): Promise { this.stopped(instance); diff --git a/daemon/src/entity/instance/Instance_config.ts b/daemon/src/entity/instance/Instance_config.ts index b55a52179..f6863d4b3 100755 --- a/daemon/src/entity/instance/Instance_config.ts +++ b/daemon/src/entity/instance/Instance_config.ts @@ -55,6 +55,7 @@ export default class InstanceConfig implements IGlobalInstanceConfig { public docker: IGlobalInstanceDockerConfig = { containerName: "", image: "", + pullPolicy: false, ports: [], extraVolumes: [], memory: 0, diff --git a/daemon/src/entity/instance/instance.ts b/daemon/src/entity/instance/instance.ts index 5ea8f5fb8..b4d656566 100755 --- a/daemon/src/entity/instance/instance.ts +++ b/daemon/src/entity/instance/instance.ts @@ -196,6 +196,7 @@ export default class Instance extends EventEmitter { if (cfg.docker) { configureEntityParams(this.config.docker, cfg.docker, "containerName", String); + configureEntityParams(this.config.docker, cfg.docker, "pullPolicy", Boolean); configureEntityParams(this.config.docker, cfg.docker, "image", String); configureEntityParams(this.config.docker, cfg.docker, "memory", Number); configureEntityParams(this.config.docker, cfg.docker, "ports"); diff --git a/frontend/src/widgets/instance/dialogs/InstanceDetail.vue b/frontend/src/widgets/instance/dialogs/InstanceDetail.vue index 23a961e22..af00d1335 100644 --- a/frontend/src/widgets/instance/dialogs/InstanceDetail.vue +++ b/frontend/src/widgets/instance/dialogs/InstanceDetail.vue @@ -667,6 +667,29 @@ defineExpose({ + + + + Always pull image + + + + Always pull Docker image + + + + + + + + + + {{ t("TXT_CODE_10194e6a") }} diff --git a/frontend/src/widgets/setupApp/CreateInstanceForm.vue b/frontend/src/widgets/setupApp/CreateInstanceForm.vue index bac906b53..ce6fe3b67 100644 --- a/frontend/src/widgets/setupApp/CreateInstanceForm.vue +++ b/frontend/src/widgets/setupApp/CreateInstanceForm.vue @@ -60,6 +60,7 @@ const formData = reactive({ docker: { containerName: "", image: "", + pullPolicy: false, ports: [], extraVolumes: [], networkMode: "bridge", diff --git a/panel/package-lock.json b/panel/package-lock.json index 1ad18d1a6..98c384df7 100644 --- a/panel/package-lock.json +++ b/panel/package-lock.json @@ -345,9 +345,9 @@ } }, "node_modules/@messageformat/runtime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", - "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.2.tgz", + "integrity": "sha512-dkIPDCjXcfhSHgNE1/qV6TeczQZR59Yx0xXeafVKgK3QVWoxc38ljwpksUpnzCGvN151KUbCJTDZVmahtf1YZw==", "dependencies": { "make-plural": "^7.0.0" } @@ -5772,9 +5772,9 @@ } }, "@messageformat/runtime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", - "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.2.tgz", + "integrity": "sha512-dkIPDCjXcfhSHgNE1/qV6TeczQZR59Yx0xXeafVKgK3QVWoxc38ljwpksUpnzCGvN151KUbCJTDZVmahtf1YZw==", "requires": { "make-plural": "^7.0.0" }