-
Notifications
You must be signed in to change notification settings - Fork 59
Fix Complement not using HSPortBindingIP
(127.0.0.1
) for the homeserver BaseURL
#781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
8689525
Fix Complement not using `HSPortBindingIP` (`127.0.0.1`) for the home…
MadLittleMods cdeb5ec
Better docstrings
MadLittleMods 5077e33
Incorporate empty `HostIP` podman edge case
MadLittleMods 1bfe471
URL grammar
MadLittleMods 64147f1
Clarify `HSPortBindingIP` better
MadLittleMods 39edab5
Add docs for `ContainerInspectionError` being returned
MadLittleMods e17f4db
Make `ContainerInspectionError` private
MadLittleMods 4eb1cb6
Use idiomatic Go doc comments
MadLittleMods 39c2ac2
Remove incorrect fallback when we can't find a matching port binding
MadLittleMods da98b90
Update to `waitForContainer`
MadLittleMods e33cbc8
Revert "Update to `waitForContainer`"
MadLittleMods cb2586f
Actually look for ports in `waitForPorts`
MadLittleMods b91e723
Fix new args missing
MadLittleMods 50ea132
Returns error on failure
MadLittleMods 616981f
`HSPortBindingIP` doc-comment usage nuance
MadLittleMods File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 |
---|---|---|
|
@@ -313,9 +313,13 @@ func (d *Deployer) StartServer(hsDep *HomeserverDeployment) error { | |
} | ||
|
||
// Wait for the container to be ready. | ||
baseURL, fedBaseURL, err := waitForPorts(ctx, d.Docker, hsDep.ContainerID) | ||
err = waitForPorts(ctx, d.Docker, hsDep.ContainerID) | ||
if err != nil { | ||
return fmt.Errorf("failed to get ports for container %s: %s", hsDep.ContainerID, err) | ||
return fmt.Errorf("failed to wait for ports on container %s: %s", hsDep.ContainerID, err) | ||
} | ||
baseURL, fedBaseURL, err := getHostAccessibleHomeserverUrls(ctx, d.Docker, hsDep.ContainerID, d.config.HSPortBindingIP) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clean things up, I've refactored |
||
if err != nil { | ||
return fmt.Errorf("failed to get host accessible homeserver URL's from container %s: %s", hsDep.ContainerID, err) | ||
} | ||
hsDep.SetEndpoints(baseURL, fedBaseURL) | ||
|
||
|
@@ -441,10 +445,19 @@ func deployImage( | |
log.Printf("%s: Started container %s", contextStr, containerID) | ||
} | ||
|
||
baseURL, fedBaseURL, err := waitForPorts(ctx, docker, containerID) | ||
// Wait for the container to be ready. | ||
err = waitForPorts(ctx, docker, containerID) | ||
if err != nil { | ||
return stubDeployment, fmt.Errorf("%s : image %s : %w", contextStr, imageID, err) | ||
return stubDeployment, fmt.Errorf("%s: failed to wait for ports on container %s: %w", contextStr, containerID, err) | ||
} | ||
baseURL, fedBaseURL, err := getHostAccessibleHomeserverUrls(ctx, docker, containerID, cfg.HSPortBindingIP) | ||
if err != nil { | ||
return stubDeployment, fmt.Errorf( | ||
"%s: failed to get host accessible homeserver URL's from container %s: %s", | ||
contextStr, containerID, err, | ||
) | ||
} | ||
|
||
inspect, err := docker.ContainerInspect(ctx, containerID) | ||
if err != nil { | ||
return stubDeployment, fmt.Errorf("ContainerInspect: %s", err) | ||
|
@@ -504,26 +517,90 @@ func copyToContainer(docker *client.Client, containerID, path string, data []byt | |
return nil | ||
} | ||
|
||
// Waits until a homeserver container has NAT ports assigned and returns its clientside API URL and federation API URL. | ||
func waitForPorts(ctx context.Context, docker *client.Client, containerID string) (baseURL string, fedBaseURL string, err error) { | ||
func assertHostnameEqual(inputUrl string, expectedHostname string) error { | ||
parsedUrl, err := url.Parse(inputUrl) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse URL %s: %s", inputUrl, err) | ||
} | ||
if parsedUrl.Hostname() != expectedHostname { | ||
return fmt.Errorf("expected hostname %s in URL %s, got %s", expectedHostname, inputUrl, parsedUrl.Hostname()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func getHostAccessibleHomeserverUrls(ctx context.Context, docker *client.Client, containerID string, hsPortBindingIP string) (baseURL string, fedBaseURL string, err error) { | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inspectResponse, err := inspectPortsOnContainer(ctx, docker, containerID) | ||
if err != nil { | ||
return "", "", fmt.Errorf("failed to inspect ports: %w", err) | ||
} | ||
|
||
baseURL, fedBaseURL, err = endpoints(inspectResponse.NetworkSettings.Ports, hsPortBindingIP, 8008, 8448) | ||
|
||
// Sanity check that the URL's match the expected binding hostname. It's important | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// that we use the canonical publically accessible hostname for the homeserver as ... | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// such as important cookies that are set during a SSO/OIDC login process (cookies are | ||
// scoped to the domain). | ||
err = assertHostnameEqual(baseURL, hsPortBindingIP) | ||
if err != nil { | ||
return "", "", fmt.Errorf("failed to assert baseURL has the correct hostname: %w", err) | ||
} | ||
err = assertHostnameEqual(fedBaseURL, hsPortBindingIP) | ||
if err != nil { | ||
return "", "", fmt.Errorf("failed to assert fedBaseURL has the correct hostname: %w", err) | ||
} | ||
|
||
return baseURL, fedBaseURL, nil | ||
} | ||
|
||
// Waits until a homeserver container has NAT ports assigned. | ||
func waitForPorts(ctx context.Context, docker *client.Client, containerID string) (err error) { | ||
// We need to hammer the inspect endpoint until the ports show up, they don't appear immediately. | ||
var inspect container.InspectResponse | ||
inspectStartTime := time.Now() | ||
for time.Since(inspectStartTime) < time.Second { | ||
inspect, err = docker.ContainerInspect(ctx, containerID) | ||
if err != nil { | ||
return "", "", err | ||
} | ||
if inspect.State != nil && !inspect.State.Running { | ||
// the container exited, bail out with a container ID for logs | ||
return "", "", fmt.Errorf("container is not running, state=%v", inspect.State.Status) | ||
} | ||
baseURL, fedBaseURL, err = endpoints(inspect.NetworkSettings.Ports, 8008, 8448) | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
_, err = inspectPortsOnContainer(ctx, docker, containerID) | ||
if err == nil { | ||
break | ||
} | ||
|
||
if inspectionErr, ok := err.(*ContainerInspectionError); ok && inspectionErr.Fatal { | ||
// If the error is fatal, we should not retry. | ||
return fmt.Errorf("Fatal inspection error: %s", err) | ||
} | ||
} | ||
return baseURL, fedBaseURL, nil | ||
return nil | ||
} | ||
|
||
type ContainerInspectionError struct { | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Error message | ||
msg string | ||
// Whether this error should stop retrying to inspect the container. | ||
Fatal bool | ||
} | ||
|
||
func (e *ContainerInspectionError) Error() string { return e.msg } | ||
|
||
func inspectPortsOnContainer( | ||
ctx context.Context, | ||
docker *client.Client, | ||
containerID string, | ||
) (inspectResponse container.InspectResponse, err error) { | ||
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inspectResponse, err = docker.ContainerInspect(ctx, containerID) | ||
if err != nil { | ||
return container.InspectResponse{}, &ContainerInspectionError{ | ||
msg: err.Error(), | ||
Fatal: false, | ||
} | ||
} | ||
if inspectResponse.State != nil && !inspectResponse.State.Running { | ||
// the container exited, bail out with a container ID for logs | ||
return container.InspectResponse{}, &ContainerInspectionError{ | ||
msg: fmt.Sprintf("container (%s) is not running, state=%v", containerID, inspectResponse.State.Status), | ||
Fatal: true, | ||
} | ||
} | ||
|
||
return inspectResponse, nil | ||
} | ||
|
||
// Waits until a homeserver deployment is ready to serve requests. | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.