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/package-lock.json b/frontend/package-lock.json index 29aae7761..2c6019c40 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,7 +42,7 @@ "socket.io-client": "^4.7.2", "uuid": "^9.0.0", "vue": "^3.3.4", - "vue-i18n": "^9.6.5", + "vue-i18n": "^9.14.5", "vue-router": "^4.2.4", "wavesurfer.js": "^7.7.1", "xterm": "^4.12.0", @@ -1228,13 +1228,12 @@ "dev": true }, "node_modules/@intlify/core-base": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.4.tgz", - "integrity": "sha512-vtZCt7NqWhKEtHa3SD/322DlgP5uR9MqWxnE0y8Q0tjDs9H5Lxhss+b5wv8rmuXRoHKLESNgw9d+EN9ybBbj9g==", - "license": "MIT", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz", + "integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==", "dependencies": { - "@intlify/message-compiler": "9.14.4", - "@intlify/shared": "9.14.4" + "@intlify/message-compiler": "9.14.5", + "@intlify/shared": "9.14.5" }, "engines": { "node": ">= 16" @@ -1244,12 +1243,11 @@ } }, "node_modules/@intlify/message-compiler": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.4.tgz", - "integrity": "sha512-vcyCLiVRN628U38c3PbahrhbbXrckrM9zpy0KZVlDk2Z0OnGwv8uQNNXP3twwGtfLsCf4gu3ci6FMIZnPaqZsw==", - "license": "MIT", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz", + "integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==", "dependencies": { - "@intlify/shared": "9.14.4", + "@intlify/shared": "9.14.5", "source-map-js": "^1.0.2" }, "engines": { @@ -1260,10 +1258,9 @@ } }, "node_modules/@intlify/shared": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.4.tgz", - "integrity": "sha512-P9zv6i1WvMc9qDBWvIgKkymjY2ptIiQ065PjDv7z7fDqH3J/HBRBN5IoiR46r/ujRcU7hCuSIZWvCAFCyuOYZA==", - "license": "MIT", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz", + "integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==", "engines": { "node": ">= 16" }, @@ -9134,13 +9131,12 @@ "dev": true }, "node_modules/vue-i18n": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.4.tgz", - "integrity": "sha512-B934C8yUyWLT0EMud3DySrwSUJI7ZNiWYsEEz2gknTthqKiG4dzWE/WSa8AzCuSQzwBEv4HtG1jZDhgzPfWSKQ==", - "license": "MIT", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz", + "integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==", "dependencies": { - "@intlify/core-base": "9.14.4", - "@intlify/shared": "9.14.4", + "@intlify/core-base": "9.14.5", + "@intlify/shared": "9.14.5", "@vue/devtools-api": "^6.5.0" }, "engines": { @@ -10386,27 +10382,27 @@ "dev": true }, "@intlify/core-base": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.4.tgz", - "integrity": "sha512-vtZCt7NqWhKEtHa3SD/322DlgP5uR9MqWxnE0y8Q0tjDs9H5Lxhss+b5wv8rmuXRoHKLESNgw9d+EN9ybBbj9g==", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz", + "integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==", "requires": { - "@intlify/message-compiler": "9.14.4", - "@intlify/shared": "9.14.4" + "@intlify/message-compiler": "9.14.5", + "@intlify/shared": "9.14.5" } }, "@intlify/message-compiler": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.4.tgz", - "integrity": "sha512-vcyCLiVRN628U38c3PbahrhbbXrckrM9zpy0KZVlDk2Z0OnGwv8uQNNXP3twwGtfLsCf4gu3ci6FMIZnPaqZsw==", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz", + "integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==", "requires": { - "@intlify/shared": "9.14.4", + "@intlify/shared": "9.14.5", "source-map-js": "^1.0.2" } }, "@intlify/shared": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.4.tgz", - "integrity": "sha512-P9zv6i1WvMc9qDBWvIgKkymjY2ptIiQ065PjDv7z7fDqH3J/HBRBN5IoiR46r/ujRcU7hCuSIZWvCAFCyuOYZA==" + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz", + "integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==" }, "@jest/schemas": { "version": "29.6.0", @@ -16046,12 +16042,12 @@ } }, "vue-i18n": { - "version": "9.14.4", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.4.tgz", - "integrity": "sha512-B934C8yUyWLT0EMud3DySrwSUJI7ZNiWYsEEz2gknTthqKiG4dzWE/WSa8AzCuSQzwBEv4HtG1jZDhgzPfWSKQ==", + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz", + "integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==", "requires": { - "@intlify/core-base": "9.14.4", - "@intlify/shared": "9.14.4", + "@intlify/core-base": "9.14.5", + "@intlify/shared": "9.14.5", "@vue/devtools-api": "^6.5.0" } }, diff --git a/frontend/package.json b/frontend/package.json index cc0f3fb0b..ef1b65640 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -46,7 +46,7 @@ "socket.io-client": "^4.7.2", "uuid": "^9.0.0", "vue": "^3.3.4", - "vue-i18n": "^9.6.5", + "vue-i18n": "^9.14.5", "vue-router": "^4.2.4", "wavesurfer.js": "^7.7.1", "xterm": "^4.12.0", 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",