-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23486 from ben-krieger/connection-base-path
Use HTTP path prefix of TCP connections to match Docker context behavior
- Loading branch information
Showing
2 changed files
with
113 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,18 @@ | |
package integration | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"net/http" | ||
"net/http/httputil" | ||
"net/url" | ||
"os" | ||
"os/exec" | ||
"os/user" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
|
||
. "github.com/containers/podman/v5/test/utils" | ||
. "github.com/onsi/ginkgo/v2" | ||
|
@@ -119,6 +125,22 @@ QA-UDS1 unix:///run/user/podman/podman.sock false true | |
Expect(session.OutputToString()).To(Equal("QA-TCP tcp://localhost:8888 true true")) | ||
}) | ||
|
||
It("add tcp to reverse proxy path", func() { | ||
cmd := []string{"system", "connection", "add", | ||
"QA-TCP-RP", | ||
"tcp://localhost:8888/reverse/proxy/path/prefix", | ||
} | ||
session := podmanTest.Podman(cmd) | ||
session.WaitWithDefaultTimeout() | ||
Expect(session).Should(ExitCleanly()) | ||
Expect(session.Out.Contents()).Should(BeEmpty()) | ||
|
||
session = podmanTest.Podman(systemConnectionListCmd) | ||
session.WaitWithDefaultTimeout() | ||
Expect(session).Should(ExitCleanly()) | ||
Expect(session.OutputToString()).To(Equal("QA-TCP-RP tcp://localhost:8888/reverse/proxy/path/prefix true true")) | ||
}) | ||
|
||
It("add to new farm", func() { | ||
cmd := []string{"system", "connection", "add", | ||
"--default", | ||
|
@@ -315,6 +337,91 @@ qe ssh://[email protected]:2222/run/podman/podman.sock ~/.ssh/id_rsa false true | |
}) | ||
}) | ||
|
||
Context("with running API service", func() { | ||
BeforeEach(func() { | ||
SkipIfNotRemote("requires podman API service") | ||
}) | ||
|
||
It("add tcp:// connection with reverse proxy path", func() { | ||
// Create a reverse proxy to the podman socket using path prefix | ||
const pathPrefix = "/reverse/proxy/path/prefix" | ||
proxyGotUsed := false | ||
proxy := http.NewServeMux() | ||
proxy.Handle(pathPrefix+"/", &httputil.ReverseProxy{ | ||
Rewrite: func(pr *httputil.ProxyRequest) { | ||
proxyGotUsed = true | ||
pr.Out.URL.Path = strings.TrimPrefix(pr.Out.URL.Path, pathPrefix) | ||
pr.Out.URL.RawPath = strings.TrimPrefix(pr.Out.URL.RawPath, pathPrefix) | ||
baseURL, _ := url.Parse("http://d") | ||
pr.SetURL(baseURL) | ||
}, | ||
Transport: &http.Transport{ | ||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { | ||
By("Proxying to " + podmanTest.RemoteSocket) | ||
url, err := url.Parse(podmanTest.RemoteSocket) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return (&net.Dialer{}).DialContext(ctx, "unix", url.Path) | ||
}, | ||
}, | ||
}) | ||
srv := &http.Server{ | ||
Handler: proxy, | ||
ReadHeaderTimeout: time.Second, | ||
} | ||
|
||
// Serve the reverse proxy on a random port | ||
lis, err := net.Listen("tcp", "127.0.0.1:0") | ||
Expect(err).ToNot(HaveOccurred()) | ||
defer lis.Close() | ||
|
||
defer srv.Close() | ||
go func() { | ||
defer GinkgoRecover() | ||
Expect(srv.Serve(lis)).To(MatchError(http.ErrServerClosed)) | ||
}() | ||
|
||
connectionURL := "tcp://" + lis.Addr().String() + pathPrefix | ||
|
||
cmd := exec.Command(podmanTest.RemotePodmanBinary, | ||
"system", "connection", "add", | ||
"--default", "QA", connectionURL, | ||
) | ||
session, err := Start(cmd, GinkgoWriter, GinkgoWriter) | ||
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("%q failed to execute", podmanTest.RemotePodmanBinary)) | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(0)) | ||
Expect(session.Out.Contents()).Should(BeEmpty()) | ||
Expect(session.Err.Contents()).Should(BeEmpty()) | ||
|
||
Expect(proxyGotUsed).To(BeFalse()) | ||
cmd = exec.Command(podmanTest.RemotePodmanBinary, | ||
"--connection", "QA", "ps") | ||
session, err = Start(cmd, GinkgoWriter, GinkgoWriter) | ||
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("%q failed to execute", podmanTest.RemotePodmanBinary)) | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(0)) | ||
Expect(session.Out.Contents()).Should(Equal([]byte(`CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | ||
`))) | ||
Expect(session.Err.Contents()).Should(BeEmpty()) | ||
Expect(proxyGotUsed).To(BeTrue()) | ||
|
||
// export the container_host env var and try again | ||
proxyGotUsed = false | ||
err = os.Setenv("CONTAINER_HOST", connectionURL) | ||
Expect(err).ToNot(HaveOccurred()) | ||
defer os.Unsetenv("CONTAINER_HOST") | ||
|
||
cmd = exec.Command(podmanTest.RemotePodmanBinary, "ps") | ||
session, err = Start(cmd, GinkgoWriter, GinkgoWriter) | ||
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("%q failed to execute", podmanTest.RemotePodmanBinary)) | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(0)) | ||
Expect(session.Out.Contents()).Should(Equal([]byte(`CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | ||
`))) | ||
Expect(session.Err.Contents()).Should(BeEmpty()) | ||
Expect(proxyGotUsed).To(BeTrue()) | ||
}) | ||
}) | ||
|
||
Context("sshd and API services required", func() { | ||
BeforeEach(func() { | ||
// These tests are unique in as much as they require podman, podman-remote, systemd and sshd. | ||
|