Skip to content

Commit 7e842ae

Browse files
authored
Merge pull request #3813 from telepresenceio/thallgren/auto-mounts
Improved control over remote volume mounts using mount policies
2 parents 37270b9 + cd56512 commit 7e842ae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3286
-2144
lines changed

CHANGELOG.yml

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ items:
9191
values: <namespaces>`.
9292
```
9393
docs: install/manager#static-versus-dynamic-namespace-selection
94+
- type: feature
95+
title: Improved control over how remote volumes are mounted using mount policies
96+
body: |-
97+
Mount policies, that affects how the telepresence traffic-agent shares the pod's volumes, and also how the
98+
client will mount them, can now be provided using the Helm chart value `agent.mountPolicies` or as JSON
99+
object in the workload annotation `telepresence.io/mount-policies`. A mount policy is applied to a volume
100+
or to all paths matching a path-prefix (distinguished by checking if first character is a '/'), and can
101+
be one of `Ignore`, `Local`, `Remote`, or `RemoteReadOnly`.
94102
- type: feature
95103
title: List output includes workload kind.
96104
body: >-

DEPENDENCIES.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ following Free and Open Source software:
129129
github.com/spf13/cobra v1.8.1 Apache License 2.0
130130
github.com/spf13/pflag v1.0.6 3-clause BSD license
131131
github.com/stretchr/testify v1.10.0 MIT license
132-
github.com/telepresenceio/go-fuseftp v0.6.1 Apache License 2.0
133-
github.com/telepresenceio/go-fuseftp/rpc v0.6.1 Apache License 2.0
132+
github.com/telepresenceio/go-fuseftp v0.6.2 Apache License 2.0
133+
github.com/telepresenceio/go-fuseftp/rpc v0.6.2 Apache License 2.0
134134
github.com/telepresenceio/telepresence/rpc/v2 (modified) Apache License 2.0
135135
github.com/vishvananda/netlink v1.3.0 Apache License 2.0
136136
github.com/vishvananda/netns v0.0.5 Apache License 2.0

charts/telepresence-oss/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The following tables lists the configurable parameters of the Telepresence chart
3030
| agent.image.registry | The registry for the injected agent image | `ghcr.io/telepresenceio` |
3131
| agent.initResources | The resources for the injected init container | |
3232
| agent.logLevel | The logging level for the traffic-agent | defaults to logLevel |
33+
| agent.mountPolicies | The policies for the agents. Key is either volume name or path prefix starting with '/' | `/tmp`: Local |
3334
| agent.resources | The resources for the injected agent container | |
3435
| agent.securityContext | The security context to use for the injected agent container | defaults to the securityContext of the first container of the app |
3536
| agent.initSecurityContext | The security context to use for the injected init container | `{}` |

charts/telepresence-oss/templates/deployment.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ spec:
135135
- name: AGENT_INIT_RESOURCES
136136
value: '{{ toJson .initResources }}'
137137
{{- end }}
138+
{{- if .mountPolicies }}
139+
- name: AGENT_MOUNT_POLICIES
140+
value: '{{ toJson .mountPolicies }}'
141+
{{- end }}
138142
{{- with .image }}
139143
{{- if .name }}
140144
- name: AGENT_IMAGE_NAME

charts/telepresence-oss/values.schema.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ properties:
2222
- portName
2323
- http
2424
- http2
25+
mountPolicies:
26+
description: 'List of volume mount policies. Defaults to {"/tmp" : "Ignore"}'
27+
type: object
28+
additionalProperties:
29+
description: The name or path prefix match of the volume that the policy applies to
30+
type: string
31+
enum:
32+
- Remote
33+
- RemoteReadOnly
34+
- Local
35+
- Ignore
2536
image:
2637
type: object
2738
additionalProperties: false

charts/telepresence-oss/values.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ agentInjector:
127127
agent:
128128
appProtocolStrategy: http2Probe
129129
port: 9900
130+
mountPolicies:
131+
"/tmp": Local
130132
image:
131133
pullPolicy: IfNotPresent
132134

cmd/traffic/cmd/agent/agent.go

+25-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"runtime/debug"
14+
"sort"
1415
"strings"
1516
"time"
1617

@@ -40,7 +41,7 @@ var DisplayName = "OSS Traffic Agent" //nolint:gochecknoglobals // extension poi
4041
// AppEnvironment returns the environment visible to this agent together with environment variables
4142
// explicitly declared for the app container and minus the environment variables provided by this
4243
// config.
43-
func AppEnvironment(ctx context.Context, ag *agentconfig.Container) (map[string]string, error) {
44+
func AppEnvironment(ctx context.Context, mounts agentconfig.MountPolicies, ag *agentconfig.Container) (map[string]string, error) {
4445
osEnv := dos.Environ(ctx)
4546
prefix := agentconfig.EnvPrefixApp + ag.EnvPrefix
4647
fullEnv := make(map[string]string, len(osEnv))
@@ -76,8 +77,25 @@ func AppEnvironment(ctx context.Context, ag *agentconfig.Container) (map[string]
7677
}
7778
}
7879
fullEnv[agentconfig.EnvInterceptContainer] = ag.Name
79-
if len(ag.Mounts) > 0 {
80-
fullEnv[agentconfig.EnvInterceptMounts] = strings.Join(ag.Mounts, ":")
80+
if len(mounts) > 0 {
81+
var localMounts, remoteMounts []string
82+
for path, policy := range mounts {
83+
switch policy {
84+
case agentconfig.MountPolicyIgnore:
85+
case agentconfig.MountPolicyRemote, agentconfig.MountPolicyRemoteReadOnly:
86+
remoteMounts = append(remoteMounts, path)
87+
case agentconfig.MountPolicyLocal:
88+
localMounts = append(localMounts, path)
89+
}
90+
}
91+
if len(localMounts) > 0 {
92+
sort.Strings(localMounts)
93+
fullEnv[agentconfig.EnvLocalMounts] = strings.Join(localMounts, ":")
94+
}
95+
if len(remoteMounts) > 0 {
96+
sort.Strings(remoteMounts)
97+
fullEnv[agentconfig.EnvInterceptMounts] = strings.Join(remoteMounts, ":")
98+
}
8199
}
82100
return fullEnv, nil
83101
}
@@ -278,7 +296,7 @@ func StartServices(ctx context.Context, g *dgroup.Group, config Config, srv Stat
278296

279297
sftpPortCh := make(chan uint16)
280298
ftpPortCh := make(chan uint16)
281-
if config.HasMounts(ctx) {
299+
if config.HasRemoteMounts() {
282300
g.Go("sftp-server", func(ctx context.Context) error {
283301
return sftpServer(ctx, sftpPortCh)
284302
})
@@ -316,13 +334,15 @@ func StartServices(ctx context.Context, g *dgroup.Group, config Config, srv Stat
316334

317335
containers := make(map[string]*rpc.AgentInfo_ContainerInfo, len(ac.Containers))
318336
for _, cn := range ac.Containers {
319-
env, err := AppEnvironment(ctx, cn)
337+
appMounts := cn.Mounts
338+
env, err := AppEnvironment(ctx, appMounts, cn)
320339
if err != nil {
321340
return nil, err
322341
}
323342
containers[cn.Name] = &rpc.AgentInfo_ContainerInfo{
324343
Environment: env,
325344
MountPoint: filepath.Join(agentconfig.ExportsMountPoint, filepath.Base(cn.MountPoint)),
345+
Mounts: appMounts.ToRPC(),
326346
}
327347
}
328348

cmd/traffic/cmd/agent/agent_test.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package agent_test
22

33
import (
44
"context"
5+
"path/filepath"
56
"runtime"
67
"testing"
78

@@ -39,7 +40,12 @@ var testConfig = agentconfig.Sidecar{
3940
Name: "test-echo",
4041
EnvPrefix: "A_",
4142
MountPoint: "/tel_app_mounts/test-echo",
42-
Mounts: []string{"/home/bob"},
43+
MountPaths: []string{"/home/bob"},
44+
Mounts: map[string]agentconfig.MountPolicy{
45+
"/tmp": agentconfig.MountPolicyLocal,
46+
"/home/bob": agentconfig.MountPolicyRemote,
47+
"/home/brianna": agentconfig.MountPolicyRemoteReadOnly,
48+
},
4349
Intercepts: []*agentconfig.Intercept{
4450
{
4551
ContainerPortName: "http",
@@ -60,8 +66,13 @@ func testContext(t *testing.T, env dos.MapEnv) context.Context {
6066
if env == nil {
6167
env = make(dos.MapEnv)
6268
}
69+
6370
require.NoError(t, fs.MkdirAll(agentconfig.ExportsMountPoint, 0o700))
6471

72+
home := filepath.Join("/tel_app_mounts/test-echo", "home")
73+
require.NoError(t, fs.MkdirAll(filepath.Join(home, "bob"), 0o700))
74+
require.NoError(t, fs.MkdirAll(filepath.Join(home, "brianna"), 0o700))
75+
6576
cfgJSON, err := agentconfig.MarshalTight(&testConfig)
6677
require.NoError(t, err)
6778

@@ -101,12 +112,13 @@ func Test_AppEnvironment(t *testing.T) {
101112
require.NoError(t, err)
102113

103114
cn := config.AgentConfig().Containers[0]
104-
env, err := agent.AppEnvironment(ctx, cn)
115+
env, err := agent.AppEnvironment(ctx, cn.Mounts, cn)
105116
require.NoError(t, err)
106117
require.Equal(t, map[string]string{
107118
"ALPHA": "alpha",
108119
"ZULU": "zulu",
109120
agentconfig.EnvInterceptContainer: "test-echo",
110-
agentconfig.EnvInterceptMounts: "/home/bob",
121+
agentconfig.EnvInterceptMounts: "/home/bob:/home/brianna",
122+
agentconfig.EnvLocalMounts: "/tmp",
111123
}, env)
112124
}

0 commit comments

Comments
 (0)