@@ -343,6 +343,10 @@ func (d *Builder) construct(bprint b.Blueprint) (errs []error) {
343343 Pause : true ,
344344 Reference : "localhost/complement:" + res .contextStr ,
345345 Changes : toChanges (labels ),
346+
347+ // Podman's compatibility API returns a 500 if the POST request has an empty body, so we give it an empty
348+ // Config to chew on.
349+ Config : & container.Config {},
346350 })
347351 if err != nil {
348352 d .log ("%s : failed to ContainerCommit: %s\n " , res .contextStr , err )
@@ -539,27 +543,59 @@ func printPortBindingsOfAllComplementContainers(docker *client.Client, contextSt
539543 log .Printf ("=============== %s : END ALL COMPLEMENT DOCKER PORT BINDINGS ===============\n \n \n " , contextStr )
540544}
541545
542- func endpoints ( p nat. PortMap , csPort , ssPort int ) ( baseURL , fedBaseURL string , err error ) {
543- csapiPort := fmt . Sprintf ( "%d/tcp" , csPort )
544- csapiPortInfo , ok := p [ nat . Port ( csapiPort )]
545- if ! ok {
546- return "" , "" , fmt .Errorf ("port %s not exposed - exposed ports : %v " , csapiPort , p )
546+ // endpoints transforms the homeserver ports into the base URL and federation base URL.
547+ func endpoints ( p nat. PortMap , hsPortBindingIP string , csPort , ssPort int ) ( baseURL , fedBaseURL string , err error ) {
548+ csapiPortBinding , err := findPortBinding ( p , hsPortBindingIP , csPort )
549+ if err != nil {
550+ return "" , "" , fmt .Errorf ("Problem finding CS API port : %s " , err )
547551 }
548- if len (csapiPortInfo ) == 0 {
549- return "" , "" , fmt .Errorf ("port %s exposed with not mapped port: %+v" , csapiPort , p )
552+ baseURL = fmt .Sprintf ("http://" + csapiPortBinding .HostIP + ":%s" , csapiPortBinding .HostPort )
553+
554+ ssapiPortBinding , err := findPortBinding (p , hsPortBindingIP , ssPort )
555+ if err != nil {
556+ return "" , "" , fmt .Errorf ("Problem finding SS API port: %s" , err )
550557 }
551- baseURL = fmt .Sprintf ("http://" + csapiPortInfo [0 ].HostIP + ":%s" , csapiPortInfo [0 ].HostPort )
558+ fedBaseURL = fmt .Sprintf ("https://" + ssapiPortBinding .HostIP + ":%s" , ssapiPortBinding .HostPort )
559+ return
560+ }
552561
553- ssapiPort := fmt .Sprintf ("%d/tcp" , ssPort )
554- ssapiPortInfo , ok := p [nat .Port (ssapiPort )]
562+ // findPortBinding finds a matching port binding for the given host/port in the `nat.PortMap`.
563+ //
564+ // This function will return the first port binding that matches the given host IP. If a
565+ // `0.0.0.0` binding is found, we will assume that it is listening on all interfaces,
566+ // including the `hsPortBindingIP`, and return a binding with the `hsPortBindingIP` as
567+ // the host IP.
568+ func findPortBinding (p nat.PortMap , hsPortBindingIP string , port int ) (portBinding nat.PortBinding , err error ) {
569+ portString := fmt .Sprintf ("%d/tcp" , port )
570+ portBindings , ok := p [nat .Port (portString )]
555571 if ! ok {
556- return "" , "" , fmt .Errorf ("port %s not exposed - exposed ports: %v" , ssapiPort , p )
557- }
558- if len (ssapiPortInfo ) == 0 {
559- return "" , "" , fmt .Errorf ("port %s exposed with not mapped port: %+v" , ssapiPort , p )
572+ return nat.PortBinding {}, fmt .Errorf ("port %s not exposed - exposed ports: %v" , portString , p )
573+ }
574+ if len (portBindings ) == 0 {
575+ return nat.PortBinding {}, fmt .Errorf ("port %s exposed with not mapped port: %+v" , portString , p )
576+ }
577+
578+ for _ , pb := range portBindings {
579+ if pb .HostIP == hsPortBindingIP {
580+ return pb , nil
581+ } else if pb .HostIP == "0.0.0.0" {
582+ // `0.0.0.0` means "all interfaces", so we can assume that this will be listening
583+ // for connections from `hsPortBindingIP` as well.
584+ return nat.PortBinding {
585+ HostIP : hsPortBindingIP ,
586+ HostPort : pb .HostPort ,
587+ }, nil
588+ } else if pb .HostIP == "" && hsPortBindingIP == "127.0.0.1" {
589+ // `HostIP` can be empty in certain environments (observed with podman v4.3.1). We
590+ // will assume this is only a binding for `127.0.0.1`.
591+ return nat.PortBinding {
592+ HostIP : hsPortBindingIP ,
593+ HostPort : pb .HostPort ,
594+ }, nil
595+ }
560596 }
561- fedBaseURL = fmt . Sprintf ( "https://" + csapiPortInfo [ 0 ]. HostIP + ":%s" , ssapiPortInfo [ 0 ]. HostPort )
562- return
597+
598+ return nat. PortBinding {}, fmt . Errorf ( "unable to find matching port binding for %s %s: %+v" , hsPortBindingIP , portString , p )
563599}
564600
565601type result struct {
0 commit comments