Skip to content

Commit 3c97587

Browse files
dymurrayShawn Hurley
authored andcommitted
test/ansible, pkg/scaffold; Update Ansible Operator CI to prevent failures (#985)
<!-- Before making a PR, please read our contributing guidelines https://github.com/operator-framework/operator-sdk/blob/master/CONTRIBUTING.MD Note: Make sure your branch is rebased to the latest upstream master. --> **Description of the change:** Updates Travis CI Molecule tasks to prevent transient errors. Also updates CI to dump operator logs if reconciliation fails. **Motivation for the change:** Fail CI less often for transient errors and make CI more robust. <!-- Note: If this PR is fixing an issue make sure to add a note saying: Closes #<ISSUE_NUMBER> -->
1 parent 1b3a305 commit 3c97587

File tree

3 files changed

+206
-116
lines changed

3 files changed

+206
-116
lines changed

pkg/scaffold/ansible/molecule_test_cluster_playbook.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const moleculeTestClusterPlaybookAnsibleTmpl = `---
4747
ansible_python_interpreter: '{{ "{{ ansible_playbook_python }}" }}'
4848
deploy_dir: "{{"{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"}}"
4949
image_name: {{.Resource.FullGroup}}/{{.ProjectName}}:testing
50+
custom_resource: "{{"{{"}} lookup('file', '/'.join([deploy_dir, 'crds/{{.Resource.Group}}_{{.Resource.Version}}_{{.Resource.LowerKind}}_cr.yaml'])) | from_yaml {{"}}"}}"
5051
tasks:
5152
- name: Create the {{.Resource.FullGroup}}/{{.Resource.Version}}.{{.Resource.Kind}}
5253
k8s:
@@ -55,9 +56,19 @@ const moleculeTestClusterPlaybookAnsibleTmpl = `---
5556
5657
- name: Get the newly created Custom Resource
5758
debug:
58-
msg: "{{"{{"}} lookup('k8s', group='{{.Resource.FullGroup}}', api_version='{{.Resource.Version}}', kind='{{.Resource.Kind}}', namespace=namespace, resource_name=cr.metadata.name) {{"}}"}}"
59-
vars:
60-
cr: "{{"{{"}} lookup('file', '/'.join([deploy_dir, 'crds/{{.Resource.Group}}_{{.Resource.Version}}_{{.Resource.LowerKind}}_cr.yaml'])) | from_yaml {{"}}"}}"
59+
msg: "{{"{{"}} lookup('k8s', group='{{.Resource.FullGroup}}', api_version='{{.Resource.Version}}', kind='{{.Resource.Kind}}', namespace=namespace, resource_name=custom_resource.metadata.name) {{"}}"}}"
60+
61+
- name: Wait 40s for reconcilation to run
62+
k8s_facts:
63+
api_version: '{{.Resource.Version}}'
64+
kind: '{{.Resource.Kind }}'
65+
namespace: '{{"{{"}} namespace {{"}}"}}'
66+
name: '{{"{{"}} custom_resource.metadata.name {{"}}"}}'
67+
register: reconcile_cr
68+
until:
69+
- "'Successful' in (reconcile_cr | json_query('resources[].status.conditions[].reason'))"
70+
delay: 4
71+
retries: 10
6172
6273
- import_playbook: "{{"{{ playbook_dir }}/../default/asserts.yml"}}"
6374
`

pkg/scaffold/ansible/molecule_test_local_playbook.go

Lines changed: 86 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -66,50 +66,92 @@ const moleculeTestLocalPlaybookAnsibleTmpl = `---
6666
REPLACE_IMAGE: {{.Resource.FullGroup}}/{{.ProjectName}}:testing
6767
custom_resource: "{{"{{"}} lookup('file', '/'.join([deploy_dir, 'crds/{{.Resource.Group}}_{{.Resource.Version}}_{{.Resource.LowerKind}}_cr.yaml'])) | from_yaml {{"}}"}}"
6868
tasks:
69-
- name: Delete the Operator Deployment
70-
k8s:
71-
state: absent
72-
namespace: '{{ "{{ namespace }}" }}'
73-
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) {{"}}"}}"
74-
register: delete_deployment
75-
when: hostvars[groups.k8s.0].build_cmd.changed
76-
77-
- name: Wait 30s for Operator Deployment to terminate
78-
k8s_facts:
79-
api_version: '{{"{{"}} definition.apiVersion {{"}}"}}'
80-
kind: '{{"{{"}} definition.kind {{"}}"}}'
81-
namespace: '{{"{{"}} namespace {{"}}"}}'
82-
name: '{{"{{"}} definition.metadata.name {{"}}"}}'
83-
vars:
84-
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml {{"}}"}}"
85-
register: deployment
86-
until: not deployment.resources
87-
delay: 3
88-
retries: 10
89-
when: delete_deployment.changed
90-
91-
- name: Create the Operator Deployment
92-
k8s:
93-
namespace: '{{ "{{ namespace }}" }}'
94-
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) {{"}}"}}"
95-
96-
- name: Create the {{.Resource.FullGroup}}/{{.Resource.Version}}.{{.Resource.Kind}}
97-
k8s:
98-
state: present
99-
namespace: '{{ "{{ namespace }}" }}'
100-
definition: "{{ "{{ custom_resource }}" }}"
101-
102-
- name: Wait 40s for reconcilation to run
103-
k8s_facts:
104-
api_version: '{{"{{"}} custom_resource.apiVersion {{"}}"}}'
105-
kind: '{{"{{"}} custom_resource.kind {{"}}"}}'
106-
namespace: '{{"{{"}} namespace {{"}}"}}'
107-
name: '{{"{{"}} custom_resource.metadata.name {{"}}"}}'
108-
register: cr
109-
until:
110-
- "'Successful' in (cr | json_query('resources[].status.conditions[].reason'))"
111-
delay: 4
112-
retries: 10
69+
- block:
70+
- name: Delete the Operator Deployment
71+
k8s:
72+
state: absent
73+
namespace: '{{ "{{ namespace }}" }}'
74+
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) {{"}}"}}"
75+
register: delete_deployment
76+
when: hostvars[groups.k8s.0].build_cmd.changed
77+
78+
- name: Wait 30s for Operator Deployment to terminate
79+
k8s_facts:
80+
api_version: '{{"{{"}} definition.apiVersion {{"}}"}}'
81+
kind: '{{"{{"}} definition.kind {{"}}"}}'
82+
namespace: '{{"{{"}} namespace {{"}}"}}'
83+
name: '{{"{{"}} definition.metadata.name {{"}}"}}'
84+
vars:
85+
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml {{"}}"}}"
86+
register: deployment
87+
until: not deployment.resources
88+
delay: 3
89+
retries: 10
90+
when: delete_deployment.changed
91+
92+
- name: Create the Operator Deployment
93+
k8s:
94+
namespace: '{{ "{{ namespace }}" }}'
95+
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) {{"}}"}}"
96+
97+
- name: Create the {{.Resource.FullGroup}}/{{.Resource.Version}}.{{.Resource.Kind}}
98+
k8s:
99+
state: present
100+
namespace: '{{ "{{ namespace }}" }}'
101+
definition: "{{ "{{ custom_resource }}" }}"
102+
103+
- name: Wait 40s for reconcilation to run
104+
k8s_facts:
105+
api_version: '{{"{{"}} custom_resource.apiVersion {{"}}"}}'
106+
kind: '{{"{{"}} custom_resource.kind {{"}}"}}'
107+
namespace: '{{"{{"}} namespace {{"}}"}}'
108+
name: '{{"{{"}} custom_resource.metadata.name {{"}}"}}'
109+
register: cr
110+
until:
111+
- "'Successful' in (cr | json_query('resources[].status.conditions[].reason'))"
112+
delay: 4
113+
retries: 10
114+
rescue:
115+
- name: debug cr
116+
ignore_errors: yes
117+
failed_when: false
118+
debug:
119+
var: debug_cr
120+
vars:
121+
debug_cr: '{{"{{"}} lookup("k8s",
122+
kind=custom_resource.kind,
123+
api_version=custom_resource.apiVersion,
124+
namespace=namespace,
125+
resource_name=custom_resource.metadata.name
126+
){{"}}"}}'
127+
128+
- name: debug memcached lookup
129+
ignore_errors: yes
130+
failed_when: false
131+
debug:
132+
var: deploy
133+
vars:
134+
deploy: '{{"{{"}} lookup("k8s",
135+
kind="Deployment",
136+
api_version="apps/v1",
137+
namespace=namespace,
138+
label_selector="app=memcached"
139+
){{"}}"}}'
140+
141+
- name: get operator logs
142+
ignore_errors: yes
143+
failed_when: false
144+
command: kubectl logs deployment/{{"{{"}} definition.metadata.name {{"}}"}} -n {{"{{"}} namespace {{"}}"}}
145+
environment:
146+
KUBECONFIG: '{{"{{"}} lookup("env", "KUBECONFIG") {{"}}"}}'
147+
vars:
148+
definition: "{{"{{"}} lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml {{"}}"}}"
149+
register: log
150+
151+
- debug: var=log.stdout_lines
152+
153+
- fail:
154+
msg: "Failed on action: converge"
113155
114156
- import_playbook: '{{"{{ playbook_dir }}/../default/asserts.yml"}}'
115157
`

test/ansible-memcached/asserts.yml

Lines changed: 106 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,81 +8,118 @@
88
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
99
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/ansible_v1alpha1_memcached_cr.yaml'])) | from_yaml }}"
1010
tasks:
11+
- block:
12+
- name: debug memcached lookup
13+
debug:
14+
var: deploy
15+
vars:
16+
deploy: '{{ lookup("k8s",
17+
kind="Deployment",
18+
api_version="apps/v1",
19+
namespace=namespace,
20+
label_selector="app=memcached"
21+
)}}'
1122

12-
- name: debug memcached lookup
13-
debug:
14-
var: deploy
15-
vars:
16-
deploy: '{{ lookup("k8s",
17-
kind="Deployment",
18-
api_version="apps/v1",
19-
namespace=namespace,
20-
label_selector="app=memcached"
21-
)}}'
23+
- name: Wait 2 minutes for memcached deployment
24+
debug:
25+
var: deploy
26+
until: deploy and deploy.status and deploy.status.replicas == deploy.status.get("availableReplicas", 0)
27+
retries: 12
28+
delay: 10
29+
vars:
30+
deploy: '{{ lookup("k8s",
31+
kind="Deployment",
32+
api_version="apps/v1",
33+
namespace=namespace,
34+
label_selector="app=memcached"
35+
)}}'
2236

23-
- name: Wait 2 minutes for memcached deployment
24-
debug:
25-
var: deploy
26-
until: deploy and deploy.status and deploy.status.replicas == deploy.status.get("availableReplicas", 0)
27-
retries: 12
28-
delay: 10
29-
vars:
30-
deploy: '{{ lookup("k8s",
31-
kind="Deployment",
32-
api_version="apps/v1",
33-
namespace=namespace,
34-
label_selector="app=memcached"
35-
)}}'
37+
- name: Create ConfigMap that the Operator should delete
38+
k8s:
39+
definition:
40+
apiVersion: v1
41+
kind: ConfigMap
42+
metadata:
43+
name: deleteme
44+
namespace: '{{ namespace }}'
45+
data:
46+
delete: me
3647

37-
- name: Create ConfigMap that the Operator should delete
38-
k8s:
39-
definition:
40-
apiVersion: v1
41-
kind: ConfigMap
42-
metadata:
43-
name: deleteme
44-
namespace: '{{ namespace }}'
45-
data:
46-
delete: me
48+
- name: Verify custom status exists
49+
assert:
50+
that: debug_cr.status.get("test") == "hello world"
51+
vars:
52+
debug_cr: '{{ lookup("k8s",
53+
kind=custom_resource.kind,
54+
api_version=custom_resource.apiVersion,
55+
namespace=namespace,
56+
resource_name=custom_resource.metadata.name
57+
)}}'
4758

48-
- name: debug CR lookup
49-
debug:
50-
var: cr
51-
vars:
52-
deploy: '{{ lookup("k8s",
53-
kind=custom_resource.kind,
54-
api_version=custom_resource.apiVersion,
55-
namespace=namespace,
56-
resource_name=custom_resource.metadata.name
57-
)}}'
59+
- name: Delete the custom resource
60+
k8s:
61+
state: absent
62+
namespace: '{{ namespace }}'
63+
definition: '{{ custom_resource }}'
5864

59-
- name: Verify custom status exists
60-
assert:
61-
that: cr.resources[0].status.get("test") == "hello world"
62-
when: cr is defined
65+
- name: Wait for the custom resource to be deleted
66+
k8s_facts:
67+
api_version: '{{ custom_resource.apiVersion }}'
68+
kind: '{{ custom_resource.kind }}'
69+
namespace: '{{ namespace }}'
70+
name: '{{ custom_resource.metadata.name }}'
71+
register: cr
72+
retries: 10
73+
delay: 2
74+
until: not cr.resources
75+
failed_when: cr.resources
6376

64-
- name: Delete the custom resource
65-
k8s:
66-
state: absent
67-
namespace: '{{ namespace }}'
68-
definition: '{{ custom_resource }}'
77+
- name: Verify the ConfigMap was deleted
78+
assert:
79+
that: not lookup('k8s', kind='ConfigMap', api_version='v1', namespace=namespace, resource_name='deleteme')
6980

70-
- name: Wait for the custom resource to be deleted
71-
k8s_facts:
72-
api_version: '{{ custom_resource.apiVersion }}'
73-
kind: '{{ custom_resource.kind }}'
74-
namespace: '{{ namespace }}'
75-
name: '{{ custom_resource.metadata.name }}'
76-
register: cr
77-
retries: 10
78-
delay: 2
79-
until: not cr.resources
80-
failed_when: cr.resources
81+
- name: Verify the Deployment was deleted (wait 30s)
82+
assert:
83+
that: not lookup('k8s', kind='Deployment', api_version='apps/v1', namespace=namespace, label_selector='app=memcached')
84+
retries: 10
85+
delay: 3
8186

82-
- name: Verify the ConfigMap was deleted
83-
assert:
84-
that: not lookup('k8s', kind='ConfigMap', api_version='v1', namespace=namespace, resource_name='deleteme')
87+
rescue:
88+
- name: debug cr
89+
ignore_errors: yes
90+
failed_when: false
91+
debug:
92+
var: debug_cr
93+
vars:
94+
debug_cr: '{{ lookup("k8s",
95+
kind=custom_resource.kind,
96+
api_version=custom_resource.apiVersion,
97+
namespace=namespace,
98+
resource_name=custom_resource.metadata.name
99+
)}}'
85100

86-
- name: Verify the Deployment was deleted
87-
assert:
88-
that: not lookup('k8s', kind='Deployment', api_version='apps/v1', namespace=namespace, label_selector='app=memcached')
101+
- name: debug memcached lookup
102+
ignore_errors: yes
103+
failed_when: false
104+
debug:
105+
var: deploy
106+
vars:
107+
deploy: '{{ lookup("k8s",
108+
kind="Deployment",
109+
api_version="apps/v1",
110+
namespace=namespace,
111+
label_selector="app=memcached"
112+
)}}'
113+
114+
- name: get operator logs
115+
ignore_errors: yes
116+
failed_when: false
117+
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ namespace }}
118+
vars:
119+
definition: "{{ lookup('file', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml }}"
120+
register: log
121+
122+
- debug: var=log.stdout_lines
123+
124+
- fail:
125+
msg: "Failed in asserts.yml"

0 commit comments

Comments
 (0)