Skip to content

Commit 47bb6d0

Browse files
committed
Add automatic cache cleanup on version change
Track the CLI version in a version.json file in the cache directory. When a version mismatch is detected, quit running daemons and clear stale cache entries (preserving logs) to prevent issues from leftover files after an upgrade. Signed-off-by: Thomas Hallgren <thomas@tada.se>
1 parent 350b979 commit 47bb6d0

File tree

5 files changed

+72
-5
lines changed

5 files changed

+72
-5
lines changed

CHANGELOG.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ items:
5252
the need for elevated privileges when using Telepresence. Currently available for amd64 architecture only
5353
due to dependency constraints.
5454
docs: install/client
55+
- type: feature
56+
title: Automatic cache cleanup on version change
57+
body: >-
58+
Telepresence now tracks its version in a version.json file in the cache directory. When the CLI detects
59+
that the major.minor version differs from the running binary, it automatically quits running daemons and
60+
clears stale cache entries (preserving logs). This prevents issues caused by leftover cache files from a
61+
previous version. Patch and pre-release version changes do not trigger a cache cleanup.
5562
- version: 2.26.2
5663
date: 2026-02-14
5764
notes:

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ Run `make generate` and commit changes to `DEPENDENCY_LICENSES.md` and `DEPENDEN
195195
- `pkg/agentconfig/` - Traffic-agent configuration
196196
- `pkg/client/k8s/` - Kubernetes client interactions
197197
- `pkg/routing/` - Network routing logic
198+
- `pkg/client/cli/cmd/` - CLI commands. One per file.
198199

199200
### RPC Definitions
200201

docs/release-notes.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ New Linux package installers (.deb for Debian/Ubuntu and .rpm for Fedora/RHEL) a
2020
A new Windows installer (.exe) is now available that installs Telepresence with the root daemon configured as a Windows service. The installer bundles WinFSP and SSHFS-Win dependencies for volume mount support, adds Telepresence to the system PATH, and optionally installs the TelepresenceDaemon service. This eliminates the need for elevated privileges when using Telepresence. Currently available for amd64 architecture only due to dependency constraints.
2121
</div>
2222

23+
## <div style="display:flex;"><img src="images/feature.png" alt="feature" style="width:30px;height:fit-content;"/><div style="display:flex;margin-left:7px;">Automatic cache cleanup on version change</div></div>
24+
<div style="margin-left: 15px">
25+
26+
Telepresence now tracks its version in a version.json file in the cache directory. When the CLI detects that the major.minor version differs from the running binary, it automatically quits running daemons and clears stale cache entries (preserving logs). This prevents issues caused by leftover cache files from a previous version. Patch and pre-release version changes do not trigger a cache cleanup.
27+
</div>
28+
2329
## Version 2.26.2 <span style="font-size: 16px;">(February 14)</span>
2430
## <div style="display:flex;"><img src="images/bugfix.png" alt="bugfix" style="width:30px;height:fit-content;"/><div style="display:flex;margin-left:7px;">[Dial 127.0.0.1 instead of 0.0.0.0 when connecting to local daemons](https://github.com/telepresenceio/telepresence/issues/4048)</div></div>
2531
<div style="margin-left: 15px">

docs/release-notes.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ New Linux package installers (.deb for Debian/Ubuntu and .rpm for Fedora/RHEL) a
2626
A new Windows installer (.exe) is now available that installs Telepresence with the root daemon configured as a Windows service. The installer bundles WinFSP and SSHFS-Win dependencies for volume mount support, adds Telepresence to the system PATH, and optionally installs the TelepresenceDaemon service. This eliminates the need for elevated privileges when using Telepresence. Currently available for amd64 architecture only due to dependency constraints.
2727
</Body>
2828
</Note>
29+
<Note>
30+
<Title type="feature">Automatic cache cleanup on version change</Title>
31+
<Body>
32+
Telepresence now tracks its version in a version.json file in the cache directory. When the CLI detects that the major.minor version differs from the running binary, it automatically quits running daemons and clears stale cache entries (preserving logs). This prevents issues caused by leftover cache files from a previous version. Patch and pre-release version changes do not trigger a cache cleanup.
33+
</Body>
34+
</Note>
2935
## Version 2.26.2 <span style={{fontSize:'16px'}}>(February 14)</span>
3036
<Note>
3137
<Title type="bugfix" docs="https://github.com/telepresenceio/telepresence/issues/4048">Dial 127.0.0.1 instead of 0.0.0.0 when connecting to local daemons</Title>

pkg/client/cli/cmd/telepresence.go

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,30 @@ package cmd
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"io/fs"
68
"os"
9+
"path/filepath"
710
"strings"
811

12+
"github.com/blang/semver/v4"
913
"github.com/spf13/cobra"
1014

1115
"github.com/telepresenceio/clog"
1216
"github.com/telepresenceio/telepresence/v2/pkg/client"
17+
"github.com/telepresenceio/telepresence/v2/pkg/client/cache"
18+
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/connect"
1319
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/daemon"
1420
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/global"
1521
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/output"
1622
"github.com/telepresenceio/telepresence/v2/pkg/client/docker/kubeauth"
1723
"github.com/telepresenceio/telepresence/v2/pkg/client/rootd"
1824
userDaemon "github.com/telepresenceio/telepresence/v2/pkg/client/userd/daemon"
1925
"github.com/telepresenceio/telepresence/v2/pkg/errcat"
26+
"github.com/telepresenceio/telepresence/v2/pkg/filelocation"
2027
"github.com/telepresenceio/telepresence/v2/pkg/maps"
28+
"github.com/telepresenceio/telepresence/v2/pkg/version"
2129
)
2230

2331
// Telepresence returns the top level "telepresence" CLI command.
@@ -29,11 +37,16 @@ func Telepresence(ctx context.Context, args []string) *cobra.Command {
2937
longHelp = helpMarkdown
3038
}
3139
rootCmd := &cobra.Command{
32-
Use: "telepresence",
33-
Args: OnlySubcommands,
34-
Short: "Connect your workstation to a Kubernetes cluster",
35-
Long: longHelp,
36-
PersistentPreRunE: output.SetFormat,
40+
Use: "telepresence",
41+
Args: OnlySubcommands,
42+
Short: "Connect your workstation to a Kubernetes cluster",
43+
Long: longHelp,
44+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
45+
if err := output.SetFormat(cmd, args); err != nil {
46+
return err
47+
}
48+
return ensureCacheVersion(cmd, args)
49+
},
3750
RunE: RunSubcommands,
3851
SilenceErrors: true, // main() will handle it after .ExecuteContext() returns
3952
SilenceUsage: true, // our FlagErrorFunc will handle it
@@ -230,3 +243,37 @@ func autocompleteContext(cmd *cobra.Command, _ []string, toComplete string) ([]s
230243
}
231244
return nss, cobra.ShellCompDirectiveNoFileComp
232245
}
246+
247+
type versionFile struct {
248+
Version semver.Version `json:"version"`
249+
}
250+
251+
func ensureCacheVersion(cmd *cobra.Command, _ []string) error {
252+
ctx := cmd.Context()
253+
var vf versionFile
254+
majorMinorMatch := false
255+
if err := cache.LoadFromUserCache(ctx, &vf, "version.json"); err == nil {
256+
majorMinorMatch = vf.Version.Major == version.Structured.Major && vf.Version.Minor == version.Structured.Minor
257+
if majorMinorMatch {
258+
return nil
259+
}
260+
}
261+
262+
// Quit all daemons (best effort, ignore errors).
263+
connect.Quit(ctx)
264+
265+
// Clear cache except logs.
266+
cacheDir := filelocation.AppUserCacheDir(ctx)
267+
entries, err := os.ReadDir(cacheDir)
268+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
269+
return err
270+
}
271+
for _, entry := range entries {
272+
if entry.Name() == "logs" {
273+
continue
274+
}
275+
_ = os.RemoveAll(filepath.Join(cacheDir, entry.Name()))
276+
}
277+
278+
return cache.SaveToUserCache(ctx, &versionFile{Version: version.Structured}, "version.json", cache.Public)
279+
}

0 commit comments

Comments
 (0)