Skip to content

Commit 8a4e1bf

Browse files
authored
Merge pull request #1884 from erikkrieg/feature/deployment-concurrency
Feature/deployment concurrency
2 parents 78014f2 + bad44e4 commit 8a4e1bf

File tree

13 files changed

+381
-90
lines changed

13 files changed

+381
-90
lines changed

docs/pages/configuration/deployments/basics.mdx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ deployments:
107107
</TabItem>
108108
</Tabs>
109109
110-
:::info Sequential Deployment
111-
Unlike images which are build in parallel, deployments will be deployed sequentially following the order in which they are specified in the `devspace.yaml`.
110+
:::info Sequential and Concurrent Deployment
111+
Unlike images, which are built in parallel by default, deployments will be deployed sequentially following the order in which they are specified in the `devspace.yaml`. If a deployment has `concurrent: true` set, then it will run before any sequential deployments and in parallel with other deployments that also have concurrency enabled.
112112
:::
113113

114114
## Run Deployments
@@ -123,8 +123,11 @@ The following flags are available for all commands that trigger the deployment p
123123

124124

125125
## Deployment Process
126-
DevSpace loads the `deployments` configuration from `devspace.yaml` and builds one deployment after another in the order that they are specified in the `deployments` array. Additionally, DevSpace also deploys related projects speficied in `dependencies`.
126+
DevSpace loads the `deployments` configuration from `devspace.yaml` and by default deploys each deployment sequentially in the order that they are specified in the `deployments` array. Alternatively, some or all deployments can be configured to deploy in parallel by setting `concurrent: true`. Deployments with concurrency enabled will deploy before sequential deployments. Additionally, DevSpace also deploys related projects specified in `dependencies`.
127127

128+
:::warning Helm hooks and concurrency
129+
When using concurrency for Helm deployments that have Helm hooks, be cautious if those hooks depend on resources created by other deployments. You may want such a deployments to be run sequentially after concurrent deployments are completed. Otherwise, appropriate retry logic will be necessary for the affected Helm hook in order to avoid deployment failure.
130+
:::
128131

129132
### 1. Deploy Dependencies
130133

docs/pages/fragments/config-deployments.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ deployments: # struct[] | Array of deployments
33
- name: my-deployment # string | Name of the deployment
44
namespace: "" # string | Namespace to deploy to (Default: "" = namespace of the active namespace/Space)
55
disabled: false # bool | If true, the deployment will not be deployed, purged or rendered
6+
concurrent: false # bool | Deploy concurrently with other deployments that also have concurrency enabled (Default: false)
67
helm: ... # struct | Use Helm as deployment tool and set options for Helm
78
kubectl: ... # struct | Use "kubectl apply" as deployment tool and set options for kubectl
89
```

e2e/tests/deploy/deploy.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,78 @@ var _ = DevSpaceDescribe("deploy", func() {
194194
framework.ExpectNoError(err)
195195
framework.ExpectEqual(out, "test")
196196
})
197+
198+
ginkgo.It("should deploy applications concurrently", func() {
199+
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/helm_concurrent_all")
200+
framework.ExpectNoError(err)
201+
defer framework.CleanupTempDir(initialDir, tempDir)
202+
203+
ns, err := kubeClient.CreateNamespace("deploy")
204+
framework.ExpectNoError(err)
205+
defer func() {
206+
err := kubeClient.DeleteNamespace(ns)
207+
framework.ExpectNoError(err)
208+
}()
209+
210+
// create a new dev command
211+
deployCmd := &cmd.DeployCmd{
212+
GlobalFlags: &flags.GlobalFlags{
213+
NoWarn: true,
214+
Namespace: ns,
215+
},
216+
}
217+
218+
// run the command
219+
err = deployCmd.Run(f)
220+
framework.ExpectNoError(err)
221+
222+
// wait until nginx pod is reachable
223+
out, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test", "container-0", ns, []string{"echo", "-n", "test"})
224+
framework.ExpectNoError(err)
225+
out2, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test-2", "container-0", ns, []string{"echo", "-n", "test"})
226+
framework.ExpectNoError(err)
227+
out3, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test-3", "container-0", ns, []string{"echo", "-n", "test"})
228+
framework.ExpectNoError(err)
229+
230+
framework.ExpectEqual(out, "test")
231+
framework.ExpectEqual(out2, "test")
232+
framework.ExpectEqual(out3, "test")
233+
})
234+
235+
ginkgo.It("should deploy applications mixed concurrently and sequentially", func() {
236+
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/helm_concurrent_sequential")
237+
framework.ExpectNoError(err)
238+
defer framework.CleanupTempDir(initialDir, tempDir)
239+
240+
ns, err := kubeClient.CreateNamespace("deploy")
241+
framework.ExpectNoError(err)
242+
defer func() {
243+
err := kubeClient.DeleteNamespace(ns)
244+
framework.ExpectNoError(err)
245+
}()
246+
247+
// create a new dev command
248+
deployCmd := &cmd.DeployCmd{
249+
GlobalFlags: &flags.GlobalFlags{
250+
NoWarn: true,
251+
Namespace: ns,
252+
},
253+
}
254+
255+
// run the command
256+
err = deployCmd.Run(f)
257+
framework.ExpectNoError(err)
258+
259+
// wait until nginx pod is reachable
260+
out, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test", "container-0", ns, []string{"echo", "-n", "test"})
261+
framework.ExpectNoError(err)
262+
out2, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test-2", "container-0", ns, []string{"echo", "-n", "test"})
263+
framework.ExpectNoError(err)
264+
out3, err := kubeClient.ExecByContainer("app.kubernetes.io/component=test-3", "container-0", ns, []string{"echo", "-n", "test"})
265+
framework.ExpectNoError(err)
266+
267+
framework.ExpectEqual(out, "test")
268+
framework.ExpectEqual(out2, "test")
269+
framework.ExpectEqual(out3, "test")
270+
})
197271
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
version: v1beta11
2+
vars:
3+
- name: IMAGE
4+
value: nginx
5+
deployments:
6+
- name: test
7+
concurrent: true
8+
helm:
9+
componentChart: true
10+
values:
11+
containers:
12+
- image: ${IMAGE}
13+
env: $(cat env.yaml)
14+
- name: test-2
15+
concurrent: true
16+
helm:
17+
componentChart: true
18+
values:
19+
containers:
20+
- image: ${IMAGE}
21+
env: $(cat env.yaml)
22+
- name: test-3
23+
concurrent: true
24+
helm:
25+
componentChart: true
26+
values:
27+
containers:
28+
- image: ${IMAGE}
29+
env: $(cat env.yaml)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- name: TEST
2+
value: value
3+
- name: TEST2
4+
value: value2
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version: v1beta11
2+
vars:
3+
- name: IMAGE
4+
value: nginx
5+
deployments:
6+
- name: test
7+
concurrent: true
8+
helm:
9+
componentChart: true
10+
values:
11+
containers:
12+
- image: ${IMAGE}
13+
env: $(cat env.yaml)
14+
- name: test-2
15+
concurrent: true
16+
helm:
17+
componentChart: true
18+
values:
19+
containers:
20+
- image: ${IMAGE}
21+
env: $(cat env.yaml)
22+
- name: test-3
23+
helm:
24+
componentChart: true
25+
values:
26+
containers:
27+
- image: ${IMAGE}
28+
env: $(cat env.yaml)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- name: TEST
2+
value: value
3+
- name: TEST2
4+
value: value2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Dockerfile
2+
.devspace/
3+
chart/
4+
node_modules/
5+
test/
6+
devspace.yaml
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Dockerfile
2+
.devspace/
3+
chart/
4+
node_modules/
5+
test/
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
version: v1beta11
2+
vars: # `vars` specifies variables which may be used as ${VAR_NAME} in devspace.yaml
3+
- name: IMAGE
4+
value: loftsh/javascript:latest
5+
deployments: # `deployments` tells DevSpace how to deploy this project
6+
- name: quickstart-con-1
7+
concurrent: true
8+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
9+
componentChart: true
10+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
11+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
12+
containers:
13+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
14+
command: ["sleep", "infinity"]
15+
- name: quickstart-con-2
16+
concurrent: true
17+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
18+
componentChart: true
19+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
20+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
21+
containers:
22+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
23+
command: ["sleep", "infinity"]
24+
- name: quickstart-con-3
25+
concurrent: true
26+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
27+
componentChart: true
28+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
29+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
30+
containers:
31+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
32+
command: ["sleep", "infinity"]
33+
- name: quickstart-con-4
34+
concurrent: true
35+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
36+
componentChart: true
37+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
38+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
39+
containers:
40+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
41+
command: ["sleep", "infinity"]
42+
- name: quickstart-con-5
43+
concurrent: true
44+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
45+
componentChart: true
46+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
47+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
48+
containers:
49+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
50+
command: ["sleep", "infinity"]
51+
- name: quickstart-seq-1
52+
helm: # This deployment uses `helm` but you can also define `kubectl` deployments or kustomizations
53+
componentChart: true
54+
displayOutput: true # We are deploying the so-called Component Chart: https://devspace.sh/component-chart/docs
55+
values: # Under `values` we can define the values for this Helm chart used during `helm install/upgrade`
56+
containers:
57+
- image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
58+
command: ["sleep", "infinity"]

0 commit comments

Comments
 (0)