AppManager: Handle new port forwards during app update
Change-Id: I72a4c5b7ec4bd5ba6ddd32cd3f33dce023d7d9ea
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 7995a41..d0faed4 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -10,6 +10,7 @@
"net/http"
"path"
"path/filepath"
+ "slices"
"strings"
"sync"
@@ -632,6 +633,9 @@
overrides CueAppData,
opts ...InstallOption,
) (ReleaseResources, error) {
+ if values == nil {
+ values = map[string]any{}
+ }
m.l.Lock()
defer m.l.Unlock()
if err := m.repo.Pull(); err != nil {
@@ -642,10 +646,29 @@
return ReleaseResources{}, err
}
instanceDir := filepath.Join(m.appDirRoot, instanceId)
- app, err := m.GetInstanceApp(instanceId, overrides)
+ oldApp, err := m.GetInstanceApp(instanceId, nil)
if err != nil {
return ReleaseResources{}, err
}
+ newApp, err := m.GetInstanceApp(instanceId, overrides)
+ if err != nil {
+ return ReleaseResources{}, err
+ }
+ oldPorts := findPortFields(oldApp.Schema())
+ newPorts := findPortFields(newApp.Schema())
+ portFields := []string{}
+ for _, np := range newPorts {
+ if !slices.Contains(oldPorts, np) {
+ portFields = append(portFields, np)
+ }
+ }
+ fakeReservations := map[string]reservePortResp{}
+ for i, f := range portFields {
+ fakeReservations[f] = reservePortResp{Port: i}
+ }
+ if err := setPortFields(values, fakeReservations); err != nil {
+ return ReleaseResources{}, err
+ }
instanceConfigPath := filepath.Join(instanceDir, "config.json")
config, err := m.appConfig(instanceConfigPath)
if err != nil {
@@ -663,7 +686,36 @@
if err != nil {
return ReleaseResources{}, err
}
- rendered, err := app.Render(config.Release, env, networks, ToAccessConfigs(clusters), merge(config.Input, values), renderedCfg.LocalCharts, m.vpnAPIClient)
+ rendered, err := newApp.Render(config.Release, env, networks, ToAccessConfigs(clusters), merge(config.Input, values), renderedCfg.LocalCharts, m.vpnAPIClient)
+ if err != nil {
+ return ReleaseResources{}, err
+ }
+ reservators := map[string]reservePortInfo{}
+ allocators := map[string]string{}
+ for _, pf := range rendered.Ports {
+ found := false
+ for _, fr := range fakeReservations {
+ if fr.Port == pf.Port {
+ found = true
+ }
+ }
+ if !found {
+ continue
+ }
+ reservators[portFields[pf.Port]] = reservePortInfo{
+ reserveAddr: pf.Network.ReservePortAddr,
+ RemoteProxy: pf.Cluster != "",
+ }
+ allocators[portFields[pf.Port]] = pf.Network.AllocatePortAddr
+ }
+ portReservations, err := reservePorts(reservators)
+ if err != nil {
+ return ReleaseResources{}, err
+ }
+ if err := setPortFields(values, portReservations); err != nil {
+ return ReleaseResources{}, err
+ }
+ rendered, err = newApp.Render(config.Release, env, networks, ToAccessConfigs(clusters), merge(config.Input, values), renderedCfg.LocalCharts, m.vpnAPIClient)
if err != nil {
return ReleaseResources{}, err
}
@@ -685,6 +737,22 @@
if err := installApp(m.repo, instanceDir, rendered.Name, rendered.Config, rendered.Resources, rendered.Data, opts...); err != nil {
return ReleaseResources{}, err
}
+ toOpen := []PortForward{}
+ for _, op := range rendered.Ports {
+ found := false
+ for _, rp := range portReservations {
+ if rp.Port == op.Port {
+ found = true
+ break
+ }
+ }
+ if !found {
+ toOpen = append(toOpen, op)
+ }
+ }
+ if err := openPorts(toOpen, portReservations, allocators, config.Release.Namespace); err != nil {
+ return ReleaseResources{}, err
+ }
for _, ocp := range renderedCfg.Out.ClusterProxy {
found := false
for _, ncp := range rendered.ClusterProxies {