From ec744db3352c6c258b80ff994089b25ab2351976 Mon Sep 17 00:00:00 2001 From: Christian Weichel Date: Sun, 31 Oct 2021 14:19:59 +0000 Subject: [PATCH] [workspacekit] Make resolv.conf writeable --- components/workspacekit/cmd/rings.go | 45 ++++++++++++++++++++++- components/workspacekit/cmd/rings_test.go | 3 -- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/components/workspacekit/cmd/rings.go b/components/workspacekit/cmd/rings.go index f4c060988e393a..5ba5d6a1150c11 100644 --- a/components/workspacekit/cmd/rings.go +++ b/components/workspacekit/cmd/rings.go @@ -343,6 +343,14 @@ var ring1Cmd = &cobra.Command{ } } + // We deliberately do not bind mount `/etc/resolv.conf`, but instead place a copy + // so that users in the workspace can modify the file. + err = copyResolvConf(ring2Root) + if err != nil { + log.WithError(err).Error("cannot copy resolv.conf") + return + } + env := make([]string, 0, len(os.Environ())) for _, e := range os.Environ() { if strings.HasPrefix(e, "WORKSPACEKIT_") { @@ -565,7 +573,9 @@ var ( "/dev", "/etc/hosts", "/etc/hostname", - "/etc/resolv.conf", + } + rejectMountPaths = map[string]struct{}{ + "/etc/resolv.conf": {}, } ) @@ -613,6 +623,11 @@ func findBindMountCandidates(procMounts io.Reader, readlink func(path string) (d continue } + // reject known paths + if _, ok := rejectMountPaths[path]; ok { + continue + } + // test remaining candidates if they're a Kubernetes configMap or secret ln, err := readlink(filepath.Join(path, "..data")) if err != nil { @@ -627,6 +642,34 @@ func findBindMountCandidates(procMounts io.Reader, readlink func(path string) (d return mounts, scanner.Err() } +// copyResolvConf copies /etc/resolv.conf to /etc/resolv.conf +func copyResolvConf(ring2root string) error { + fn := "/etc/resolv.conf" + stat, err := os.Stat(fn) + if err != nil { + return err + } + + org, err := os.Open(fn) + if err != nil { + return err + } + defer org.Close() + + dst, err := os.OpenFile(filepath.Join(ring2root, fn), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, stat.Mode()) + if err != nil { + return err + } + defer dst.Close() + + _, err = io.Copy(dst, org) + if err != nil { + return err + } + + return nil +} + func receiveSeccmpFd(conn *net.UnixConn) (libseccomp.ScmpFd, error) { buf := make([]byte, unix.CmsgSpace(4)) diff --git a/components/workspacekit/cmd/rings_test.go b/components/workspacekit/cmd/rings_test.go index d06e85c9e45502..04117a93f01e04 100644 --- a/components/workspacekit/cmd/rings_test.go +++ b/components/workspacekit/cmd/rings_test.go @@ -30,7 +30,6 @@ func TestFindBindMountCandidates(t *testing.T) { "/workspace", "/etc/hosts", "/etc/hostname", - "/etc/resolv.conf", }, }, { @@ -42,7 +41,6 @@ func TestFindBindMountCandidates(t *testing.T) { "/sys", "/etc/hosts", "/etc/hostname", - "/etc/resolv.conf", }, }, { @@ -60,7 +58,6 @@ func TestFindBindMountCandidates(t *testing.T) { "/workspace", "/etc/hosts", "/etc/hostname", - "/etc/resolv.conf", "/custom-certs", }, },