mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-10 04:12:08 +08:00
feat(linux): reinstall an existing Service during package upgrades
The deb and rpm packages never refreshed an installed Service, and the previous package's prerm/%preun uninstalls it unconditionally. When the Service unit existed before the upgrade, the new postinst/%post now reinstalls it with its group and restores disabled, enabled-runtime, masked-runtime and stopped states. First installs and explicit removals never add a Service. rpm runs the new %post before the old %preun. %post records the transaction process (pid and start time) in /run, and /usr/bin/clash-verge-service-uninstall becomes a wrapper that skips only that %preun call and otherwise runs the real uninstaller, now under /usr/lib/clash-verge-rev. deb has no such ordering: an upgrade from a released version still loses the Service, and later deb upgrades reinstall it in place only once the prerm upgrade guard from #8240 ships. The scripts exit 0, because a failing postinst or %post cannot restore the Service. On failure they write /run/clash-verge-service-upgrade instead; package script output never reaches the GUI. At startup the app offers a reinstall if the Service is not ready and warns if its previous state was not restored. Both notices replay when a window subscribes, and the marker is acknowledged only after both are taken. In-app updates stop a Service-run core and hold the core lifecycle until the package manager exits, including after the 30-second startup timeout. Refs #8515 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -550,9 +550,16 @@ const SERVICE_BINARIES = [
|
||||
'clash-verge-service-uninstall',
|
||||
]
|
||||
|
||||
// Linux packages install the uninstaller under /usr/lib behind a wrapper sidecar; see
|
||||
// src-tauri/packages/linux/service-uninstall.sh and the files entries in tauri.linux.conf.json.
|
||||
const LINUX_UNINSTALLER_FILE = 'clash-verge-service-uninstall-bin'
|
||||
|
||||
function serviceFileInfo(name) {
|
||||
const ext = platform === 'win32' ? '.exe' : ''
|
||||
const suffix = platform === 'linux' ? `-${SIDECAR_HOST}` : ''
|
||||
if (platform === 'linux' && name === 'clash-verge-service-uninstall') {
|
||||
return { sourceFile: name, targetFile: LINUX_UNINSTALLER_FILE }
|
||||
}
|
||||
return {
|
||||
sourceFile: `${name}${ext}`,
|
||||
targetFile: `${name}${suffix}${ext}`,
|
||||
@@ -573,6 +580,22 @@ async function findExtractedFile(dir, fileName) {
|
||||
}
|
||||
|
||||
async function resolveServiceBundle() {
|
||||
await fetchServiceBundle()
|
||||
if (platform === 'linux') {
|
||||
const wrapper = path.join(
|
||||
SERVICE_DIR,
|
||||
`clash-verge-service-uninstall-${SIDECAR_HOST}`,
|
||||
)
|
||||
await fsp.copyFile(
|
||||
path.join(cwd, 'src-tauri', 'packages', 'linux', 'service-uninstall.sh'),
|
||||
wrapper,
|
||||
)
|
||||
await fsp.chmod(wrapper, 0o755)
|
||||
await updateHashCache(wrapper)
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchServiceBundle() {
|
||||
const files = SERVICE_BINARIES.map((name) => {
|
||||
const info = serviceFileInfo(name)
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user