Skip to content

Commit 38f6390

Browse files
authored
local-env incorporating last discussion (#191)
* incorporating review - no more file gc - by default, files storage relative to ${HOME}/.signadot/data/sandboxes/{sandboxName}/local/files - addition of sources in default output, and change of format for files ``` export SIGNADOT_BASELINE_KIND="Deployment" # constant export SIGNADOT_BASELINE_NAMESPACE="hotrod-devmesh" # fieldRef: metadata.namespace export SIGNADOT_BASELINE_NAME="location" # constant export OTEL_EXPORTER_OTLP_ENDPOINT="http://jaeger:4318" # constant export MYSQL_HOST="localhost" # constant (override) export MYSQL_PORT="3306" # constant export MYSQL_PASS="abc" # constant export CUSTOM="CUSTOMVAL" # constant (override) export CUSTOMCF="11" # configMap: hotrod-devmesh/x[key] (override) export RES="hello-world" # sandboxResource: myresource/step1.out (override) ``` ``` /Users/scott/.signadot/data/sandboxes/local-env/local/files # /Users/scott/.signadot/data/sandboxes/local-env/local/files/CUSTOM # constant (override) /Users/scott/.signadot/data/sandboxes/local-env/local/files/CUSTOMCF # configMap: hotrod-devmesh/x[key] (override) /Users/scott/.signadot/data/sandboxes/local-env/local/files/RES_ALL # /Users/scott/.signadot/data/sandboxes/local-env/local/files/RES_ALL/step1.out # sandboxResource: myresource/step1.out (override) /Users/scott/.signadot/data/sandboxes/local-env/local/files/RES_KEYED # sandboxResource: myresource/step1.out (override) ``` * sb get-files clean up: - remove old centrally-stored sandbox local files - remove config file variable and just use default or -d - move central location to ${HOME}/.signadot/sandboxes/{sandbox}/local/files * use merged libconnect changes from libconnect@main
1 parent 5d8ed13 commit 38f6390

File tree

10 files changed

+138
-159
lines changed

10 files changed

+138
-159
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ require (
1919
github.com/oklog/run v1.1.0
2020
github.com/panta/machineid v1.0.2
2121
github.com/signadot/go-sdk v0.3.8-0.20250617214735-334394d59150
22-
github.com/signadot/libconnect v0.1.1-0.20250625134612-59c224b2be55
22+
github.com/signadot/libconnect v0.1.1-0.20250701080820-3e0032a770f2
2323
github.com/spf13/cobra v1.8.1
2424
github.com/spf13/viper v1.11.0
2525
github.com/theckman/yacspin v0.13.12

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN
354354
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
355355
github.com/signadot/go-sdk v0.3.8-0.20250617214735-334394d59150 h1:ASJG4pszRfB3POcOi3FvCyl5OSvRntUmtjCdfMpTvXo=
356356
github.com/signadot/go-sdk v0.3.8-0.20250617214735-334394d59150/go.mod h1:e/WZPadqyJ7S57OgDfUQn9TojmEGQO7z6B5vqF9TjKo=
357-
github.com/signadot/libconnect v0.1.1-0.20250625134612-59c224b2be55 h1:FxjfmoRPKZ+lU7MvtqPkjI4Qyd9ADBEXZurTxndlosI=
358-
github.com/signadot/libconnect v0.1.1-0.20250625134612-59c224b2be55/go.mod h1:VwIZ9rhG9HYJlvRXAo8XrJbE697VO8e12zFaCxOjOLw=
357+
github.com/signadot/libconnect v0.1.1-0.20250701080820-3e0032a770f2 h1:vb7Hhv7yK1p8cxWL4OGSkoWRpk42qV4nVwFIyPAr34M=
358+
github.com/signadot/libconnect v0.1.1-0.20250701080820-3e0032a770f2/go.mod h1:3OVwfvTsENxOIY7mRuhvygEPkdYMKKhaWl35Ll3LcEI=
359359
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
360360
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
361361
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=

internal/command/local/connect.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/signadot/cli/internal/config"
1919
sbmapi "github.com/signadot/cli/internal/locald/api/sandboxmanager"
2020
sbmgr "github.com/signadot/cli/internal/locald/sandboxmanager"
21-
"github.com/signadot/cli/internal/utils"
2221
"github.com/signadot/cli/internal/utils/system"
2322
clusters "github.com/signadot/go-sdk/client/cluster"
2423
"github.com/signadot/libconnect/common/processes"
@@ -128,10 +127,6 @@ func runConnectImpl(out io.Writer, log *slog.Logger, localConfig *config.LocalCo
128127
return fmt.Errorf("signadot is already connected\n")
129128
}
130129

131-
if err := utils.GCPaths(); err != nil {
132-
return err
133-
}
134-
135130
// Check version skew
136131
if err := checkVersionSkew(localConfig, ciConfig); err != nil {
137132
return err

internal/command/local/disconnect.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
rmapi "github.com/signadot/cli/internal/locald/api/rootmanager"
1313
sbmapi "github.com/signadot/cli/internal/locald/api/sandboxmanager"
1414
sbmgr "github.com/signadot/cli/internal/locald/sandboxmanager"
15-
"github.com/signadot/cli/internal/utils"
1615
"github.com/signadot/cli/internal/utils/system"
1716
"github.com/signadot/go-sdk/client/sandboxes"
1817
"github.com/signadot/libconnect/common/processes"
@@ -71,12 +70,6 @@ func runDisconnectWith(cfg *config.LocalDisconnect, signadotDir string) error {
7170
}
7271
<-ticker.C
7372
}
74-
defer func() {
75-
if err := utils.GCPaths(); err != nil {
76-
fmt.Printf("error removing signadot sb get-files: %v", err)
77-
}
78-
}()
79-
8073
if wasRunning {
8174
fmt.Printf("disconnected.\n")
8275
return nil

internal/command/sandbox/get_env.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"os"
8+
"text/tabwriter"
79
"time"
810

911
"github.com/signadot/cli/internal/config"
@@ -80,13 +82,14 @@ func getEnv(cfg *config.SandboxGetEnv, out, errOut io.Writer, name string) error
8082
func printEnv(out io.Writer, oFmt config.OutputFormat, resEnv []k8senv.EnvItem) error {
8183
switch oFmt {
8284
case config.OutputFormatDefault:
85+
w := tabwriter.NewWriter(os.Stdout, 0, 4, 1, ' ', tabwriter.TabIndent)
8386
for _, item := range resEnv {
84-
_, err := out.Write([]byte(item.ToShellEval() + "\n"))
87+
_, err := w.Write([]byte(item.ToShellEval() + "\n"))
8588
if err != nil {
8689
return err
8790
}
8891
}
89-
return nil
92+
return w.Flush()
9093
case config.OutputFormatJSON:
9194
return print.RawJSON(out, resEnv)
9295
case config.OutputFormatYAML:
@@ -97,7 +100,7 @@ func printEnv(out io.Writer, oFmt config.OutputFormat, resEnv []k8senv.EnvItem)
97100
}
98101

99102
func calculateOverrides(ctx context.Context, kubeClient client.Client, ns string, resOuts []sandboxmanager.ResourceOutput, xEnv []k8senv.EnvItem, sbEnv []*models.SandboxEnvVar) ([]k8senv.EnvItem, error) {
100-
sbEnvMap := map[string]string{}
103+
sbEnvMap := map[string]*k8senv.EnvItem{}
101104
for _, sbEnvVar := range sbEnv {
102105
xEnvVar, err := extractSBEnvVar(ctx, kubeClient, ns, resOuts, sbEnvVar)
103106
if err != nil {
@@ -106,20 +109,21 @@ func calculateOverrides(ctx context.Context, kubeClient client.Client, ns string
106109
if xEnvVar == nil {
107110
continue
108111
}
109-
sbEnvMap[xEnvVar.Name] = xEnvVar.Value
112+
sbEnvMap[xEnvVar.Name] = xEnvVar
110113
}
111114
for i := range xEnv {
112115
xEnvVar := &xEnv[i]
113-
sbVal, ok := sbEnvMap[xEnvVar.Name]
116+
sbEnvVar, ok := sbEnvMap[xEnvVar.Name]
114117
if !ok {
115118
continue
116119
}
117-
xEnvVar.Value = sbVal
120+
xEnvVar.Value = sbEnvVar.Value
121+
xEnvVar.Source = sbEnvVar.Source
118122
delete(sbEnvMap, xEnvVar.Name)
119123
}
120124
res := xEnv
121-
for k, v := range sbEnvMap {
122-
res = append(res, k8senv.EnvItem{Name: k, Value: v})
125+
for _, v := range sbEnvMap {
126+
res = append(res, *v)
123127
}
124128
return res, nil
125129
}

internal/command/sandbox/get_files.go

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import (
99
"path/filepath"
1010
"slices"
1111
"strings"
12+
"text/tabwriter"
1213
"time"
1314

1415
"github.com/signadot/cli/internal/config"
1516
"github.com/signadot/cli/internal/local"
1617
"github.com/signadot/cli/internal/locald/sandboxmanager"
1718
"github.com/signadot/cli/internal/print"
18-
"github.com/signadot/cli/internal/utils"
19+
"github.com/signadot/cli/internal/utils/system"
1920
"github.com/signadot/go-sdk/client/sandboxes"
2021
"github.com/signadot/go-sdk/models"
2122
"github.com/signadot/libconnect/common/k8senv"
@@ -76,12 +77,27 @@ func getFiles(cfg *config.SandboxGetFiles, out, errOut io.Writer, name string) e
7677
if err != nil {
7778
return err
7879
}
79-
absOut, err := filepath.Abs(cfg.OutputDir)
80-
if err != nil {
81-
return err
80+
if cfg.OutputDir == "" {
81+
baseDir, err := system.GetSandboxLocalFilesBaseDir(name)
82+
if err != nil {
83+
return err
84+
}
85+
_, err = os.Stat(baseDir)
86+
if err == nil {
87+
err := os.RemoveAll(baseDir)
88+
if err != nil {
89+
return err
90+
}
91+
} else {
92+
if !os.IsNotExist(err) {
93+
return err
94+
}
95+
}
96+
cfg.OutputDir = baseDir
8297
}
83-
err = writeGCFiles(k8sEnv.Files, absOut)
84-
if err != nil {
98+
// either no err from stat and no such baseDir
99+
// or error is that baseDir doesn't exist
100+
if err := os.MkdirAll(cfg.OutputDir, 0755); err != nil {
85101
return err
86102
}
87103
// no-clobber
@@ -101,7 +117,11 @@ func getFiles(cfg *config.SandboxGetFiles, out, errOut io.Writer, name string) e
101117
k8sEnv.Files.Name = cfg.OutputDir
102118
switch cfg.OutputFormat {
103119
case config.OutputFormatDefault:
104-
return printTree(out, k8sEnv.Files, []bool{})
120+
w := tabwriter.NewWriter(os.Stdout, 0, 4, 1, ' ', tabwriter.TabIndent)
121+
if err := printTree(w, k8sEnv.Files, cfg.OutputDir, []bool{}); err != nil {
122+
return err
123+
}
124+
return w.Flush()
105125
case config.OutputFormatJSON:
106126
return print.RawJSON(out, k8sEnv.Files)
107127
case config.OutputFormatYAML:
@@ -119,6 +139,7 @@ func calculateFileOverrides(ctx context.Context, kubeClient client.Client, ns st
119139
child := files.Path(fileOp.Path)
120140
if fileOp.ValueFrom == nil {
121141
child.Content = []byte(fileOp.Value)
142+
child.Source = &k8senv.Source{Override: true, Constant: &fileOp.Value}
122143
continue
123144
}
124145
if err := overrideFileValueFrom(ctx, kubeClient, child, fileOp, ns, resOuts, cmMap, secMap); err != nil {
@@ -156,34 +177,50 @@ func overrideFileValueFrom(ctx context.Context, kubeClient client.Client, child
156177
return nil
157178
}
158179
child.Content = []byte(val)
180+
child.Source = &k8senv.Source{
181+
Override: true,
182+
ConfigMap: &k8senv.MapKey{
183+
Namespace: cm.Namespace,
184+
Name: cm.Name,
185+
Key: cmSource.Key,
186+
},
187+
}
159188
}
160189
return nil
161190

162191
case vf.Secret != nil:
163-
cmSource := vf.Secret
164-
cm := secMap[cmSource.Name]
165-
if cm == nil {
166-
cm = &corev1.Secret{}
167-
err := kubeClient.Get(ctx, client.ObjectKey{Namespace: ns, Name: cmSource.Name}, cm)
168-
if cmSource.Optional && k8serrors.IsNotFound(err) {
192+
secSource := vf.Secret
193+
sec := secMap[secSource.Name]
194+
if sec == nil {
195+
sec = &corev1.Secret{}
196+
err := kubeClient.Get(ctx, client.ObjectKey{Namespace: ns, Name: secSource.Name}, sec)
197+
if secSource.Optional && k8serrors.IsNotFound(err) {
169198
return nil
170199
}
171200
if err != nil {
172201
return err
173202
}
174-
secMap[cmSource.Name] = cm
203+
secMap[secSource.Name] = sec
175204
}
176-
if cmSource.Key == "" {
177-
child.MountSecret(cm)
205+
if secSource.Key == "" {
206+
child.MountSecret(sec)
178207
} else {
179-
val, ok := cm.Data[cmSource.Key]
180-
if !cmSource.Optional && !ok {
181-
return fmt.Errorf("key %q not found in secret %q", cmSource.Key, cmSource.Name)
208+
val, ok := sec.Data[secSource.Key]
209+
if !secSource.Optional && !ok {
210+
return fmt.Errorf("key %q not found in secret %q", secSource.Key, secSource.Name)
182211
}
183212
if !ok {
184213
return nil
185214
}
186215
child.Content = val
216+
child.Source = &k8senv.Source{
217+
Override: true,
218+
Secret: &k8senv.MapKey{
219+
Namespace: sec.Namespace,
220+
Name: sec.Name,
221+
Key: secSource.Key,
222+
},
223+
}
187224
}
188225
return nil
189226
case vf.Resource != nil:
@@ -195,6 +232,13 @@ func overrideFileValueFrom(ctx context.Context, kubeClient client.Client, child
195232
}
196233
if vfr.OutputKey == resOut.Output {
197234
child.Content = []byte(resOut.Value)
235+
child.Source = &k8senv.Source{
236+
Override: true,
237+
SandboxResource: &k8senv.SandboxResource{
238+
Name: vfr.Name,
239+
OutputKey: vfr.OutputKey,
240+
},
241+
}
198242
return nil
199243
}
200244
if vfr.OutputKey != "" {
@@ -203,6 +247,13 @@ func overrideFileValueFrom(ctx context.Context, kubeClient client.Client, child
203247
// all resource outputs mounted.
204248
keyChild := child.Path(resOut.Output)
205249
keyChild.Content = []byte(resOut.Value)
250+
keyChild.Source = &k8senv.Source{
251+
Override: true,
252+
SandboxResource: &k8senv.SandboxResource{
253+
Name: vfr.Name,
254+
OutputKey: resOut.Output,
255+
},
256+
}
206257
}
207258
return nil
208259

@@ -232,30 +283,18 @@ func noClobber(errOut io.Writer, files *k8senv.Files, base string) (bool, error)
232283
if err != nil {
233284
return false, err
234285
}
235-
fmt.Fprintf(errOut, "%s already exists, skipping\n", base)
286+
fmt.Fprintf(errOut, "WARNING: %s already exists, skipping\n", base)
236287
return true, nil
237288
}
238289

239-
func writeGCFiles(files *k8senv.Files, base string) error {
240-
if files.IsDir() {
241-
for k, child := range files.Children {
242-
if err := writeGCFiles(child, filepath.Join(base, k)); err != nil {
243-
return err
244-
}
245-
}
246-
return nil
247-
}
248-
return utils.RegisterPathForGC(base)
249-
}
250-
251290
var (
252291
vBar []byte = []byte("│ ")
253292
highL []byte = []byte("└── ")
254293
turnStyle []byte = []byte("├── ")
255294
space []byte = []byte(strings.Repeat(" ", 4))
256295
)
257296

258-
func printTree(out io.Writer, files *k8senv.Files, ended []bool) error {
297+
func printTree(out io.Writer, files *k8senv.Files, base string, ended []bool) error {
259298
var err error
260299
for i, b := range ended {
261300
if i < len(ended)-1 {
@@ -273,7 +312,12 @@ func printTree(out io.Writer, files *k8senv.Files, ended []bool) error {
273312
return err
274313
}
275314
}
276-
_, err = out.Write([]byte(files.Name + "\n"))
315+
src := "\t#"
316+
if files.Source != nil {
317+
src = fmt.Sprintf("\t# %s", files.Source)
318+
}
319+
320+
_, err = fmt.Fprintf(out, "%s%s\n", files.Name, src)
277321
if err != nil {
278322
return err
279323
}
@@ -283,7 +327,7 @@ func printTree(out io.Writer, files *k8senv.Files, ended []bool) error {
283327
keys := slices.Sorted(maps.Keys(files.Children))
284328
for _, k := range keys {
285329
n++
286-
if err := printTree(out, files.Children[k], append(ended, n == N)); err != nil {
330+
if err := printTree(out, files.Children[k], filepath.Join(base, k), append(ended, n == N)); err != nil {
287331
return err
288332
}
289333
}

internal/command/sandbox/get_utils.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ func extractSBEnvVar(ctx context.Context, kubeClient client.Client, ns string, r
4343
return &k8senv.EnvItem{
4444
Name: sbEnvVar.Name,
4545
Value: sbEnvVar.Value,
46+
Source: k8senv.Source{
47+
Override: true,
48+
Constant: &sbEnvVar.Value,
49+
},
4650
}, nil
4751
}
4852
vf := sbEnvVar.ValueFrom
@@ -67,6 +71,14 @@ func extractSBEnvVar(ctx context.Context, kubeClient client.Client, ns string, r
6771
return &k8senv.EnvItem{
6872
Name: sbEnvVar.Name,
6973
Value: val,
74+
Source: k8senv.Source{
75+
Override: true,
76+
ConfigMap: &k8senv.MapKey{
77+
Namespace: ns,
78+
Name: key.Name,
79+
Key: vf.ConfigMap.Key,
80+
},
81+
},
7082
}, nil
7183
case vf.Secret != nil:
7284
secret := &corev1.Secret{}
@@ -88,6 +100,14 @@ func extractSBEnvVar(ctx context.Context, kubeClient client.Client, ns string, r
88100
return &k8senv.EnvItem{
89101
Name: sbEnvVar.Name,
90102
Value: string(val),
103+
Source: k8senv.Source{
104+
Override: true,
105+
Secret: &k8senv.MapKey{
106+
Namespace: ns,
107+
Name: key.Name,
108+
Key: vf.ConfigMap.Key,
109+
},
110+
},
91111
}, nil
92112
case vf.Resource != nil:
93113
vfr := vf.Resource
@@ -102,6 +122,13 @@ func extractSBEnvVar(ctx context.Context, kubeClient client.Client, ns string, r
102122
return &k8senv.EnvItem{
103123
Name: sbEnvVar.Name,
104124
Value: out.Value,
125+
Source: k8senv.Source{
126+
Override: true,
127+
SandboxResource: &k8senv.SandboxResource{
128+
Name: vfr.Name,
129+
OutputKey: vfr.OutputKey,
130+
},
131+
},
105132
}, nil
106133
}
107134
return nil, fmt.Errorf("output %q in resource %q unavailable", vfr.OutputKey, vfr.Name)

0 commit comments

Comments
 (0)