Skip to content

Commit 5d9c24a

Browse files
authored
Merge pull request #1834 from pratikjagrut/add.flgs.to.sync.cmd
feat: add new flags to sync command
2 parents 3e027cd + 89df969 commit 5d9c24a

File tree

6 files changed

+108
-12
lines changed

6 files changed

+108
-12
lines changed

cmd/sync.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/loft-sh/devspace/pkg/devspace/plugin"
1111
"github.com/loft-sh/devspace/pkg/devspace/upgrade"
1212
"github.com/loft-sh/devspace/pkg/util/message"
13-
"github.com/loft-sh/devspace/pkg/util/ptr"
1413
"k8s.io/apimachinery/pkg/labels"
1514

1615
"github.com/loft-sh/devspace/cmd/flags"
@@ -29,9 +28,12 @@ type SyncCmd struct {
2928
*flags.GlobalFlags
3029

3130
LabelSelector string
31+
ImageSelector string
3232
Container string
3333
Pod string
3434
Pick bool
35+
Wait bool
36+
Polling bool
3537

3638
Exclude []string
3739
ContainerPath string
@@ -82,6 +84,7 @@ devspace sync --container-path=/my-path
8284
syncCmd.Flags().StringVarP(&cmd.Container, "container", "c", "", "Container name within pod where to sync to")
8385
syncCmd.Flags().StringVar(&cmd.Pod, "pod", "", "Pod to sync to")
8486
syncCmd.Flags().StringVarP(&cmd.LabelSelector, "label-selector", "l", "", "Comma separated key=value selector list (e.g. release=test)")
87+
syncCmd.Flags().StringVar(&cmd.ImageSelector, "image-selector", "", "The image to search a pod for (e.g. nginx, nginx:latest, ${runtime.images.app}, nginx:${runtime.images.app.tag})")
8588
syncCmd.Flags().BoolVar(&cmd.Pick, "pick", true, "Select a pod")
8689

8790
syncCmd.Flags().StringSliceVarP(&cmd.Exclude, "exclude", "e", []string{}, "Exclude directory from sync")
@@ -97,6 +100,9 @@ devspace sync --container-path=/my-path
97100
syncCmd.Flags().BoolVar(&cmd.UploadOnly, "upload-only", false, "If set DevSpace will only upload files")
98101
syncCmd.Flags().BoolVar(&cmd.DownloadOnly, "download-only", false, "If set DevSpace will only download files")
99102

103+
syncCmd.Flags().BoolVar(&cmd.Wait, "wait", true, "Wait for the pod(s) to start if they are not running")
104+
syncCmd.Flags().BoolVar(&cmd.Polling, "polling", false, "If polling should be used to detect file changes in the container")
105+
100106
return syncCmd
101107
}
102108

@@ -176,7 +182,16 @@ func (cmd *SyncCmd) Run(f factory.Factory) error {
176182

177183
// Build params
178184
options := targetselector.NewOptionsFromFlags(cmd.Container, cmd.LabelSelector, cmd.Namespace, cmd.Pod, cmd.Pick)
179-
options.Wait = ptr.Bool(false)
185+
// get image selector if specified
186+
imageSelector, err := getImageSelector(client, configLoader, configOptions, "", cmd.ImageSelector, logger)
187+
if err != nil {
188+
return err
189+
}
190+
191+
// set image selector
192+
options.ImageSelector = imageSelector
193+
options.Wait = &cmd.Wait
194+
180195
if cmd.DownloadOnly && cmd.UploadOnly {
181196
return errors.New("--upload-only cannot be used together with --download-only")
182197
}
@@ -266,7 +281,7 @@ func (cmd *SyncCmd) applyFlagsToSyncConfig(syncConfig *latest.SyncConfig) error
266281
if cmd.Container != "" {
267282
syncConfig.ContainerName = ""
268283
}
269-
if cmd.LabelSelector != "" || cmd.Pod != "" {
284+
if cmd.LabelSelector != "" || cmd.Pod != "" || cmd.ImageSelector != "" {
270285
syncConfig.LabelSelector = nil
271286
syncConfig.ImageSelector = ""
272287
}
@@ -288,5 +303,9 @@ func (cmd *SyncCmd) applyFlagsToSyncConfig(syncConfig *latest.SyncConfig) error
288303
syncConfig.InitialSync = latest.InitialSyncStrategy(cmd.InitialSync)
289304
}
290305

306+
if cmd.Polling {
307+
syncConfig.Polling = cmd.Polling
308+
}
309+
291310
return nil
292311
}

docs/pages/commands/devspace_sync.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ devspace sync --container-path=/my-path
4444
--no-watch Synchronizes local and remote and then stops
4545
--pick Select a pod (default true)
4646
--pod string Pod to sync to
47+
--polling bool If polling should be used to detect file changes in the container
4748
--upload-only If set DevSpace will only upload files
4849
--verbose Shows every file that is synced
50+
--wait Wait for the pod(s) to start if they are not running
51+
4952
```
5053

5154

@@ -69,4 +72,3 @@ devspace sync --container-path=/my-path
6972
--var strings Variables to override during execution (e.g. --var=MYVAR=MYVALUE)
7073
--vars-secret string The secret to restore/save the variables from/to, if --restore-vars or --save-vars is enabled (default "devspace-vars")
7174
```
72-

e2e/tests/sync/sync.go

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,65 @@ var _ = DevSpaceDescribe("sync", func() {
3737
})
3838

3939
ginkgo.It("devspace sync should work with and without config", func() {
40-
// TODO:
41-
// test devspace sync command with devspace.yaml and without devspace.yaml
40+
tempDir, err := framework.CopyToTempDir("tests/sync/testdata/no-config")
41+
framework.ExpectNoError(err)
42+
defer framework.CleanupTempDir(initialDir, tempDir)
43+
44+
ns, err := kubeClient.CreateNamespace("sync")
45+
framework.ExpectNoError(err)
46+
defer func() {
47+
err := kubeClient.DeleteNamespace(ns)
48+
framework.ExpectNoError(err)
49+
}()
50+
51+
// deploy app to sync
52+
deployCmd := &cmd.DeployCmd{
53+
GlobalFlags: &flags.GlobalFlags{
54+
NoWarn: true,
55+
Namespace: ns,
56+
ConfigPath: "sync.yaml",
57+
},
58+
}
59+
err = deployCmd.Run(f)
60+
framework.ExpectNoError(err)
61+
62+
// interrupt chan for the sync command
63+
interrupt, stop := framework.InterruptChan()
64+
defer stop()
65+
66+
// sync with watch
67+
syncCmd := &cmd.SyncCmd{
68+
GlobalFlags: &flags.GlobalFlags{
69+
NoWarn: true,
70+
Namespace: ns,
71+
},
72+
ImageSelector: "node:13.14-alpine",
73+
ContainerPath: "/app",
74+
UploadOnly: true,
75+
Polling: true,
76+
Wait: true,
77+
Interrupt: interrupt,
78+
}
79+
80+
// start the command
81+
waitGroup := sync.WaitGroup{}
82+
waitGroup.Add(1)
83+
go func() {
84+
defer ginkgo.GinkgoRecover()
85+
defer waitGroup.Done()
86+
87+
err := syncCmd.Run(f)
88+
framework.ExpectNoError(err)
89+
}()
90+
91+
// wait until files were synced
92+
framework.ExpectRemoteFileContents("node:13.14-alpine", ns, "/app/file1.txt", "Hello World\n")
93+
94+
// stop sync
95+
stop()
96+
97+
// wait for the command to finish
98+
waitGroup.Wait()
4299
})
43100

44101
ginkgo.It("should execute a command after sync", func() {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello World
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: v1beta11
2+
vars:
3+
- name: IMAGE
4+
value: node:13.14-alpine
5+
deployments:
6+
- name: test
7+
helm:
8+
componentChart: true
9+
values:
10+
containers:
11+
- image: ${IMAGE}
12+
command: ["sleep"]
13+
args: ["999999999999"]

pkg/devspace/services/synccontroller/controller.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7-
runtimevar "github.com/loft-sh/devspace/pkg/devspace/config/loader/variable/runtime"
8-
"github.com/loft-sh/devspace/pkg/devspace/imageselector"
9-
"github.com/loft-sh/devspace/pkg/devspace/kubectl/selector"
107
"io"
11-
kerrors "k8s.io/apimachinery/pkg/api/errors"
12-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
138
"os"
149
"path/filepath"
1510
"runtime"
1611
"strconv"
1712
"time"
1813

14+
runtimevar "github.com/loft-sh/devspace/pkg/devspace/config/loader/variable/runtime"
15+
"github.com/loft-sh/devspace/pkg/devspace/imageselector"
16+
"github.com/loft-sh/devspace/pkg/devspace/kubectl/selector"
17+
kerrors "k8s.io/apimachinery/pkg/api/errors"
18+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19+
1920
"github.com/loft-sh/devspace/pkg/devspace/config"
2021
"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
2122
"github.com/loft-sh/devspace/pkg/devspace/dependency/types"
@@ -279,7 +280,10 @@ func (c *controller) startSync(options *Options, onInitUploadDone chan struct{},
279280
}
280281
}
281282

282-
options.TargetOptions.ImageSelector = []imageselector.ImageSelector{}
283+
if len(options.TargetOptions.ImageSelector) == 0 {
284+
options.TargetOptions.ImageSelector = []imageselector.ImageSelector{}
285+
}
286+
283287
if syncConfig.ImageSelector != "" {
284288
imageSelector, err := runtimevar.NewRuntimeResolver(true).FillRuntimeVariablesAsImageSelector(syncConfig.ImageSelector, c.config, c.dependencies)
285289
if err != nil {

0 commit comments

Comments
 (0)