From e2c43be24adffe1f17a2d65b383b248cd23de57c Mon Sep 17 00:00:00 2001 From: Jacky Date: Mon, 21 Apr 2025 06:20:15 +0000 Subject: [PATCH] feat(ota): upgrade container --- app/src/constants/errors/docker.ts | 5 + app/src/language/ar/app.po | 25 +++ app/src/language/de_DE/app.po | 25 +++ app/src/language/en/app.po | 25 +++ app/src/language/es/app.po | 25 +++ app/src/language/fr_FR/app.po | 25 +++ app/src/language/ko_KR/app.po | 25 +++ app/src/language/messages.pot | 20 ++ app/src/language/ru_RU/app.po | 25 +++ app/src/language/tr_TR/app.po | 25 +++ app/src/language/uk_UA/app.po | 20 ++ app/src/language/vi_VN/app.po | 25 +++ app/src/language/zh_CN/app.po | 66 +++--- app/src/language/zh_TW/app.po | 25 +++ internal/cmd/main.go | 5 +- internal/cmd/upgrade_docker.go | 23 ++ internal/docker/errors.go | 5 + internal/docker/ota.go | 329 +++++++++++++++++++++++++++++ internal/kernel/boot.go | 13 ++ 19 files changed, 708 insertions(+), 28 deletions(-) create mode 100644 internal/cmd/upgrade_docker.go create mode 100644 internal/docker/ota.go diff --git a/app/src/constants/errors/docker.ts b/app/src/constants/errors/docker.ts index 717bf696..cc87e869 100644 --- a/app/src/constants/errors/docker.ts +++ b/app/src/constants/errors/docker.ts @@ -7,4 +7,9 @@ export default { 500006: () => $gettext('Container status unknown'), 500007: () => $gettext('Failed to inspect container: {0}'), 500008: () => $gettext('Nginx is not running in another container'), + 500009: () => $gettext('Failed to get hostname: {0}'), + 500010: () => $gettext('Failed to pull image: {0}'), + 500011: () => $gettext('Failed to inspect current container: {0}'), + 500012: () => $gettext('Failed to create temp container: {0}'), + 500013: () => $gettext('Failed to start temp container: {0}'), } diff --git a/app/src/language/ar/app.po b/app/src/language/ar/app.po index ef1cb974..6b466ab8 100644 --- a/app/src/language/ar/app.po +++ b/app/src/language/ar/app.po @@ -1599,6 +1599,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "فشل في التفعيل %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "فشل في التفعيل %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1721,6 +1726,11 @@ msgstr "فشل في الحصول على معلومات الشهادة" msgid "Failed to get certificate information" msgstr "فشل في الحصول على معلومات الشهادة" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "فشل في التفعيل %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1736,6 +1746,11 @@ msgstr "فشل في الحصول على معلومات الشهادة" msgid "Failed to inspect container: {0}" msgstr "فشل في التفعيل %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "فشل في التفعيل %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1760,6 +1775,11 @@ msgstr "فشل في التفعيل %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "فشل في التفعيل %{msg}" + #: src/constants/errors/backup.ts:53 #, fuzzy msgid "Failed to read encrypted file: {0}" @@ -1809,6 +1829,11 @@ msgstr "فشل في الحصول على الشهادة" msgid "Failed to save Nginx performance settings" msgstr "فشل في الحصول على معلومات الشهادة" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "فشل في التفعيل %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/de_DE/app.po b/app/src/language/de_DE/app.po index 0ff77b6f..537b048a 100644 --- a/app/src/language/de_DE/app.po +++ b/app/src/language/de_DE/app.po @@ -1645,6 +1645,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Aktiviern von %{msg} fehlgeschlagen" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Aktiviern von %{msg} fehlgeschlagen" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1767,6 +1772,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen" msgid "Failed to get certificate information" msgstr "Fehler beim Abrufen von Zertifikatsinformationen" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Aktiviern von %{msg} fehlgeschlagen" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1782,6 +1792,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen" msgid "Failed to inspect container: {0}" msgstr "Aktiviern von %{msg} fehlgeschlagen" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Aktiviern von %{msg} fehlgeschlagen" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1806,6 +1821,11 @@ msgstr "Aktiviern von %{msg} fehlgeschlagen" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Aktiviern von %{msg} fehlgeschlagen" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1851,6 +1871,11 @@ msgstr "Zertifikat ist gültig" msgid "Failed to save Nginx performance settings" msgstr "Fehler beim Abrufen von Zertifikatsinformationen" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Aktiviern von %{msg} fehlgeschlagen" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/en/app.po b/app/src/language/en/app.po index e73257dd..47b02ace 100644 --- a/app/src/language/en/app.po +++ b/app/src/language/en/app.po @@ -1629,6 +1629,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Failed to enable %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Failed to enable %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1752,6 +1757,11 @@ msgstr "Certificate is valid" msgid "Failed to get certificate information" msgstr "Certificate is valid" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Failed to enable %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1767,6 +1777,11 @@ msgstr "Certificate is valid" msgid "Failed to inspect container: {0}" msgstr "Failed to enable %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Failed to enable %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1791,6 +1806,11 @@ msgstr "Failed to enable %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Failed to enable %{msg}" + #: src/constants/errors/backup.ts:53 #, fuzzy msgid "Failed to read encrypted file: {0}" @@ -1840,6 +1860,11 @@ msgstr "Certificate is valid" msgid "Failed to save Nginx performance settings" msgstr "Certificate is valid" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Failed to enable %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/es/app.po b/app/src/language/es/app.po index 910abdc5..193d2efa 100644 --- a/app/src/language/es/app.po +++ b/app/src/language/es/app.po @@ -1601,6 +1601,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Error al habilitar %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Error al habilitar %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1723,6 +1728,11 @@ msgstr "No se pudo obtener la información del certificado" msgid "Failed to get certificate information" msgstr "No se pudo obtener la información del certificado" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Error al habilitar %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1738,6 +1748,11 @@ msgstr "No se pudo obtener la información del certificado" msgid "Failed to inspect container: {0}" msgstr "Error al habilitar %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Error al habilitar %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1762,6 +1777,11 @@ msgstr "Error al habilitar %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Error al habilitar %{msg}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1807,6 +1827,11 @@ msgstr "Falla al obtener el certificado" msgid "Failed to save Nginx performance settings" msgstr "No se pudo obtener la información del certificado" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Error al habilitar %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/fr_FR/app.po b/app/src/language/fr_FR/app.po index c725b0b7..1ed4cbe5 100644 --- a/app/src/language/fr_FR/app.po +++ b/app/src/language/fr_FR/app.po @@ -1656,6 +1656,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Impossible d'activer %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Impossible d'activer %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1778,6 +1783,11 @@ msgstr "Échec de l'obtention des informations sur le certificat" msgid "Failed to get certificate information" msgstr "Échec de l'obtention des informations sur le certificat" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Impossible d'activer %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1793,6 +1803,11 @@ msgstr "Échec de l'obtention des informations sur le certificat" msgid "Failed to inspect container: {0}" msgstr "Impossible d'activer %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Impossible d'activer %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1818,6 +1833,11 @@ msgstr "Impossible d'activer %{msg}" msgid "Failed to parse nginx.conf" msgstr "Erreur lecture nginx.conf" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Impossible d'activer %{msg}" + #: src/constants/errors/backup.ts:53 #, fuzzy msgid "Failed to read encrypted file: {0}" @@ -1868,6 +1888,11 @@ msgstr "Obtenir un certificat" msgid "Failed to save Nginx performance settings" msgstr "Échec de l'obtention des informations sur le certificat" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Impossible d'activer %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/ko_KR/app.po b/app/src/language/ko_KR/app.po index c1b17a6c..87208a60 100644 --- a/app/src/language/ko_KR/app.po +++ b/app/src/language/ko_KR/app.po @@ -1594,6 +1594,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "%{msg} 활성화 실패" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "%{msg} 활성화 실패" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1716,6 +1721,11 @@ msgstr "인증서 정보 가져오기 실패" msgid "Failed to get certificate information" msgstr "인증서 정보 가져오기 실패" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "%{msg} 활성화 실패" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1731,6 +1741,11 @@ msgstr "인증서 정보 가져오기 실패" msgid "Failed to inspect container: {0}" msgstr "%{msg} 활성화 실패" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "%{msg} 활성화 실패" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1755,6 +1770,11 @@ msgstr "%{msg} 활성화 실패" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "%{msg} 활성화 실패" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1800,6 +1820,11 @@ msgstr "인증서 획득 실패" msgid "Failed to save Nginx performance settings" msgstr "인증서 정보 가져오기 실패" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "%{msg} 활성화 실패" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/messages.pot b/app/src/language/messages.pot index d956619f..c2a6c992 100644 --- a/app/src/language/messages.pot +++ b/app/src/language/messages.pot @@ -1495,6 +1495,10 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "" +#: src/constants/errors/docker.ts:13 +msgid "Failed to create temp container: {0}" +msgstr "" + #: src/constants/errors/backup.ts:2 msgid "Failed to create temporary directory" msgstr "" @@ -1599,6 +1603,10 @@ msgstr "" msgid "Failed to get certificate information" msgstr "" +#: src/constants/errors/docker.ts:10 +msgid "Failed to get hostname: {0}" +msgstr "" + #: src/views/dashboard/components/ParamsOptimization.vue:61 msgid "Failed to get Nginx performance settings" msgstr "" @@ -1611,6 +1619,10 @@ msgstr "" msgid "Failed to inspect container: {0}" msgstr "" +#: src/constants/errors/docker.ts:12 +msgid "Failed to inspect current container: {0}" +msgstr "" + #: src/components/ConfigHistory/ConfigHistory.vue:77 msgid "Failed to load history records" msgstr "" @@ -1631,6 +1643,10 @@ msgstr "" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +msgid "Failed to pull image: {0}" +msgstr "" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1671,6 +1687,10 @@ msgstr "" msgid "Failed to save Nginx performance settings" msgstr "" +#: src/constants/errors/docker.ts:14 +msgid "Failed to start temp container: {0}" +msgstr "" + #: src/constants/errors/backup.ts:38 msgid "Failed to verify hashes: {0}" msgstr "" diff --git a/app/src/language/ru_RU/app.po b/app/src/language/ru_RU/app.po index 4abd7821..81da7cd2 100644 --- a/app/src/language/ru_RU/app.po +++ b/app/src/language/ru_RU/app.po @@ -1585,6 +1585,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Не удалось включить %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Не удалось включить %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1707,6 +1712,11 @@ msgstr "Не удалось получить информацию о серти msgid "Failed to get certificate information" msgstr "Не удалось получить информацию о сертификате" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Не удалось включить %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1722,6 +1732,11 @@ msgstr "Не удалось получить информацию о серти msgid "Failed to inspect container: {0}" msgstr "Не удалось включить %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Не удалось включить %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1746,6 +1761,11 @@ msgstr "Не удалось включить %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Не удалось включить %{msg}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1791,6 +1811,11 @@ msgstr "Не удалось получить сертификат" msgid "Failed to save Nginx performance settings" msgstr "Не удалось получить информацию о сертификате" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Не удалось включить %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/tr_TR/app.po b/app/src/language/tr_TR/app.po index 76d98562..7625c30f 100644 --- a/app/src/language/tr_TR/app.po +++ b/app/src/language/tr_TR/app.po @@ -1618,6 +1618,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Etkinleştirilemedi %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Etkinleştirilemedi %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1740,6 +1745,11 @@ msgstr "Sertifika bilgileri alınamadı" msgid "Failed to get certificate information" msgstr "Sertifika bilgileri alınamadı" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Etkinleştirilemedi %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1755,6 +1765,11 @@ msgstr "Sertifika bilgileri alınamadı" msgid "Failed to inspect container: {0}" msgstr "Etkinleştirilemedi %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Etkinleştirilemedi %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1779,6 +1794,11 @@ msgstr "Etkinleştirilemedi %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Etkinleştirilemedi %{msg}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1824,6 +1844,11 @@ msgstr "Sertifika alınamadı" msgid "Failed to save Nginx performance settings" msgstr "Sertifika bilgileri alınamadı" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Etkinleştirilemedi %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/uk_UA/app.po b/app/src/language/uk_UA/app.po index d476a811..9c8f29fa 100644 --- a/app/src/language/uk_UA/app.po +++ b/app/src/language/uk_UA/app.po @@ -1507,6 +1507,10 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "" +#: src/constants/errors/docker.ts:13 +msgid "Failed to create temp container: {0}" +msgstr "" + #: src/constants/errors/backup.ts:2 msgid "Failed to create temporary directory" msgstr "" @@ -1611,6 +1615,10 @@ msgstr "" msgid "Failed to get certificate information" msgstr "" +#: src/constants/errors/docker.ts:10 +msgid "Failed to get hostname: {0}" +msgstr "" + #: src/views/dashboard/components/ParamsOptimization.vue:61 msgid "Failed to get Nginx performance settings" msgstr "" @@ -1623,6 +1631,10 @@ msgstr "" msgid "Failed to inspect container: {0}" msgstr "" +#: src/constants/errors/docker.ts:12 +msgid "Failed to inspect current container: {0}" +msgstr "" + #: src/components/ConfigHistory/ConfigHistory.vue:77 msgid "Failed to load history records" msgstr "" @@ -1643,6 +1655,10 @@ msgstr "" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +msgid "Failed to pull image: {0}" +msgstr "" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1683,6 +1699,10 @@ msgstr "" msgid "Failed to save Nginx performance settings" msgstr "" +#: src/constants/errors/docker.ts:14 +msgid "Failed to start temp container: {0}" +msgstr "" + #: src/constants/errors/backup.ts:38 msgid "Failed to verify hashes: {0}" msgstr "" diff --git a/app/src/language/vi_VN/app.po b/app/src/language/vi_VN/app.po index 05bd0aea..56d16c4e 100644 --- a/app/src/language/vi_VN/app.po +++ b/app/src/language/vi_VN/app.po @@ -1634,6 +1634,11 @@ msgstr "" msgid "Failed to create symbolic link: {0}" msgstr "Không thể bật %{msg}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "Không thể bật %{msg}" + #: src/constants/errors/backup.ts:2 #, fuzzy msgid "Failed to create temporary directory" @@ -1756,6 +1761,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ" msgid "Failed to get certificate information" msgstr "Không thể truy xuất thông tin chứng chỉ" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "Không thể bật %{msg}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 #, fuzzy msgid "Failed to get Nginx performance settings" @@ -1771,6 +1781,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ" msgid "Failed to inspect container: {0}" msgstr "Không thể bật %{msg}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "Không thể bật %{msg}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 #, fuzzy msgid "Failed to load history records" @@ -1795,6 +1810,11 @@ msgstr "Không thể bật %{msg}" msgid "Failed to parse nginx.conf" msgstr "" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "Không thể bật %{msg}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "" @@ -1840,6 +1860,11 @@ msgstr "Nhận chứng chỉ" msgid "Failed to save Nginx performance settings" msgstr "Không thể truy xuất thông tin chứng chỉ" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "Không thể bật %{msg}" + #: src/constants/errors/backup.ts:38 #, fuzzy msgid "Failed to verify hashes: {0}" diff --git a/app/src/language/zh_CN/app.po b/app/src/language/zh_CN/app.po index b31375ba..3d82aacd 100644 --- a/app/src/language/zh_CN/app.po +++ b/app/src/language/zh_CN/app.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-04-19 14:14+0800\n" +"PO-Revision-Date: 2025-04-21 14:19+0800\n" "Last-Translator: 0xJacky \n" "Language-Team: Chinese (Simplified Han script) \n" @@ -679,7 +679,7 @@ msgstr "命令" #: src/constants/errors/docker.ts:6 msgid "Command exited with unexpected exit code: {0}, error: {1}" -msgstr "" +msgstr "命令以意外退出代码退出:{0},错误:{1}" #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115 #: src/components/NgxConfigEditor/LocationEditor.vue:104 @@ -758,7 +758,7 @@ msgstr "连接超时时间" #: src/constants/errors/docker.ts:7 msgid "Container status unknown" -msgstr "" +msgstr "未知容器状态" #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120 #: src/components/NgxConfigEditor/LocationEditor.vue:116 @@ -1168,7 +1168,7 @@ msgstr "你想删除这个 Upstream 吗?" #: src/constants/errors/docker.ts:2 msgid "Docker client not initialized" -msgstr "" +msgstr "Docker 客户端未初始化" #: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88 #: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16 @@ -1428,9 +1428,8 @@ msgid "Fail to obtain certificate" msgstr "获取证书失败" #: src/constants/errors/docker.ts:4 -#, fuzzy msgid "Failed to attach to exec instance: {0}" -msgstr "解压缩失败:{0}" +msgstr "连接执行实例失败:{0}" #: src/constants/errors/backup.ts:5 msgid "Failed to backup Nginx config files: {0}" @@ -1508,6 +1507,10 @@ msgstr "创建还原目录失败:{0}" msgid "Failed to create symbolic link: {0}" msgstr "创建符号链接失败:{0}" +#: src/constants/errors/docker.ts:13 +msgid "Failed to create temp container: {0}" +msgstr "创建临时容器失败:{0}" + #: src/constants/errors/backup.ts:2 msgid "Failed to create temporary directory" msgstr "创建临时目录失败" @@ -1593,9 +1596,8 @@ msgid "Failed to evaluate symbolic links: {0}" msgstr "符号链接解析失败:{0}" #: src/constants/errors/docker.ts:3 -#, fuzzy msgid "Failed to exec command: {0}" -msgstr "读取文件失败:{0}" +msgstr "执行命令失败:{0}" #: src/constants/errors/backup.ts:35 msgid "Failed to extract archive: {0}" @@ -1613,6 +1615,10 @@ msgstr "生成初始化向量失败:{0}" msgid "Failed to get certificate information" msgstr "获取证书信息失败" +#: src/constants/errors/docker.ts:10 +msgid "Failed to get hostname: {0}" +msgstr "获取主机名失败: {0}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 msgid "Failed to get Nginx performance settings" msgstr "获取 Nginx 性能参数失败" @@ -1622,9 +1628,12 @@ msgid "Failed to get performance data" msgstr "获取性能数据失败" #: src/constants/errors/docker.ts:8 -#, fuzzy msgid "Failed to inspect container: {0}" -msgstr "复制文件内容失败:{0}" +msgstr "检查容器失败:{0}" + +#: src/constants/errors/docker.ts:12 +msgid "Failed to inspect current container: {0}" +msgstr "检查当前容器失败:{0}" #: src/components/ConfigHistory/ConfigHistory.vue:77 msgid "Failed to load history records" @@ -1646,6 +1655,10 @@ msgstr "打开压缩文件失败:{0}" msgid "Failed to parse nginx.conf" msgstr "解析 nginx.conf 失败" +#: src/constants/errors/docker.ts:11 +msgid "Failed to pull image: {0}" +msgstr "拉取镜像失败:{0}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "读取加密文件失败:{0}" @@ -1663,9 +1676,8 @@ msgid "Failed to read nginx.conf" msgstr "读取 nginx.conf 失败" #: src/constants/errors/docker.ts:5 -#, fuzzy msgid "Failed to read output: {0}" -msgstr "读取文件失败:{0}" +msgstr "读取输出失败:{0}" #: src/constants/errors/backup.ts:21 msgid "Failed to read symlink: {0}" @@ -1687,6 +1699,10 @@ msgstr "证书撤销失败" msgid "Failed to save Nginx performance settings" msgstr "保存 Nginx 性能参数失败" +#: src/constants/errors/docker.ts:14 +msgid "Failed to start temp container: {0}" +msgstr "启动临时容器失败:{0}" + #: src/constants/errors/backup.ts:38 msgid "Failed to verify hashes: {0}" msgstr "验证哈希值失败:{0}" @@ -2535,9 +2551,8 @@ msgid "Nginx is not running" msgstr "Nginx 未启动" #: src/constants/errors/docker.ts:9 -#, fuzzy msgid "Nginx is not running in another container" -msgstr "Nginx 未启动" +msgstr "Nginx 未在另一个容器中运行" #: src/views/dashboard/NginxDashBoard.vue:112 msgid "Nginx is running" @@ -3225,9 +3240,8 @@ msgid "Reload Nginx" msgstr "重载 Nginx" #: src/constants/errors/nginx.ts:3 -#, fuzzy msgid "Reload nginx failed: {0}" -msgstr "Nginx 重载失败:{0}" +msgstr "重载 Nginx 失败: {0}" #: src/components/Notification/notifications.ts:10 msgid "Reload Nginx on %{node} failed, response: %{resp}" @@ -3653,19 +3667,19 @@ msgstr "使用 HTTP01 challenge provider" #: src/constants/errors/nginx_log.ts:8 msgid "" -"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://nginxui." -"com/guide/config-nginx.html for more information" +"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://" +"nginxui.com/guide/config-nginx.html for more information" msgstr "" -"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://nginxui." -"com/guide/config-nginx.html" +"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://" +"nginxui.com/guide/config-nginx.html" #: src/constants/errors/nginx_log.ts:7 msgid "" -"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://nginxui." -"com/guide/config-nginx.html for more information" +"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://" +"nginxui.com/guide/config-nginx.html for more information" msgstr "" -"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://nginxui." -"com/guide/config-nginx.html" +"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://" +"nginxui.com/guide/config-nginx.html" #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:147 msgid "Shared Memory Zone" @@ -4682,8 +4696,8 @@ msgstr "你的 Passkeys" #~ msgstr "请将远程 Nginx UI 升级到最新版本" #~ msgid "" -#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: " -#~ "%{resp}" +#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %" +#~ "{resp}" #~ msgstr "" #~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}" diff --git a/app/src/language/zh_TW/app.po b/app/src/language/zh_TW/app.po index 6c82a17a..c680afe0 100644 --- a/app/src/language/zh_TW/app.po +++ b/app/src/language/zh_TW/app.po @@ -1518,6 +1518,11 @@ msgstr "無法建立還原目錄:{0}" msgid "Failed to create symbolic link: {0}" msgstr "建立符號連結失敗:{0}" +#: src/constants/errors/docker.ts:13 +#, fuzzy +msgid "Failed to create temp container: {0}" +msgstr "無法建立壓縮項目:{0}" + #: src/constants/errors/backup.ts:2 msgid "Failed to create temporary directory" msgstr "無法建立臨時目錄" @@ -1623,6 +1628,11 @@ msgstr "無法生成初始化向量:{0}" msgid "Failed to get certificate information" msgstr "取得憑證資訊失敗" +#: src/constants/errors/docker.ts:10 +#, fuzzy +msgid "Failed to get hostname: {0}" +msgstr "複製檔案內容失敗:{0}" + #: src/views/dashboard/components/ParamsOptimization.vue:61 msgid "Failed to get Nginx performance settings" msgstr "無法取得 Nginx 效能設定" @@ -1636,6 +1646,11 @@ msgstr "無法取得效能資料" msgid "Failed to inspect container: {0}" msgstr "複製檔案內容失敗:{0}" +#: src/constants/errors/docker.ts:12 +#, fuzzy +msgid "Failed to inspect current container: {0}" +msgstr "複製檔案內容失敗:{0}" + #: src/components/ConfigHistory/ConfigHistory.vue:77 msgid "Failed to load history records" msgstr "無法載入歷史記錄" @@ -1656,6 +1671,11 @@ msgstr "無法開啟壓縮檔:{0}" msgid "Failed to parse nginx.conf" msgstr "解析 nginx.conf 失敗" +#: src/constants/errors/docker.ts:11 +#, fuzzy +msgid "Failed to pull image: {0}" +msgstr "讀取檔案失敗:{0}" + #: src/constants/errors/backup.ts:53 msgid "Failed to read encrypted file: {0}" msgstr "無法讀取加密檔案:{0}" @@ -1697,6 +1717,11 @@ msgstr "撤銷憑證失敗" msgid "Failed to save Nginx performance settings" msgstr "儲存 Nginx 效能設定失敗" +#: src/constants/errors/docker.ts:14 +#, fuzzy +msgid "Failed to start temp container: {0}" +msgstr "複製檔案內容失敗:{0}" + #: src/constants/errors/backup.ts:38 msgid "Failed to verify hashes: {0}" msgstr "無法驗證雜湊值:{0}" diff --git a/internal/cmd/main.go b/internal/cmd/main.go index 5bbb1fad..85b6ff60 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -26,10 +26,11 @@ func NewAppCmd() *cli.Command { }, }, { - Name: "reset-password", - Usage: "Reset the initial user password", + Name: "reset-password", + Usage: "Reset the initial user password", Action: user.ResetInitUserPassword, }, + UpgradeDockerStep2Command, }, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/internal/cmd/upgrade_docker.go b/internal/cmd/upgrade_docker.go new file mode 100644 index 00000000..ab77f599 --- /dev/null +++ b/internal/cmd/upgrade_docker.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "context" + + "github.com/0xJacky/Nginx-UI/internal/docker" + "github.com/uozi-tech/cosy/logger" + "github.com/urfave/cli/v3" +) + +// Command to be executed in the temporary container +var UpgradeDockerStep2Command = &cli.Command{ + Name: "upgrade-docker-step2", + Usage: "Execute the second step of Docker container upgrade (to be run inside the temp container)", + Action: UpgradeDockerStep2, +} + +// UpgradeDockerStep2 executes the second step in the temporary container +func UpgradeDockerStep2(ctx context.Context, command *cli.Command) error { + logger.Info("Starting Docker OTA upgrade step 2 from CLI...") + + return docker.UpgradeStepTwo(ctx) +} diff --git a/internal/docker/errors.go b/internal/docker/errors.go index 3499894c..a5494b06 100644 --- a/internal/docker/errors.go +++ b/internal/docker/errors.go @@ -12,4 +12,9 @@ var ( ErrContainerStatusUnknown = e.New(500006, "container status unknown") ErrInspectContainer = e.New(500007, "failed to inspect container: {0}") ErrNginxNotRunningInAnotherContainer = e.New(500008, "nginx is not running in another container") + ErrFailedToGetHostname = e.New(500009, "failed to get hostname: {0}") + ErrFailedToPullImage = e.New(500010, "failed to pull image: {0}") + ErrFailedToInspectCurrentContainer = e.New(500011, "failed to inspect current container: {0}") + ErrFailedToCreateTempContainer = e.New(500012, "failed to create temp container: {0}") + ErrFailedToStartTempContainer = e.New(500013, "failed to start temp container: {0}") ) diff --git a/internal/docker/ota.go b/internal/docker/ota.go new file mode 100644 index 00000000..c77b703f --- /dev/null +++ b/internal/docker/ota.go @@ -0,0 +1,329 @@ +package docker + +import ( + "context" + "fmt" + "io" + "os" + "strings" + "time" + + "github.com/0xJacky/Nginx-UI/internal/upgrader" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/client" + "github.com/pkg/errors" + "github.com/uozi-tech/cosy" + "github.com/uozi-tech/cosy/logger" +) + +const ( + ImageName = "uozi/nginx-ui" + TempPrefix = "nginx-ui-temp-" + OldSuffix = "_old" +) + +// getTimestampedTempName returns a temporary container name with timestamp +func getTimestampedTempName() string { + return fmt.Sprintf("%s%d", TempPrefix, time.Now().Unix()) +} + +// removeAllTempContainers removes all containers with the TempPrefix +func removeAllTempContainers(ctx context.Context, cli *client.Client) (err error) { + containers, err := cli.ContainerList(ctx, container.ListOptions{All: true}) + if err != nil { + return + } + + for _, c := range containers { + for _, name := range c.Names { + processedName := strings.TrimPrefix(name, "/") + if strings.HasPrefix(processedName, TempPrefix) { + err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true}) + if err != nil { + logger.Error("Failed to remove temp container:", err) + } else { + logger.Info("Successfully removed temp container:", processedName) + } + break + } + } + } + + return nil +} + +// UpgradeStepOne Trigger in the OTA upgrade +func UpgradeStepOne(channel string) (err error) { + ctx := context.Background() + + // 1. Get the tag of the latest release + release, err := upgrader.GetRelease(channel) + if err != nil { + return err + } + tag := release.TagName + + // 2. Pull the image + cli, err := initClient() + if err != nil { + return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error()) + } + defer cli.Close() + + // Pull the image with the specified tag + out, err := cli.ImagePull(ctx, fmt.Sprintf("%s:%s", ImageName, tag), image.PullOptions{}) + if err != nil { + return cosy.WrapErrorWithParams(ErrFailedToPullImage, err.Error()) + } + defer out.Close() + + // Wait for pull to complete by reading the output + io.Copy(os.Stdout, out) + + // 3. Create a temp container + // Clean up any existing temp containers + err = removeAllTempContainers(ctx, cli) + if err != nil { + logger.Error("Failed to clean up existing temp containers:", err) + // Continue execution despite cleanup errors + } + + // Generate timestamped temp container name + tempContainerName := getTimestampedTempName() + + // Get current container name + hostname, err := os.Hostname() + if err != nil { + return cosy.WrapErrorWithParams(ErrFailedToGetHostname, err.Error()) + } + containerInfo, err := cli.ContainerInspect(ctx, hostname) + if err != nil { + return cosy.WrapErrorWithParams(ErrFailedToInspectCurrentContainer, err.Error()) + } + currentContainerName := strings.TrimPrefix(containerInfo.Name, "/") + + // Set up the command for the temp container to execute step 2 + upgradeCmd := []string{"./nginx-ui", "upgrade-docker-step2"} + + // Add old container name as environment variable + containerEnv := containerInfo.Config.Env + containerEnv = append(containerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName)) + + // Create temp container using new image + _, err = cli.ContainerCreate( + ctx, + &container.Config{ + Image: fmt.Sprintf("%s:%s", ImageName, tag), + Cmd: upgradeCmd, // Use upgrade command instead of original command + Env: containerEnv, + }, + &container.HostConfig{ + Binds: containerInfo.HostConfig.Binds, + PortBindings: containerInfo.HostConfig.PortBindings, + RestartPolicy: containerInfo.HostConfig.RestartPolicy, + }, + nil, + nil, + tempContainerName, + ) + if err != nil { + return cosy.WrapErrorWithParams(ErrFailedToCreateTempContainer, err.Error()) + } + + // Start the temp container to execute step 2 + err = cli.ContainerStart(ctx, tempContainerName, container.StartOptions{}) + if err != nil { + return cosy.WrapErrorWithParams(ErrFailedToStartTempContainer, err.Error()) + } + + // Output status information + logger.Info("Docker OTA upgrade step 1 completed. Temp container started to execute step 2.") + + return nil +} + +// UpgradeStepTwo Trigger in the temp container +func UpgradeStepTwo(ctx context.Context) (err error) { + // 1. Copy the old config + cli, err := initClient() + if err != nil { + return + } + defer cli.Close() + + // Get old container name from environment variable, fallback to settings if not available + currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME") + if currentContainerName == "" { + return errors.New("could not find old container name") + } + // Get the current running temp container name + // Since we can't directly get our own container name from inside, we'll search all temp containers + containers, err := cli.ContainerList(ctx, container.ListOptions{All: true}) + if err != nil { + return errors.Wrap(err, "failed to list containers") + } + + // Find containers with the temp prefix + var tempContainerName string + for _, c := range containers { + for _, name := range c.Names { + processedName := strings.TrimPrefix(name, "/") + if strings.HasPrefix(processedName, TempPrefix) { + tempContainerName = processedName + break + } + } + if tempContainerName != "" { + break + } + } + + if tempContainerName == "" { + return errors.New("could not find temp container") + } + + // Get temp container info to get the new image + tempContainerInfo, err := cli.ContainerInspect(ctx, tempContainerName) + if err != nil { + return errors.Wrap(err, "failed to inspect temp container") + } + newImage := tempContainerInfo.Config.Image + + // Get current container info + oldContainerInfo, err := cli.ContainerInspect(ctx, currentContainerName) + if err != nil { + return errors.Wrap(err, "failed to inspect current container") + } + + // 2. Stop the old container and rename to _old + err = cli.ContainerStop(ctx, currentContainerName, container.StopOptions{}) + if err != nil { + return errors.Wrap(err, "failed to stop current container") + } + + // Rename the old container with _old suffix + err = cli.ContainerRename(ctx, currentContainerName, currentContainerName+OldSuffix) + if err != nil { + return errors.Wrap(err, "failed to rename old container") + } + + // 3. Use the old config to create and start a new container with the updated image + // Create new container with original config but using the new image + newContainerEnv := oldContainerInfo.Config.Env + // Pass the old container name to the new container + newContainerEnv = append(newContainerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName)) + + _, err = cli.ContainerCreate( + ctx, + &container.Config{ + Image: newImage, + Cmd: oldContainerInfo.Config.Cmd, + Env: newContainerEnv, + Entrypoint: oldContainerInfo.Config.Entrypoint, + Labels: oldContainerInfo.Config.Labels, + ExposedPorts: oldContainerInfo.Config.ExposedPorts, + Volumes: oldContainerInfo.Config.Volumes, + WorkingDir: oldContainerInfo.Config.WorkingDir, + }, + &container.HostConfig{ + Binds: oldContainerInfo.HostConfig.Binds, + PortBindings: oldContainerInfo.HostConfig.PortBindings, + RestartPolicy: oldContainerInfo.HostConfig.RestartPolicy, + NetworkMode: oldContainerInfo.HostConfig.NetworkMode, + Mounts: oldContainerInfo.HostConfig.Mounts, + Privileged: oldContainerInfo.HostConfig.Privileged, + }, + nil, + nil, + currentContainerName, + ) + if err != nil { + // If creation fails, try to recover + recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName) + if recoverErr == nil { + // Start old container + recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{}) + if recoverErr == nil { + return errors.Wrap(err, "failed to create new container, recovered to old container") + } + } + return errors.Wrap(err, "failed to create new container and failed to recover") + } + + // Start the new container + err = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{}) + if err != nil { + // If startup fails, try to recover + // First remove the failed new container + removeErr := cli.ContainerRemove(ctx, currentContainerName, container.RemoveOptions{Force: true}) + if removeErr != nil { + logger.Error("Failed to remove failed new container:", removeErr) + } + + // Rename the old container back to original + recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName) + if recoverErr == nil { + // Start old container + recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{}) + if recoverErr == nil { + return errors.Wrap(err, "failed to start new container, recovered to old container") + } + } + return errors.Wrap(err, "failed to start new container and failed to recover") + } + + logger.Info("Docker OTA upgrade step 2 completed successfully. New container is running.") + return nil +} + +// UpgradeStepThree Trigger in the new container +func UpgradeStepThree() error { + ctx := context.Background() + // Remove the old container + cli, err := initClient() + if err != nil { + return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error()) + } + defer cli.Close() + + // Get old container name from environment variable, fallback to settings if not available + currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME") + if currentContainerName == "" { + logger.Warn("Old container name not found in environment, skipping cleanup") + return nil + } + oldContainerName := currentContainerName + OldSuffix + + // Check if old container exists and remove it if it does + containers, err := cli.ContainerList(ctx, container.ListOptions{All: true}) + if err != nil { + return errors.Wrap(err, "failed to list containers") + } + + for _, c := range containers { + for _, name := range c.Names { + processedName := strings.TrimPrefix(name, "/") + // Remove old container + if processedName == oldContainerName { + err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true}) + if err != nil { + logger.Error("Failed to remove old container:", err) + // Continue execution, don't interrupt because of failure to remove old container + } else { + logger.Info("Successfully removed old container:", oldContainerName) + } + break + } + } + } + + // Clean up all temp containers + err = removeAllTempContainers(ctx, cli) + if err != nil { + logger.Error("Failed to clean up temp containers:", err) + // Continue execution despite cleanup errors + } + + return nil +} diff --git a/internal/kernel/boot.go b/internal/kernel/boot.go index f5a2fd2a..2d3555c8 100644 --- a/internal/kernel/boot.go +++ b/internal/kernel/boot.go @@ -12,6 +12,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cluster" "github.com/0xJacky/Nginx-UI/internal/cron" + "github.com/0xJacky/Nginx-UI/internal/docker" "github.com/0xJacky/Nginx-UI/internal/passkey" "github.com/0xJacky/Nginx-UI/internal/validation" "github.com/0xJacky/Nginx-UI/model" @@ -35,6 +36,7 @@ func Boot() { InitCryptoSecret, validation.Init, cache.Init, + CheckAndCleanupOTAContainers, } syncs := []func(){ @@ -129,3 +131,14 @@ func InitJsExtensionType() { // See https://github.com/golang/go/issues/32350 _ = mime.AddExtensionType(".js", "text/javascript; charset=utf-8") } + +// CheckAndCleanupOTAContainers Check and cleanup OTA update temporary containers +func CheckAndCleanupOTAContainers() { + // Execute the third step cleanup operation at startup + err := docker.UpgradeStepThree() + if err != nil { + logger.Error("Failed to cleanup OTA containers:", err) + } else { + logger.Info("OTA container cleanup completed successfully") + } +}