Skip to content

Commit f7f764f

Browse files
authored
Merge pull request #4047 from bgruszka/release/v2
fix: compose intercept ignores httpFilters due to missing http mechanism
2 parents 21e6a33 + a00f239 commit f7f764f

File tree

10 files changed

+192
-87
lines changed

10 files changed

+192
-87
lines changed

.github/actions/install-dependencies/action.yaml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,24 @@ runs:
4040
brew install jq
4141
fi
4242
- if: runner.os == 'Windows'
43-
name: setup make and zip
43+
name: setup make
4444
shell: pwsh
4545
run: |
4646
# Use make from Git for Windows (pre-installed on runners)
4747
echo "C:\Program Files\Git\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Append
48-
# Download Info-ZIP (Git for Windows only has unzip, not zip)
49-
Invoke-WebRequest -Uri "https://www.willus.com/archive/zip64/infozip_binaries_win32.zip" -OutFile infozip.zip
50-
Expand-Archive -Path infozip.zip -DestinationPath C:\infozip
51-
echo "C:\infozip" | Out-File -FilePath $env:GITHUB_PATH -Append
48+
- if: runner.os == 'Windows'
49+
name: download Info-ZIP
50+
uses: nick-fields/retry/@v3
51+
with:
52+
max_attempts: 3
53+
timeout_minutes: 1
54+
shell: pwsh
55+
command: |
56+
$ErrorActionPreference = 'Stop'
57+
# Download Info-ZIP (Git for Windows only has unzip, not zip)
58+
Invoke-WebRequest -Uri "https://www.willus.com/archive/zip64/infozip_binaries_win32.zip" -OutFile infozip.zip
59+
Expand-Archive -Path infozip.zip -DestinationPath C:\infozip
60+
echo "C:\infozip" | Out-File -FilePath $env:GITHUB_PATH -Append
5261
- if: runner.os == 'Windows'
5362
name: download winfsp
5463
uses: nick-fields/retry/@v3

.github/workflows/dev.yaml

Lines changed: 26 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,26 @@ on:
44
types:
55
- labeled
66

7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
711
env:
8-
TELEPRESENCE_REGISTRY: ghcr.io/telepresenceio
12+
TELEPRESENCE_REGISTRY: local
913

1014
jobs:
11-
build_images:
15+
build_and_test:
1216
if: ${{ github.event.label.name == 'ok to test' || github.event.label.name == 'compatibility test' }}
13-
runs-on: ubuntu-latest
14-
outputs:
15-
telepresenceVersion: ${{ steps.version.outputs.version }}
16-
telepresenceSemver: ${{ steps.version.outputs.semver }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
runners:
21+
- ubuntu-latest
22+
# Re-enable when we can run a proper cluster. Colima almost works on macOS but the very limited
23+
# resources available make the test fail very often. On windows, we'll need WSL2
24+
# - macos-latest
25+
# - windows-latest
26+
runs-on: ${{ matrix.runners }}
1727
steps:
1828
- name: Remove ok to test label
1929
if: github.event.label.name == 'ok to test'
@@ -33,62 +43,27 @@ jobs:
3343
with:
3444
fetch-depth: 0
3545
ref: "${{ github.event.pull_request.head.sha }}"
46+
- name: install dependencies
47+
uses: ./.github/actions/install-dependencies
3648
- name: Get Telepresence Version
3749
id: version
3850
run: |
3951
v=$(go run build-aux/genversion/main.go ${{github.run_id}})
4052
echo "TELEPRESENCE_VERSION=$v" >> "$GITHUB_ENV"
4153
echo "TELEPRESENCE_SEMVER=${v#v}" >> "$GITHUB_ENV"
42-
echo "version=$v" >> $GITHUB_OUTPUT
43-
echo "semver=${v#v}" >> $GITHUB_OUTPUT
44-
- name: Setup docker buildx
45-
uses: docker/setup-buildx-action@v3
46-
with:
47-
platforms: linux/amd64,linux/arm64
48-
- name: Build image dependencies
49-
run: make images-deps
50-
- name: Log in to registry
51-
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
52-
- name: Push client image
53-
run: |
54-
docker buildx build --platform=linux/amd64,linux/arm64 --build-arg TELEPRESENCE_VERSION=${{env.TELEPRESENCE_SEMVER}} \
55-
--push --tag ${{env.TELEPRESENCE_REGISTRY}}/telepresence:${{env.TELEPRESENCE_SEMVER}} -f build-aux/docker/images/Dockerfile.client .
56-
- name: Push tel2 image
57-
run: |
58-
docker buildx build --platform=linux/amd64,linux/arm64 --build-arg TELEPRESENCE_VERSION=${{env.TELEPRESENCE_SEMVER}} \
59-
--push --tag ${{env.TELEPRESENCE_REGISTRY}}/tel2:${{env.TELEPRESENCE_SEMVER}} -f build-aux/docker/images/Dockerfile.traffic .
60-
- name: Log out from registry
61-
if: always()
62-
run: docker logout
63-
64-
run_tests:
65-
if: ${{ github.event.label.name == 'ok to test' || github.event.label.name == 'compatibility test' }}
66-
strategy:
67-
fail-fast: false
68-
matrix:
69-
runners:
70-
- ubuntu-latest
71-
# Re-enable when we can run a proper cluster. Colima almost works on macOS but the very limited
72-
# resources available make the test fail very often. On windows, we'll need WSL2
73-
# - macos-latest
74-
# - windows-latest
75-
runs-on: ${{ matrix.runners }}
76-
needs: build_images
77-
env:
78-
TELEPRESENCE_VERSION: ${{ needs.build_images.outputs.telepresenceVersion }}
79-
steps:
80-
- uses: actions/checkout@v4
81-
with:
82-
ref: "${{ github.event.pull_request.head.sha }}"
83-
- name: install dependencies
84-
uses: ./.github/actions/install-dependencies
8554
- name: Start minikube
8655
if: runner.os == 'Linux'
8756
uses: medyagh/setup-minikube@latest
8857
with:
8958
kubernetes-version: v1.33.5
9059
- name: Build client
9160
run: make build
61+
- name: Build images
62+
run: make client-image tel2-image
63+
- name: Load images into minikube
64+
run: |
65+
minikube image load ${{env.TELEPRESENCE_REGISTRY}}/telepresence:${{env.TELEPRESENCE_SEMVER}}
66+
minikube image load ${{env.TELEPRESENCE_REGISTRY}}/tel2:${{env.TELEPRESENCE_SEMVER}}
9267
- name: Run integration tests
9368
if: github.event.label.name == 'ok to test'
9469
uses: nick-fields/retry/@v3
@@ -106,6 +81,7 @@ jobs:
10681
if: ${{ github.event.label.name == 'compatibility test' }}
10782
env:
10883
DEV_MANAGER_VERSION: "2.24.1"
84+
DEV_MANAGER_REGISTRY: ghcr.io/telepresenceio
10985
uses: nick-fields/retry/@v3
11086
with:
11187
max_attempts: 3
@@ -121,6 +97,7 @@ jobs:
12197
if: ${{ github.event.label.name == 'compatibility test' }}
12298
env:
12399
DEV_CLIENT_VERSION: "2.24.1"
100+
DEV_CLIENT_REGISTRY: ghcr.io/telepresenceio
124101
uses: nick-fields/retry/@v3
125102
with:
126103
max_attempts: 3
@@ -136,30 +113,3 @@ jobs:
136113
env:
137114
LOG_SUFFIX: "${{ runner.os }}-${{ runner.arch }}-${{ matrix.clusters.distribution }}-${{ matrix.clusters.version }}"
138115
if: ${{ always() }}
139-
purge_images:
140-
if: ${{ always() }}
141-
runs-on: ubuntu-latest
142-
permissions:
143-
packages: write
144-
needs:
145-
- build_images
146-
- run_tests
147-
steps:
148-
- name: Delete tel2 and telepresence image
149-
uses: dataaxiom/ghcr-cleanup-action@v1
150-
continue-on-error: true
151-
with:
152-
owner: telepresenceio
153-
packages: tel2,telepresence
154-
token: ${{ secrets.GITHUB_TOKEN }}
155-
delete-tags: ${{ needs.build_images.outputs.telepresenceSemver }}
156-
- name: Prune tel2 and telepresence
157-
uses: dataaxiom/ghcr-cleanup-action@v1
158-
with:
159-
owner: telepresenceio
160-
packages: tel2,telepresence
161-
token: ${{ secrets.GITHUB_TOKEN }}
162-
delete-untagged: true
163-
delete-ghost-images: true
164-
delete-partial-images: true
165-
delete-orphaned-images: true

.github/workflows/release.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ jobs:
215215
v=${{ github.ref_name }}
216216
packaging/homebrew-package.sh "${v#v}" "${{ vars.GH_BOT_USER }}" "${{ vars.GH_BOT_EMAIL }}" "${{ secrets.HOMEBREW_TAP_TOKEN }}"
217217
218+
prune-images:
219+
if: ${{ always() }}
220+
runs-on: ubuntu-latest
221+
permissions:
222+
packages: write
223+
needs:
224+
- push-images
225+
steps:
226+
- name: Prune tel2 and telepresence
227+
uses: dataaxiom/ghcr-cleanup-action@v1
228+
with:
229+
owner: telepresenceio
230+
packages: tel2,telepresence
231+
token: ${{ secrets.GITHUB_TOKEN }}
232+
delete-untagged: true
233+
delete-ghost-images: true
234+
delete-partial-images: true
235+
delete-orphaned-images: true
236+
218237
test-release:
219238
needs:
220239
- push-images

CHANGELOG.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ 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+
- version: 2.26.2
56+
date: 2026-02-05
57+
notes:
58+
- type: bugfix
59+
title: Fix HTTP intercepts via telepresence compose failing when httpFilters or httpPaths are set
60+
body: >-
61+
The compose extension set HeaderFilters and PathFilters on the intercept spec but left the mechanism as "tcp".
62+
This caused the traffic manager to reject the intercept with "global TCP/UDP intercepts are disabled".
63+
The mechanism is now correctly switched to "http" when any HTTP filters are specified, matching the behavior
64+
of the CLI intercept command.
5565
- version: 2.26.1
5666
date: 2026-01-26
5767
notes:

docs/release-notes.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ 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+
## Version 2.26.2 <span style="font-size: 16px;">(February 5)</span>
24+
## <div style="display:flex;"><img src="images/bugfix.png" alt="bugfix" style="width:30px;height:fit-content;"/><div style="display:flex;margin-left:7px;">Fix HTTP intercepts via telepresence compose failing when httpFilters or httpPaths are set</div></div>
25+
<div style="margin-left: 15px">
26+
27+
The compose extension set HeaderFilters and PathFilters on the intercept spec but left the mechanism as "tcp". This caused the traffic manager to reject the intercept with "global TCP/UDP intercepts are disabled". The mechanism is now correctly switched to "http" when any HTTP filters are specified, matching the behavior of the CLI intercept command.
28+
</div>
29+
2330
## Version 2.26.1 <span style="font-size: 16px;">(January 26)</span>
2431
## <div style="display:flex;"><img src="images/bugfix.png" alt="bugfix" style="width:30px;height:fit-content;"/><div style="display:flex;margin-left:7px;">[Add support for "warning" as an alias for "warn" in log levels](https://github.com/telepresenceio/telepresence/issues/4043)</div></div>
2532
<div style="margin-left: 15px">

docs/release-notes.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ 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+
## Version 2.26.2 <span style={{fontSize:'16px'}}>(February 5)</span>
30+
<Note>
31+
<Title type="bugfix">Fix HTTP intercepts via telepresence compose failing when httpFilters or httpPaths are set</Title>
32+
<Body>
33+
The compose extension set HeaderFilters and PathFilters on the intercept spec but left the mechanism as "tcp". This caused the traffic manager to reject the intercept with "global TCP/UDP intercepts are disabled". The mechanism is now correctly switched to "http" when any HTTP filters are specified, matching the behavior of the CLI intercept command.
34+
</Body>
35+
</Note>
2936
## Version 2.26.1 <span style={{fontSize:'16px'}}>(January 26)</span>
3037
<Note>
3138
<Title type="bugfix" docs="https://github.com/telepresenceio/telepresence/issues/4043">Add support for "warning" as an alias for "warn" in log levels</Title>

docs/variables.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version: "2.27.0"
2-
dlVersion: "v2.27.0"
2+
dlVersion: "v2.27.0"

integration_test/itest/helm.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,16 @@ func (s *cluster) TelepresenceHelmInstall(ctx context.Context, upgrade bool, set
260260
}
261261

262262
vx.Image = GetImage(ctx)
263-
if !s.isCI && s.ManagerVersion().EQ(s.ClientVersion()) {
264-
pp := "Always"
263+
if s.ManagerVersion().EQ(s.ClientVersion()) {
265264
if s.ManagerRegistry() == "local" {
266265
// Using minikube with local images.
267266
// They are automatically present and must not be pulled.
268-
pp = "Never"
267+
vx.Image.PullPolicy = "Never"
268+
vx.Agent.Image.PullPolicy = "Never"
269+
} else if !s.isCI {
270+
vx.Image.PullPolicy = "Always"
271+
vx.Agent.Image.PullPolicy = "Always"
269272
}
270-
vx.Image.PullPolicy = pp
271-
vx.Agent.Image.PullPolicy = pp
272273
}
273274

274275
ss, err := yaml.Marshal(&vx)

pkg/client/cli/docker/compose/extension.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ func (e *httpFilterExtension) amendInterceptSpec(spec *manager.InterceptSpec) er
273273
}
274274
spec.HeaderFilters = e.HttpFilters
275275
spec.PathFilters = intercept.BuildPathFilters(e.Paths, e.PathPrefixes, e.PathRegexps)
276+
if len(spec.HeaderFilters) > 0 || len(spec.PathFilters) > 0 {
277+
spec.Mechanism = "http"
278+
}
276279
spec.Metadata = e.Metadata
277280
return nil
278281
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package compose
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/telepresenceio/telepresence/rpc/v2/manager"
10+
"github.com/telepresenceio/telepresence/v2/pkg/types"
11+
)
12+
13+
func TestAmendInterceptSpec_MechanismSetToHTTP(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
httpFilters map[string]string
17+
httpPaths []string
18+
httpPathPrefixes []string
19+
httpPathRegexps []string
20+
expectedMechanism string
21+
}{
22+
{
23+
name: "no filters leaves mechanism as tcp",
24+
expectedMechanism: "tcp",
25+
},
26+
{
27+
name: "header filter switches mechanism to http",
28+
httpFilters: map[string]string{"x-dev-id": "jdoe"},
29+
expectedMechanism: "http",
30+
},
31+
{
32+
name: "multiple header filters switch mechanism to http",
33+
httpFilters: map[string]string{"x-dev-id": "jdoe", "x-env": "staging"},
34+
expectedMechanism: "http",
35+
},
36+
{
37+
name: "exact path filter switches mechanism to http",
38+
httpPaths: []string{"/api/v1/users"},
39+
expectedMechanism: "http",
40+
},
41+
{
42+
name: "path prefix filter switches mechanism to http",
43+
httpPathPrefixes: []string{"/api/"},
44+
expectedMechanism: "http",
45+
},
46+
{
47+
name: "path regex filter switches mechanism to http",
48+
httpPathRegexps: []string{`/api/v[0-9]+/.*`},
49+
expectedMechanism: "http",
50+
},
51+
{
52+
name: "headers and paths together switch mechanism to http",
53+
httpFilters: map[string]string{"x-dev-id": "jdoe"},
54+
httpPathPrefixes: []string{"/api/"},
55+
expectedMechanism: "http",
56+
},
57+
}
58+
59+
for _, tt := range tests {
60+
t.Run(tt.name, func(t *testing.T) {
61+
ext := &httpFilterExtension{
62+
HttpFilters: tt.httpFilters,
63+
Paths: tt.httpPaths,
64+
PathPrefixes: tt.httpPathPrefixes,
65+
PathRegexps: tt.httpPathRegexps,
66+
Ports: []types.PortMapping{"3005:3005"},
67+
}
68+
69+
spec := &manager.InterceptSpec{Mechanism: "tcp"}
70+
err := ext.amendInterceptSpec(spec)
71+
require.NoError(t, err)
72+
assert.Equal(t, tt.expectedMechanism, spec.Mechanism)
73+
})
74+
}
75+
}
76+
77+
func TestAmendInterceptSpec_HeaderFiltersPopulated(t *testing.T) {
78+
filters := map[string]string{"x-dev-id": "jdoe", "x-env": "staging"}
79+
ext := &httpFilterExtension{
80+
HttpFilters: filters,
81+
Ports: []types.PortMapping{"3005:3005"},
82+
}
83+
84+
spec := &manager.InterceptSpec{Mechanism: "tcp"}
85+
err := ext.amendInterceptSpec(spec)
86+
require.NoError(t, err)
87+
assert.Equal(t, filters, spec.HeaderFilters)
88+
}
89+
90+
func TestAmendInterceptSpec_NoPorts_ReturnsError(t *testing.T) {
91+
ext := &httpFilterExtension{
92+
HttpFilters: map[string]string{"x-dev-id": "jdoe"},
93+
}
94+
95+
spec := &manager.InterceptSpec{Mechanism: "tcp"}
96+
err := ext.amendInterceptSpec(spec)
97+
require.Error(t, err)
98+
assert.Contains(t, err.Error(), "requires at least one port")
99+
}

0 commit comments

Comments
 (0)