Merged by openshift-bot
OpenShift Bot authored on 2016/09/28 23:34:52... | ... |
@@ -249,16 +249,24 @@ func (o *NewAppOptions) RunNewApp() error { |
249 | 249 |
return err |
250 | 250 |
} |
251 | 251 |
|
252 |
- // if the user has set the "app" label explicitly on their objects in the template, |
|
253 |
- // we should not return a failure when we can't set it ourselves. |
|
254 |
- ignoreLabelFailure := false |
|
255 |
- if len(config.Labels) == 0 && len(result.Name) > 0 { |
|
256 |
- config.Labels = map[string]string{"app": result.Name} |
|
257 |
- ignoreLabelFailure = true |
|
252 |
+ // set labels explicitly supplied by the user on the command line |
|
253 |
+ if err := setLabels(config.Labels, result); err != nil { |
|
254 |
+ return err |
|
258 | 255 |
} |
259 | 256 |
|
260 |
- if err := setLabels(config.Labels, result, ignoreLabelFailure); err != nil { |
|
261 |
- return err |
|
257 |
+ if len(result.Name) > 0 { |
|
258 |
+ // only set the computed implicit "app" label on objects if no object we've produced |
|
259 |
+ // already has the "app" label. |
|
260 |
+ appLabel := map[string]string{"app": result.Name} |
|
261 |
+ hasAppLabel, err := hasLabel(appLabel, result) |
|
262 |
+ if err != nil { |
|
263 |
+ return err |
|
264 |
+ } |
|
265 |
+ if !hasAppLabel { |
|
266 |
+ if err := setLabels(appLabel, result); err != nil { |
|
267 |
+ return err |
|
268 |
+ } |
|
269 |
+ } |
|
262 | 270 |
} |
263 | 271 |
|
264 | 272 |
if err := setAnnotations(map[string]string{newcmd.GeneratedByNamespace: newcmd.GeneratedByNewApp}, result); err != nil { |
... | ... |
@@ -507,16 +515,30 @@ func setAnnotations(annotations map[string]string, result *newcmd.AppResult) err |
507 | 507 |
return nil |
508 | 508 |
} |
509 | 509 |
|
510 |
-func setLabels(labels map[string]string, result *newcmd.AppResult, ignoreFailure bool) error { |
|
510 |
+func setLabels(labels map[string]string, result *newcmd.AppResult) error { |
|
511 | 511 |
for _, object := range result.List.Items { |
512 | 512 |
err := util.AddObjectLabels(object, labels) |
513 |
- if err != nil && !ignoreFailure { |
|
513 |
+ if err != nil { |
|
514 | 514 |
return err |
515 | 515 |
} |
516 | 516 |
} |
517 | 517 |
return nil |
518 | 518 |
} |
519 | 519 |
|
520 |
+func hasLabel(labels map[string]string, result *newcmd.AppResult) (bool, error) { |
|
521 |
+ for _, obj := range result.List.Items { |
|
522 |
+ objCopy, err := kapi.Scheme.DeepCopy(obj) |
|
523 |
+ if err != nil { |
|
524 |
+ return false, err |
|
525 |
+ } |
|
526 |
+ err = util.AddObjectLabelsWithFlags(objCopy.(runtime.Object), labels, util.ErrorOnExistingDstKey) |
|
527 |
+ if err != nil { |
|
528 |
+ return true, nil |
|
529 |
+ } |
|
530 |
+ } |
|
531 |
+ return false, nil |
|
532 |
+} |
|
533 |
+ |
|
520 | 534 |
// isInvalidTriggerError returns true if the given error is |
521 | 535 |
// a validation error that contains 'invalid trigger type' in its |
522 | 536 |
// error message. This error is returned from older servers that |
... | ... |
@@ -208,7 +208,7 @@ func (o *NewBuildOptions) RunNewBuild() error { |
208 | 208 |
config.Labels = map[string]string{"build": result.Name} |
209 | 209 |
} |
210 | 210 |
|
211 |
- if err := setLabels(config.Labels, result, false); err != nil { |
|
211 |
+ if err := setLabels(config.Labels, result); err != nil { |
|
212 | 212 |
return err |
213 | 213 |
} |
214 | 214 |
if err := setAnnotations(map[string]string{newcmd.GeneratedByNamespace: newcmd.GeneratedByNewBuild}, result); err != nil { |
... | ... |
@@ -18,8 +18,9 @@ const ( |
18 | 18 |
ErrorOnDifferentDstKeyValue |
19 | 19 |
) |
20 | 20 |
|
21 |
-// AddObjectLabels adds new label(s) to a single runtime.Object |
|
22 |
-func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
|
21 |
+// AddObjectLabelsWithFlags will set labels on the target object. Label overwrite behavior |
|
22 |
+// is controlled by the flags argument. |
|
23 |
+func AddObjectLabelsWithFlags(obj runtime.Object, labels labels.Set, flags int) error { |
|
23 | 24 |
if labels == nil { |
24 | 25 |
return nil |
25 | 26 |
} |
... | ... |
@@ -39,12 +40,12 @@ func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
39 | 39 |
|
40 | 40 |
switch objType := obj.(type) { |
41 | 41 |
case *deployapi.DeploymentConfig: |
42 |
- if err := addDeploymentConfigNestedLabels(objType, labels); err != nil { |
|
42 |
+ if err := addDeploymentConfigNestedLabels(objType, labels, flags); err != nil { |
|
43 | 43 |
return fmt.Errorf("unable to add nested labels to %s/%s: %v", obj.GetObjectKind().GroupVersionKind(), accessor.GetName(), err) |
44 | 44 |
} |
45 | 45 |
} |
46 | 46 |
|
47 |
- if err := MergeInto(metaLabels, labels, OverwriteExistingDstKey); err != nil { |
|
47 |
+ if err := MergeInto(metaLabels, labels, flags); err != nil { |
|
48 | 48 |
return fmt.Errorf("unable to add labels to %s/%s: %v", obj.GetObjectKind().GroupVersionKind(), accessor.GetName(), err) |
49 | 49 |
} |
50 | 50 |
|
... | ... |
@@ -68,7 +69,7 @@ func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
68 | 68 |
existing = found |
69 | 69 |
} |
70 | 70 |
} |
71 |
- if err := MergeInto(existing, labels, OverwriteExistingDstKey); err != nil { |
|
71 |
+ if err := MergeInto(existing, labels, flags); err != nil { |
|
72 | 72 |
return err |
73 | 73 |
} |
74 | 74 |
m["labels"] = mapToGeneric(existing) |
... | ... |
@@ -83,7 +84,7 @@ func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
83 | 83 |
if found, ok := interfaceToStringMap(obj); ok { |
84 | 84 |
existing = found |
85 | 85 |
} |
86 |
- if err := MergeInto(existing, labels, OverwriteExistingDstKey); err != nil { |
|
86 |
+ if err := MergeInto(existing, labels, flags); err != nil { |
|
87 | 87 |
return err |
88 | 88 |
} |
89 | 89 |
unstruct.Object["labels"] = mapToGeneric(existing) |
... | ... |
@@ -92,6 +93,13 @@ func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
92 | 92 |
} |
93 | 93 |
|
94 | 94 |
return nil |
95 |
+ |
|
96 |
+} |
|
97 |
+ |
|
98 |
+// AddObjectLabels adds new label(s) to a single runtime.Object, overwriting |
|
99 |
+// existing labels that have the same key. |
|
100 |
+func AddObjectLabels(obj runtime.Object, labels labels.Set) error { |
|
101 |
+ return AddObjectLabelsWithFlags(obj, labels, OverwriteExistingDstKey) |
|
95 | 102 |
} |
96 | 103 |
|
97 | 104 |
// AddObjectAnnotations adds new annotation(s) to a single runtime.Object |
... | ... |
@@ -168,11 +176,11 @@ func AddObjectAnnotations(obj runtime.Object, annotations map[string]string) err |
168 | 168 |
} |
169 | 169 |
|
170 | 170 |
// addDeploymentConfigNestedLabels adds new label(s) to a nested labels of a single DeploymentConfig object |
171 |
-func addDeploymentConfigNestedLabels(obj *deployapi.DeploymentConfig, labels labels.Set) error { |
|
171 |
+func addDeploymentConfigNestedLabels(obj *deployapi.DeploymentConfig, labels labels.Set, flags int) error { |
|
172 | 172 |
if obj.Spec.Template.Labels == nil { |
173 | 173 |
obj.Spec.Template.Labels = make(map[string]string) |
174 | 174 |
} |
175 |
- if err := MergeInto(obj.Spec.Template.Labels, labels, OverwriteExistingDstKey); err != nil { |
|
175 |
+ if err := MergeInto(obj.Spec.Template.Labels, labels, flags); err != nil { |
|
176 | 176 |
return fmt.Errorf("unable to add labels to Template.DeploymentConfig.Template.ControllerTemplate.Template: %v", err) |
177 | 177 |
} |
178 | 178 |
return nil |
... | ... |
@@ -47,6 +47,7 @@ os::cmd::expect_success 'oc new-app php mysql' |
47 | 47 |
os::cmd::expect_success 'oc delete all -l app=php' |
48 | 48 |
os::cmd::expect_failure 'oc get dc/mysql' |
49 | 49 |
os::cmd::expect_failure 'oc get dc/php' |
50 |
+os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-without-app-label.json -o yaml' 'app: ruby-helloworld-sample' |
|
50 | 51 |
|
51 | 52 |
# ensure non-duplicate invalid label errors show up |
52 | 53 |
os::cmd::expect_failure_and_text 'oc new-app nginx -l qwer1345%$$#=self' 'error: ImageStream "nginx" is invalid' |
... | ... |
@@ -63,10 +64,10 @@ os::cmd::expect_success_and_text 'oc new-app ruby-helloworld-sample -o yaml' 'AD |
63 | 63 |
os::cmd::expect_success_and_text 'oc new-app ruby-helloworld-sample --param MYSQL_PASSWORD=hello -o yaml' 'hello' |
64 | 64 |
|
65 | 65 |
# verify we can create from a template when some objects in the template declare an app label |
66 |
-# the app label should still be applied to the other objects in the template. |
|
67 |
-os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-with-app-label.json -o yaml' 'app: ruby-helloworld-sample' |
|
68 |
-# verify the existing app label on an object is overridden by new-app |
|
69 |
-os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-app-label.json -o yaml' 'app: myapp' |
|
66 |
+# the app label will not be applied to any objects in the template. |
|
67 |
+os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-app-label.json -o yaml' 'app: ruby-helloworld-sample' |
|
68 |
+# verify the existing app label on an object is not overridden by new-app |
|
69 |
+os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-with-app-label.json -o yaml' 'app: myapp' |
|
70 | 70 |
|
71 | 71 |
# verify that a template can be passed in stdin |
72 | 72 |
os::cmd::expect_success 'cat examples/sample-app/application-template-stibuild.json | oc new-app -o yaml -f -' |
73 | 73 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,482 @@ |
0 |
+{ |
|
1 |
+ "kind": "Template", |
|
2 |
+ "apiVersion": "v1", |
|
3 |
+ "metadata": { |
|
4 |
+ "name": "ruby-helloworld-sample", |
|
5 |
+ "creationTimestamp": null, |
|
6 |
+ "annotations": { |
|
7 |
+ "description": "some objects in this template declare their own app label to confirm new-app will tolerate it", |
|
8 |
+ "iconClass": "icon-ruby", |
|
9 |
+ "tags": "instant-app,ruby,mysql" |
|
10 |
+ } |
|
11 |
+ }, |
|
12 |
+ "objects": [ |
|
13 |
+ { |
|
14 |
+ "kind": "Service", |
|
15 |
+ "apiVersion": "v1", |
|
16 |
+ "metadata": { |
|
17 |
+ "name": "frontend", |
|
18 |
+ "creationTimestamp": null |
|
19 |
+ }, |
|
20 |
+ "spec": { |
|
21 |
+ "ports": [ |
|
22 |
+ { |
|
23 |
+ "name": "web", |
|
24 |
+ "protocol": "TCP", |
|
25 |
+ "port": 5432, |
|
26 |
+ "targetPort": 8080, |
|
27 |
+ "nodePort": 0 |
|
28 |
+ } |
|
29 |
+ ], |
|
30 |
+ "selector": { |
|
31 |
+ "name": "frontend" |
|
32 |
+ }, |
|
33 |
+ "portalIP": "", |
|
34 |
+ "type": "ClusterIP", |
|
35 |
+ "sessionAffinity": "None" |
|
36 |
+ }, |
|
37 |
+ "status": { |
|
38 |
+ "loadBalancer": {} |
|
39 |
+ } |
|
40 |
+ }, |
|
41 |
+ { |
|
42 |
+ "kind": "Route", |
|
43 |
+ "apiVersion": "v1", |
|
44 |
+ "metadata": { |
|
45 |
+ "name": "route-edge", |
|
46 |
+ "creationTimestamp": null |
|
47 |
+ }, |
|
48 |
+ "spec": { |
|
49 |
+ "host": "www.example.com", |
|
50 |
+ "to": { |
|
51 |
+ "kind": "Service", |
|
52 |
+ "name": "frontend" |
|
53 |
+ }, |
|
54 |
+ "tls": { |
|
55 |
+ "termination": "edge", |
|
56 |
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBoTELMAkGA1UEBhMCVVMx\nCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl\nZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0ExGjAYBgNVBAMMEXd3\ndy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\nY29tMB4XDTE1MDExMjE0MTk0MVoXDTE2MDExMjE0MTk0MVowfDEYMBYGA1UEAwwP\nd3d3LmV4YW1wbGUuY29tMQswCQYDVQQIDAJTQzELMAkGA1UEBhMCVVMxIjAgBgkq\nhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xEDAOBgNVBAoMB0V4YW1wbGUx\nEDAOBgNVBAsMB0V4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrv\ngu6ZTTefNN7jjiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm\n47VRx5Qrf/YLXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1M\nmNrQUgZyQC6XIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAGjDTALMAkGA1UdEwQC\nMAAwDQYJKoZIhvcNAQEFBQADggEBAFCi7ZlkMnESvzlZCvv82Pq6S46AAOTPXdFd\nTMvrh12E1sdVALF1P1oYFJzG1EiZ5ezOx88fEDTW+Lxb9anw5/KJzwtWcfsupf1m\nV7J0D3qKzw5C1wjzYHh9/Pz7B1D0KthQRATQCfNf8s6bbFLaw/dmiIUhHLtIH5Qc\nyfrejTZbOSP77z8NOWir+BWWgIDDB2//3AkDIQvT20vmkZRhkqSdT7et4NmXOX/j\njhPti4b2Fie0LeuvgaOdKjCpQQNrYthZHXeVlOLRhMTSk3qUczenkKTOhvP7IS9q\n+Dzv5hqgSfvMG392KWh5f8xXfJNs4W5KLbZyl901MeReiLrPH3w=\n-----END CERTIFICATE-----", |
|
57 |
+ "key": "-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMrvgu6ZTTefNN7j\njiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm47VRx5Qrf/YL\nXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1MmNrQUgZyQC6X\nIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAECgYEAnxOjEj/vrLNLMZE1Q9H7PZVF\nWdP/JQVNvQ7tCpZ3ZdjxHwkvf//aQnuxS5yX2Rnf37BS/TZu+TIkK4373CfHomSx\nUTAn2FsLmOJljupgGcoeLx5K5nu7B7rY5L1NHvdpxZ4YjeISrRtEPvRakllENU5y\ngJE8c2eQOx08ZSRE4TkCQQD7dws2/FldqwdjJucYijsJVuUdoTqxP8gWL6bB251q\nelP2/a6W2elqOcWId28560jG9ZS3cuKvnmu/4LG88vZFAkEAzphrH3673oTsHN+d\nuBd5uyrlnGjWjuiMKv2TPITZcWBjB8nJDSvLneHF59MYwejNNEof2tRjgFSdImFH\nmi995wJBAMtPjW6wiqRz0i41VuT9ZgwACJBzOdvzQJfHgSD9qgFb1CU/J/hpSRIM\nkYvrXK9MbvQFvG6x4VuyT1W8mpe1LK0CQAo8VPpffhFdRpF7psXLK/XQ/0VLkG3O\nKburipLyBg/u9ZkaL0Ley5zL5dFBjTV2Qkx367Ic2b0u9AYTCcgi2DsCQQD3zZ7B\nv7BOm7MkylKokY2MduFFXU0Bxg6pfZ7q3rvg8gqhUFbaMStPRYg6myiDiW/JfLhF\nTcFT4touIo7oriFJ\n-----END PRIVATE KEY-----", |
|
58 |
+ "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEFzCCAv+gAwIBAgIJALK1iUpF2VQLMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCU0MxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoG\nA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UECwwHVGVzdCBDQTEaMBgG\nA1UEAwwRd3d3LmV4YW1wbGVjYS5jb20xIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVA\nZXhhbXBsZS5jb20wHhcNMTUwMTEyMTQxNTAxWhcNMjUwMTA5MTQxNTAxWjCBoTEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkx\nHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0Ex\nGjAYBgNVBAMMEXd3dy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFt\ncGxlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nw2rK1J2NMtQj0KDug7g7HRKl5jbf0QMkMKyTU1fBtZ0cCzvsF4CqV11LK4BSVWaK\nrzkaXe99IVJnH8KdOlDl5Dh/+cJ3xdkClSyeUT4zgb6CCBqg78ePp+nN11JKuJlV\nIG1qdJpB1J5O/kCLsGcTf7RS74MtqMFo96446Zvt7YaBhWPz6gDaO/TUzfrNcGLA\nEfHVXkvVWqb3gqXUztZyVex/gtP9FXQ7gxTvJml7UkmT0VAFjtZnCqmFxpLZFZ15\n+qP9O7Q2MpsGUO/4vDAuYrKBeg1ZdPSi8gwqUP2qWsGd9MIWRv3thI2903BczDc7\nr8WaIbm37vYZAS9G56E4+wIDAQABo1AwTjAdBgNVHQ4EFgQUugLrSJshOBk5TSsU\nANs4+SmJUGwwHwYDVR0jBBgwFoAUugLrSJshOBk5TSsUANs4+SmJUGwwDAYDVR0T\nBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaMJ33zAMV4korHo5aPfayV3uHoYZ\n1ChzP3eSsF+FjoscpoNSKs91ZXZF6LquzoNezbfiihK4PYqgwVD2+O0/Ty7UjN4S\nqzFKVR4OS/6lCJ8YncxoFpTntbvjgojf1DEataKFUN196PAANc3yz8cWHF4uvjPv\nWkgFqbIjb+7D1YgglNyovXkRDlRZl0LD1OQ0ZWhd4Ge1qx8mmmanoBeYZ9+DgpFC\nj9tQAbS867yeOryNe7sEOIpXAAqK/DTu0hB6+ySsDfMo4piXCc2aA/eI2DCuw08e\nw17Dz9WnupZjVdwTKzDhFgJZMLDqn37HQnT6EemLFqbcR0VPEnfyhDtZIQ==\n-----END CERTIFICATE-----" |
|
59 |
+ } |
|
60 |
+ }, |
|
61 |
+ "status": {} |
|
62 |
+ }, |
|
63 |
+ { |
|
64 |
+ "kind": "ImageStream", |
|
65 |
+ "apiVersion": "v1", |
|
66 |
+ "metadata": { |
|
67 |
+ "name": "origin-ruby-sample", |
|
68 |
+ "creationTimestamp": null |
|
69 |
+ }, |
|
70 |
+ "spec": {}, |
|
71 |
+ "status": { |
|
72 |
+ "dockerImageRepository": "" |
|
73 |
+ } |
|
74 |
+ }, |
|
75 |
+ { |
|
76 |
+ "kind": "ImageStream", |
|
77 |
+ "apiVersion": "v1", |
|
78 |
+ "metadata": { |
|
79 |
+ "name": "ruby-22-centos7", |
|
80 |
+ "creationTimestamp": null |
|
81 |
+ }, |
|
82 |
+ "spec": { |
|
83 |
+ "dockerImageRepository": "centos/ruby-22-centos7" |
|
84 |
+ }, |
|
85 |
+ "status": { |
|
86 |
+ "dockerImageRepository": "" |
|
87 |
+ } |
|
88 |
+ }, |
|
89 |
+ { |
|
90 |
+ "kind": "BuildConfig", |
|
91 |
+ "apiVersion": "v1", |
|
92 |
+ "metadata": { |
|
93 |
+ "name": "ruby-sample-build", |
|
94 |
+ "creationTimestamp": null, |
|
95 |
+ "labels": { |
|
96 |
+ "name": "ruby-sample-build" |
|
97 |
+ } |
|
98 |
+ }, |
|
99 |
+ "spec": { |
|
100 |
+ "triggers": [ |
|
101 |
+ { |
|
102 |
+ "type": "GitHub", |
|
103 |
+ "github": { |
|
104 |
+ "secret": "secret101" |
|
105 |
+ } |
|
106 |
+ }, |
|
107 |
+ { |
|
108 |
+ "type": "Generic", |
|
109 |
+ "generic": { |
|
110 |
+ "secret": "secret101" |
|
111 |
+ } |
|
112 |
+ }, |
|
113 |
+ { |
|
114 |
+ "type": "ImageChange", |
|
115 |
+ "imageChange": {} |
|
116 |
+ }, |
|
117 |
+ { |
|
118 |
+ "type": "ConfigChange" |
|
119 |
+ } |
|
120 |
+ ], |
|
121 |
+ "source": { |
|
122 |
+ "type": "Git", |
|
123 |
+ "git": { |
|
124 |
+ "uri": "https://github.com/openshift/ruby-hello-world.git" |
|
125 |
+ } |
|
126 |
+ }, |
|
127 |
+ "strategy": { |
|
128 |
+ "type": "Source", |
|
129 |
+ "sourceStrategy": { |
|
130 |
+ "from": { |
|
131 |
+ "kind": "ImageStreamTag", |
|
132 |
+ "name": "ruby-22-centos7:latest" |
|
133 |
+ }, |
|
134 |
+ "env": [ |
|
135 |
+ { |
|
136 |
+ "name": "EXAMPLE", |
|
137 |
+ "value": "sample-app" |
|
138 |
+ } |
|
139 |
+ ] |
|
140 |
+ } |
|
141 |
+ }, |
|
142 |
+ "output": { |
|
143 |
+ "to": { |
|
144 |
+ "kind": "ImageStreamTag", |
|
145 |
+ "name": "origin-ruby-sample:latest" |
|
146 |
+ } |
|
147 |
+ }, |
|
148 |
+ "postCommit": { |
|
149 |
+ "args": ["bundle", "exec", "rake", "test"] |
|
150 |
+ }, |
|
151 |
+ "resources": {} |
|
152 |
+ }, |
|
153 |
+ "status": { |
|
154 |
+ "lastVersion": 0 |
|
155 |
+ } |
|
156 |
+ }, |
|
157 |
+ { |
|
158 |
+ "kind": "DeploymentConfig", |
|
159 |
+ "apiVersion": "v1", |
|
160 |
+ "metadata": { |
|
161 |
+ "name": "frontend", |
|
162 |
+ "creationTimestamp": null |
|
163 |
+ }, |
|
164 |
+ "spec": { |
|
165 |
+ "strategy": { |
|
166 |
+ "type": "Rolling", |
|
167 |
+ "rollingParams": { |
|
168 |
+ "updatePeriodSeconds": 1, |
|
169 |
+ "intervalSeconds": 1, |
|
170 |
+ "timeoutSeconds": 120, |
|
171 |
+ "pre": { |
|
172 |
+ "failurePolicy": "Abort", |
|
173 |
+ "execNewPod": { |
|
174 |
+ "command": [ |
|
175 |
+ "/bin/true" |
|
176 |
+ ], |
|
177 |
+ "env": [ |
|
178 |
+ { |
|
179 |
+ "name": "CUSTOM_VAR1", |
|
180 |
+ "value": "custom_value1" |
|
181 |
+ } |
|
182 |
+ ], |
|
183 |
+ "containerName": "ruby-helloworld" |
|
184 |
+ } |
|
185 |
+ }, |
|
186 |
+ "post": { |
|
187 |
+ "failurePolicy": "Ignore", |
|
188 |
+ "execNewPod": { |
|
189 |
+ "command": [ |
|
190 |
+ "/bin/false" |
|
191 |
+ ], |
|
192 |
+ "env": [ |
|
193 |
+ { |
|
194 |
+ "name": "CUSTOM_VAR2", |
|
195 |
+ "value": "custom_value2" |
|
196 |
+ } |
|
197 |
+ ], |
|
198 |
+ "containerName": "ruby-helloworld" |
|
199 |
+ } |
|
200 |
+ } |
|
201 |
+ }, |
|
202 |
+ "resources": {} |
|
203 |
+ }, |
|
204 |
+ "triggers": [ |
|
205 |
+ { |
|
206 |
+ "type": "ImageChange", |
|
207 |
+ "imageChangeParams": { |
|
208 |
+ "automatic": true, |
|
209 |
+ "containerNames": [ |
|
210 |
+ "ruby-helloworld" |
|
211 |
+ ], |
|
212 |
+ "from": { |
|
213 |
+ "kind": "ImageStreamTag", |
|
214 |
+ "name": "origin-ruby-sample:latest" |
|
215 |
+ } |
|
216 |
+ } |
|
217 |
+ }, |
|
218 |
+ { |
|
219 |
+ "type": "ConfigChange" |
|
220 |
+ } |
|
221 |
+ ], |
|
222 |
+ "replicas": 2, |
|
223 |
+ "selector": { |
|
224 |
+ "name": "frontend" |
|
225 |
+ }, |
|
226 |
+ "template": { |
|
227 |
+ "metadata": { |
|
228 |
+ "creationTimestamp": null, |
|
229 |
+ "labels": { |
|
230 |
+ "name": "frontend" |
|
231 |
+ } |
|
232 |
+ }, |
|
233 |
+ "spec": { |
|
234 |
+ "containers": [ |
|
235 |
+ { |
|
236 |
+ "name": "ruby-helloworld", |
|
237 |
+ "image": "origin-ruby-sample", |
|
238 |
+ "ports": [ |
|
239 |
+ { |
|
240 |
+ "containerPort": 8080, |
|
241 |
+ "protocol": "TCP" |
|
242 |
+ } |
|
243 |
+ ], |
|
244 |
+ "env": [ |
|
245 |
+ { |
|
246 |
+ "name": "ADMIN_USERNAME", |
|
247 |
+ "value": "${ADMIN_USERNAME}" |
|
248 |
+ }, |
|
249 |
+ { |
|
250 |
+ "name": "ADMIN_PASSWORD", |
|
251 |
+ "value": "${ADMIN_PASSWORD}" |
|
252 |
+ }, |
|
253 |
+ { |
|
254 |
+ "name": "MYSQL_USER", |
|
255 |
+ "value": "${MYSQL_USER}" |
|
256 |
+ }, |
|
257 |
+ { |
|
258 |
+ "name": "MYSQL_PASSWORD", |
|
259 |
+ "value": "${MYSQL_PASSWORD}" |
|
260 |
+ }, |
|
261 |
+ { |
|
262 |
+ "name": "MYSQL_DATABASE", |
|
263 |
+ "value": "${MYSQL_DATABASE}" |
|
264 |
+ } |
|
265 |
+ ], |
|
266 |
+ "resources": {}, |
|
267 |
+ "terminationMessagePath": "/dev/termination-log", |
|
268 |
+ "imagePullPolicy": "IfNotPresent", |
|
269 |
+ "securityContext": { |
|
270 |
+ "capabilities": {}, |
|
271 |
+ "privileged": false |
|
272 |
+ } |
|
273 |
+ } |
|
274 |
+ ], |
|
275 |
+ "restartPolicy": "Always", |
|
276 |
+ "dnsPolicy": "ClusterFirst" |
|
277 |
+ } |
|
278 |
+ } |
|
279 |
+ }, |
|
280 |
+ "status": {} |
|
281 |
+ }, |
|
282 |
+ { |
|
283 |
+ "kind": "Service", |
|
284 |
+ "apiVersion": "v1", |
|
285 |
+ "metadata": { |
|
286 |
+ "name": "database", |
|
287 |
+ "creationTimestamp": null |
|
288 |
+ }, |
|
289 |
+ "spec": { |
|
290 |
+ "ports": [ |
|
291 |
+ { |
|
292 |
+ "name": "db", |
|
293 |
+ "protocol": "TCP", |
|
294 |
+ "port": 5434, |
|
295 |
+ "targetPort": 3306, |
|
296 |
+ "nodePort": 0 |
|
297 |
+ } |
|
298 |
+ ], |
|
299 |
+ "selector": { |
|
300 |
+ "name": "database" |
|
301 |
+ }, |
|
302 |
+ "portalIP": "", |
|
303 |
+ "type": "ClusterIP", |
|
304 |
+ "sessionAffinity": "None" |
|
305 |
+ }, |
|
306 |
+ "status": { |
|
307 |
+ "loadBalancer": {} |
|
308 |
+ } |
|
309 |
+ }, |
|
310 |
+ { |
|
311 |
+ "kind": "DeploymentConfig", |
|
312 |
+ "apiVersion": "v1", |
|
313 |
+ "metadata": { |
|
314 |
+ "name": "database", |
|
315 |
+ "creationTimestamp": null |
|
316 |
+ }, |
|
317 |
+ "spec": { |
|
318 |
+ "strategy": { |
|
319 |
+ "type": "Recreate", |
|
320 |
+ "recreateParams": { |
|
321 |
+ "pre": { |
|
322 |
+ "failurePolicy": "Abort", |
|
323 |
+ "execNewPod": { |
|
324 |
+ "command": [ |
|
325 |
+ "/bin/true" |
|
326 |
+ ], |
|
327 |
+ "env": [ |
|
328 |
+ { |
|
329 |
+ "name": "CUSTOM_VAR1", |
|
330 |
+ "value": "custom_value1" |
|
331 |
+ } |
|
332 |
+ ], |
|
333 |
+ "containerName": "ruby-helloworld-database", |
|
334 |
+ "volumes": ["ruby-helloworld-data"] |
|
335 |
+ } |
|
336 |
+ }, |
|
337 |
+ "mid": { |
|
338 |
+ "failurePolicy": "Abort", |
|
339 |
+ "execNewPod": { |
|
340 |
+ "command": [ |
|
341 |
+ "/bin/true" |
|
342 |
+ ], |
|
343 |
+ "env": [ |
|
344 |
+ { |
|
345 |
+ "name": "CUSTOM_VAR2", |
|
346 |
+ "value": "custom_value2" |
|
347 |
+ } |
|
348 |
+ ], |
|
349 |
+ "containerName": "ruby-helloworld-database", |
|
350 |
+ "volumes": ["ruby-helloworld-data"] |
|
351 |
+ } |
|
352 |
+ }, |
|
353 |
+ "post": { |
|
354 |
+ "failurePolicy": "Ignore", |
|
355 |
+ "execNewPod": { |
|
356 |
+ "command": [ |
|
357 |
+ "/bin/false" |
|
358 |
+ ], |
|
359 |
+ "env": [ |
|
360 |
+ { |
|
361 |
+ "name": "CUSTOM_VAR2", |
|
362 |
+ "value": "custom_value2" |
|
363 |
+ } |
|
364 |
+ ], |
|
365 |
+ "containerName": "ruby-helloworld-database", |
|
366 |
+ "volumes": ["ruby-helloworld-data"] |
|
367 |
+ } |
|
368 |
+ } |
|
369 |
+ }, |
|
370 |
+ "resources": {} |
|
371 |
+ }, |
|
372 |
+ "triggers": [ |
|
373 |
+ { |
|
374 |
+ "type": "ConfigChange" |
|
375 |
+ } |
|
376 |
+ ], |
|
377 |
+ "replicas": 1, |
|
378 |
+ "selector": { |
|
379 |
+ "name": "database" |
|
380 |
+ }, |
|
381 |
+ "template": { |
|
382 |
+ "metadata": { |
|
383 |
+ "creationTimestamp": null, |
|
384 |
+ "labels": { |
|
385 |
+ "name": "database" |
|
386 |
+ } |
|
387 |
+ }, |
|
388 |
+ "spec": { |
|
389 |
+ "containers": [ |
|
390 |
+ { |
|
391 |
+ "name": "ruby-helloworld-database", |
|
392 |
+ "image": "openshift/mysql-55-centos7:latest", |
|
393 |
+ "ports": [ |
|
394 |
+ { |
|
395 |
+ "containerPort": 3306, |
|
396 |
+ "protocol": "TCP" |
|
397 |
+ } |
|
398 |
+ ], |
|
399 |
+ "env": [ |
|
400 |
+ { |
|
401 |
+ "name": "MYSQL_USER", |
|
402 |
+ "value": "${MYSQL_USER}" |
|
403 |
+ }, |
|
404 |
+ { |
|
405 |
+ "name": "MYSQL_PASSWORD", |
|
406 |
+ "value": "${MYSQL_PASSWORD}" |
|
407 |
+ }, |
|
408 |
+ { |
|
409 |
+ "name": "MYSQL_DATABASE", |
|
410 |
+ "value": "${MYSQL_DATABASE}" |
|
411 |
+ } |
|
412 |
+ ], |
|
413 |
+ "resources": {}, |
|
414 |
+ "volumeMounts": [ |
|
415 |
+ { |
|
416 |
+ "name": "ruby-helloworld-data", |
|
417 |
+ "mountPath": "/var/lib/mysql/data" |
|
418 |
+ } |
|
419 |
+ ], |
|
420 |
+ "terminationMessagePath": "/dev/termination-log", |
|
421 |
+ "imagePullPolicy": "Always", |
|
422 |
+ "securityContext": { |
|
423 |
+ "capabilities": {}, |
|
424 |
+ "privileged": false |
|
425 |
+ } |
|
426 |
+ } |
|
427 |
+ ], |
|
428 |
+ "volumes": [ |
|
429 |
+ { |
|
430 |
+ "name": "ruby-helloworld-data", |
|
431 |
+ "emptyDir": { |
|
432 |
+ "medium": "" |
|
433 |
+ } |
|
434 |
+ } |
|
435 |
+ ], |
|
436 |
+ "restartPolicy": "Always", |
|
437 |
+ "dnsPolicy": "ClusterFirst" |
|
438 |
+ } |
|
439 |
+ } |
|
440 |
+ }, |
|
441 |
+ "status": {} |
|
442 |
+ } |
|
443 |
+ ], |
|
444 |
+ "parameters": [ |
|
445 |
+ { |
|
446 |
+ "name": "ADMIN_USERNAME", |
|
447 |
+ "description": "administrator username", |
|
448 |
+ "generate": "expression", |
|
449 |
+ "from": "admin[A-Z0-9]{3}" |
|
450 |
+ }, |
|
451 |
+ { |
|
452 |
+ "name": "ADMIN_PASSWORD", |
|
453 |
+ "description": "administrator password", |
|
454 |
+ "generate": "expression", |
|
455 |
+ "from": "[a-zA-Z0-9]{8}" |
|
456 |
+ }, |
|
457 |
+ { |
|
458 |
+ "name": "MYSQL_USER", |
|
459 |
+ "description": "database username", |
|
460 |
+ "generate": "expression", |
|
461 |
+ "from": "user[A-Z0-9]{3}", |
|
462 |
+ "required": true |
|
463 |
+ }, |
|
464 |
+ { |
|
465 |
+ "name": "MYSQL_PASSWORD", |
|
466 |
+ "description": "database password", |
|
467 |
+ "generate": "expression", |
|
468 |
+ "from": "[a-zA-Z0-9]{8}", |
|
469 |
+ "required": true |
|
470 |
+ }, |
|
471 |
+ { |
|
472 |
+ "name": "MYSQL_DATABASE", |
|
473 |
+ "description": "database name", |
|
474 |
+ "value": "root", |
|
475 |
+ "required": true |
|
476 |
+ } |
|
477 |
+ ], |
|
478 |
+ "labels": { |
|
479 |
+ "template": "application-template-stibuild" |
|
480 |
+ } |
|
481 |
+} |