Skip to content

Commit

Permalink
Add containerd path marker file (#813)
Browse files Browse the repository at this point in the history
We need to properly clean up the containerd path on snap removal.
For that, the path needs to be stored in a file.
This serves two purposes:
1. The existence of the file indicates that the cluster was already bootstrapped
   and the containerd directory is not created by some other service.
2. The containerd path is configurable, having this information in a file makes it easy
   to access even after the k8sd service is already stopped.
  • Loading branch information
bschimke95 authored Nov 20, 2024
1 parent 00236be commit 83c1ffb
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 6 deletions.
12 changes: 11 additions & 1 deletion k8s/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ k8s::common::is_strict() {
# Cleanup configuration left by the network feature
k8s::remove::network() {
k8s::common::setup_env

"${SNAP}/bin/kube-proxy" --cleanup || true

k8s::cmd::k8s x-cleanup network || true
Expand Down Expand Up @@ -94,6 +94,16 @@ k8s::remove::containers() {
done
}

k8s::remove::containerd() {
k8s::common::setup_env

# only remove containerd if the snap was already bootstrapped.
# this is to prevent removing containerd when it is not installed by the snap.
if [ -f "$SNAP_COMMON/lock/containerd-socket-path" ]; then
rm -f $(cat "$SNAP_COMMON/lock/containerd-socket-path")
fi
}

# Run a ctr command against the local containerd socket
# Example: 'k8s::cmd::ctr image ls -q'
k8s::cmd::ctr() {
Expand Down
2 changes: 2 additions & 0 deletions snap/hooks/remove
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ k8s::common::setup_env
k8s::remove::containers

k8s::remove::network

k8s::remove::containerd
5 changes: 5 additions & 0 deletions src/k8s/pkg/k8sd/setup/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ func Containerd(snap snap.Snap, extraContainerdConfig map[string]any, extraArgs
}
}

// Write the containerd socket path to a file to properly clean-up on removal.
if err := utils.WriteFile(filepath.Join(snap.LockFilesDir(), "containerd-socket-path"), []byte(snap.ContainerdSocketDir()), 0o600); err != nil {
return fmt.Errorf("failed to write containerd-socket-path: %w", err)
}

return nil
}

Expand Down
7 changes: 7 additions & 0 deletions src/k8s/pkg/k8sd/setup/containerd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,11 @@ func TestContainerd(t *testing.T) {
g.Expect(val).To(BeZero())
})
})

t.Run("Lockfile", func(t *testing.T) {
g := NewWithT(t)
b, err := os.ReadFile(filepath.Join(s.LockFilesDir(), "containerd-socket-path"))
g.Expect(err).To(Not(HaveOccurred()))
g.Expect(string(b)).To(Equal(s.ContainerdSocketDir()))
})
}
11 changes: 6 additions & 5 deletions src/k8s/pkg/snap/snap.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,16 @@ func (s *snap) PreInitChecks(ctx context.Context, config types.ClusterConfig) er
}
}

// check if the containerd.sock file already exists, signaling the fact that another containerd instance
// check if the containerd path already exists, signaling the fact that another containerd instance
// is already running on this node, which will conflict with the snap.
socketPath := s.ContainerdSocketPath()
if _, err := os.Stat(socketPath); err == nil {
// Checks the directories instead of the containerd.sock file, since this file does not exist if
// containerd is not running/stopped.
if _, err := os.Stat(s.ContainerdSocketDir()); err == nil {
return fmt.Errorf("The path '%s' required for the containerd socket already exists. "+
"This may mean that another service is already using that path, and it conflicts with the k8s snap. "+
"Please make sure that there is no other service installed that uses the same path, and remove the existing file.", socketPath)
"Please make sure that there is no other service installed that uses the same path, and remove the existing directory.", s.ContainerdSocketDir())
} else if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("Encountered an error while checking '%s': %w", socketPath, err)
return fmt.Errorf("Encountered an error while checking '%s': %w", s.ContainerdSocketDir(), err)
}

return nil
Expand Down

0 comments on commit 83c1ffb

Please sign in to comment.