Files
dokku/plugins/ports/triggers.go
Jose Diaz-Gonzalez f8ccf52079 refactor: only use detected port mapping if override is not specified
Previously, we would always set the port mapping during a dockerfile build, making it difficult for users to override mappings. We also only _sometimes_ updated the detected port mapping, further confusing issues when users were migrating from Dockerfile to Buildpacks for builds.

Now, we always detect the port mapping during the build process, and only use that detected port mapping if an override is not specified. This greatly simplifies the experience around port mapping, as now a user can create an app, set a port mapping, and that first deploy will respect the port mapping without an additional deploy.

The builder always has the best context for what the app should be listening on, and thus we can always specify a "default" port mapping at this stage. Users can override this map as desired later.

This change also results in the removal of a ton of internal code that is now centralized in the ports plugin.

Closes #4067
2023-08-05 10:58:57 -04:00

224 lines
5.3 KiB
Go

package ports
import (
"fmt"
"sort"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// TriggerInstall migrates the ports config to properties
func TriggerInstall() error {
if err := common.PropertySetup("ports"); err != nil {
return fmt.Errorf("Unable to install the ports plugin: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil {
return nil
}
for _, appName := range apps {
if common.PropertyExists("ports", appName, "map") {
continue
}
common.LogInfo1(fmt.Sprintf("Migrating DOKKU_PROXY_PORT_MAP to ports map property for %s", appName))
portMapString := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "")
portMaps, _ := parsePortMapString(portMapString)
propertyValue := []string{}
for _, portMap := range portMaps {
propertyValue = append(propertyValue, portMap.String())
}
if err := common.PropertyListWrite("ports", appName, "map", propertyValue); err != nil {
return err
}
if err := config.UnsetMany(appName, []string{"DOKKU_PROXY_PORT_MAP"}, false); err != nil {
return err
}
}
return nil
}
// TriggerPortsClear removes all ports for the specified app
func TriggerPortsClear(appName string) error {
return clearPorts(appName)
}
// TriggerPortsConfigure ensures we have a port mapping
func TriggerPortsConfigure(appName string) error {
if err := initializeProxyPort(appName); err != nil {
return err
}
if err := initializeProxySSLPort(appName); err != nil {
return err
}
return nil
}
// TriggerPortsGet prints out the port mapping for a given app
func TriggerPortsGet(appName string) error {
portMaps := getPortMaps(appName)
if len(portMaps) == 0 {
portMaps = getDetectedPortMaps(appName)
}
for _, portMap := range portMaps {
if portMap.AllowsPersistence() {
continue
}
fmt.Println(portMap)
}
return nil
}
// TriggerPortsGetAvailable prints out an available port greater than 1024
func TriggerPortsGetAvailable() error {
port := getAvailablePort()
if port > 0 {
common.Log(fmt.Sprint(port))
}
return nil
}
// TriggerPortsGetProperty writes the ports key to stdout for a given app container
func TriggerPortsGetProperty(appName string, key string) error {
if key == "proxy-port" {
fmt.Println(getComputedProxyPort(appName))
return nil
}
if key == "proxy-ssl-port" {
fmt.Println(getComputedProxySSLPort(appName))
return nil
}
fmt.Println(common.PropertyGet("ports", appName, key))
return nil
}
// TriggerPortsSetDetected writes out detected ports
func TriggerPortsSetDetected(appName string, portMapString string) error {
portMaps, _ := parsePortMapString(portMapString)
var value []string
for _, portMap := range uniquePortMaps(portMaps) {
if portMap.AllowsPersistence() {
continue
}
value = append(value, portMap.String())
}
sort.Strings(value)
return common.PropertyListWrite("ports", appName, "map-detected", value)
}
// TriggerPostAppCloneSetup creates new ports files
func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
err := common.PropertyClone("ports", oldAppName, newAppName)
if err != nil {
return err
}
return nil
}
// TriggerPostAppRenameSetup renames ports files
func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
if err := common.PropertyClone("ports", oldAppName, newAppName); err != nil {
return err
}
if err := common.PropertyDestroy("ports", oldAppName); err != nil {
return err
}
return nil
}
// TriggerPostCertsRemove unsets port config vars after SSL cert is added
func TriggerPostCertsRemove(appName string) error {
keys := []string{"DOKKU_PROXY_SSL_PORT"}
if err := config.UnsetMany(appName, keys, false); err != nil {
return err
}
return removePortMaps(appName, filterAppPortMaps(appName, "https", 443))
}
// TriggerPostCertsUpdate sets port config vars after SSL cert is added
func TriggerPostCertsUpdate(appName string) error {
port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "")
sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "")
portMaps := getPortMaps(appName)
toUnset := []string{}
if port == "80" {
toUnset = append(toUnset, "DOKKU_PROXY_PORT")
}
if sslPort == "443" {
toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT")
}
if len(toUnset) > 0 {
if err := config.UnsetMany(appName, toUnset, false); err != nil {
return err
}
}
var http80Ports []PortMap
for _, portMap := range portMaps {
if portMap.Scheme == "http" && portMap.HostPort == 80 {
http80Ports = append(http80Ports, portMap)
}
}
if len(http80Ports) > 0 {
var https443Ports []PortMap
for _, portMap := range portMaps {
if portMap.Scheme == "https" && portMap.HostPort == 443 {
https443Ports = append(https443Ports, portMap)
}
}
if err := removePortMaps(appName, https443Ports); err != nil {
return err
}
var toAdd []PortMap
for _, portMap := range http80Ports {
toAdd = append(toAdd, PortMap{
Scheme: "https",
HostPort: 443,
ContainerPort: portMap.ContainerPort,
})
}
if err := addPortMaps(appName, toAdd); err != nil {
return err
}
}
return nil
}
// TriggerPostDelete is the ports post-delete plugin trigger
func TriggerPostDelete(appName string) error {
if err := common.PropertyDestroy("ports", appName); err != nil {
common.LogWarn(err.Error())
}
return nil
}