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
224 lines
5.3 KiB
Go
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
|
|
}
|