Skip to content

Commit 1ca4f58

Browse files
fabianvfShawn Hurley
authored andcommitted
pkg/ansible: Add log aggregator sidecar for Ansible Operator (#1193)
* Add log aggregator sidecar for Ansible Operator * add missing dependency * rename operator container to operator, update CI * accidentally mounted operator fs readOnly * add scaffold to migrate command * add docs on new logging container
1 parent 4ab4996 commit 1ca4f58

File tree

9 files changed

+124
-9
lines changed

9 files changed

+124
-9
lines changed

commands/operator-sdk/cmd/migrate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func migrateAnsible() error {
9191
&ansible.Entrypoint{},
9292
&ansible.UserSetup{},
9393
&ansible.K8sStatus{},
94+
&ansible.AoLogs{},
9495
)
9596
if err != nil {
9697
return fmt.Errorf("migrate ansible scaffold failed: (%v)", err)

doc/ansible/dev/developer_guide.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,21 @@ NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
321321
foo-operator 1 1 1 1 1m
322322
```
323323

324+
#### Viewing the Ansible logs
325+
326+
The `foo-operator` deployment creates a Pod with two containers, `operator` and `ansible`.
327+
The `ansible` container exists only to expose the standard Ansible stdout logs that most Ansible
328+
users will be familiar with. In order to see the logs from a particular container, you can run
329+
330+
```sh
331+
kubectl logs deployment/foo-operator -c ansible
332+
kubectl logs deployment/foo-operator -c operator
333+
```
334+
335+
The `ansible` logs contain all of the information about the Ansible run and will make it much easier to debug issues within your Ansible tasks,
336+
whereas the `operator` logs will contain much more detailed information about the Ansible Operator's internals and interface with Kubernetes.
337+
338+
324339
## Custom Resource Status Management
325340
The operator will automatically update the CR's `status` subresource with
326341
generic information about the previous Ansible run. This includes the number of

doc/ansible/user-guide.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,23 @@ NAME READY STATUS RESTARTS AGE
365365
example-memcached-6fd7c98d8-7dqdr 1/1 Running 0 1m
366366
example-memcached-6fd7c98d8-g5k7v 1/1 Running 0 1m
367367
example-memcached-6fd7c98d8-m7vn7 1/1 Running 0 1m
368-
memcached-operator-7cc7cfdf86-vvjqk 1/1 Running 0 2m
368+
memcached-operator-7cc7cfdf86-vvjqk 2/2 Running 0 2m
369369
```
370370

371+
### View the Ansible logs
372+
373+
The `memcached-operator` deployment creates a Pod with two containers, `operator` and `ansible`.
374+
The `ansible` container exists only to expose the standard Ansible stdout logs that most Ansible
375+
users will be familiar with. In order to see the logs from a particular container, you can run
376+
377+
```sh
378+
kubectl logs deployment/memcached-operator -c ansible
379+
kubectl logs deployment/memcached-operator -c operator
380+
```
381+
382+
The `ansible` logs contain all of the information about the Ansible run and will make it much easier to debug issues within your Ansible tasks,
383+
whereas the `operator` logs will contain much more detailed information about the Ansible Operator's internals and interface with Kubernetes.
384+
371385
### Update the size
372386

373387
Change the `spec.size` field in the memcached CR from 3 to 4 and apply the

hack/image/ansible/scaffold-ansible-image.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func main() {
3939
&ansible.Entrypoint{},
4040
&ansible.UserSetup{},
4141
&ansible.K8sStatus{},
42+
&ansible.AoLogs{},
4243
)
4344
if err != nil {
4445
log.Fatalf("Add scaffold failed: (%v)", err)

hack/tests/e2e-ansible.sh

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ test_operator() {
3535
if ! timeout 1m kubectl rollout status deployment/memcached-operator;
3636
then
3737
echo FAIL: operator failed to run
38-
kubectl logs deployment/memcached-operator
38+
kubectl logs deployment/memcached-operator -c operator
39+
kubectl logs deployment/memcached-operator -c ansible
3940
exit 1
4041
fi
4142

@@ -44,7 +45,8 @@ test_operator() {
4445
if ! timeout 20s bash -c -- 'until kubectl get deployment -l app=memcached | grep memcached; do sleep 1; done';
4546
then
4647
echo FAIL: operator failed to create memcached Deployment
47-
kubectl logs deployment/memcached-operator
48+
kubectl logs deployment/memcached-operator -c operator
49+
kubectl logs deployment/memcached-operator -c ansible
4850
exit 1
4951
fi
5052
memcached_deployment=$(kubectl get deployment -l app=memcached -o jsonpath="{..metadata.name}")
@@ -65,23 +67,26 @@ test_operator() {
6567
if kubectl get configmap deleteme 2> /dev/null;
6668
then
6769
echo FAIL: the finalizer did not delete the configmap
68-
kubectl logs deployment/memcached-operator
70+
kubectl logs deployment/memcached-operator -c operator
71+
kubectl logs deployment/memcached-operator -c ansible
6972
exit 1
7073
fi
7174

7275
# The deployment should get garbage collected, so we expect to fail getting the deployment.
7376
if ! timeout 20s bash -c -- "while kubectl get deployment ${memcached_deployment} 2> /dev/null; do sleep 1; done";
7477
then
7578
echo FAIL: memcached Deployment did not get garbage collected
76-
kubectl logs deployment/memcached-operator
79+
kubectl logs deployment/memcached-operator -c operator
80+
kubectl logs deployment/memcached-operator -c ansible
7781
exit 1
7882
fi
7983

8084
# Ensure that no errors appear in the log
81-
if kubectl logs deployment/memcached-operator | grep -i error;
85+
if kubectl logs deployment/memcached-operator -c operator | grep -i error;
8286
then
8387
echo FAIL: the operator log includes errors
84-
kubectl logs deployment/memcached-operator
88+
kubectl logs deployment/memcached-operator -c operator
89+
kubectl logs deployment/memcached-operator -c ansible
8590
exit 1
8691
fi
8792
}

pkg/scaffold/ansible/ao_logs.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2019 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package ansible
16+
17+
import (
18+
"path/filepath"
19+
20+
"github.com/operator-framework/operator-sdk/pkg/scaffold/input"
21+
)
22+
23+
//DockerfileHybrid - Dockerfile for a hybrid operator
24+
type AoLogs struct {
25+
input.Input
26+
}
27+
28+
// GetInput - gets the input
29+
func (a *AoLogs) GetInput() (input.Input, error) {
30+
if a.Path == "" {
31+
a.Path = filepath.Join("bin", "ao-logs")
32+
}
33+
a.TemplateBody = aoLogsTmpl
34+
a.IsExec = true
35+
return a.Input, nil
36+
}
37+
38+
const aoLogsTmpl = `#!/bin/bash
39+
40+
watch_dir=${1:-/tmp/ansible-operator/runner}
41+
filename=${2:-stdout}
42+
mkdir -p ${watch_dir}
43+
inotifywait -r -m -e close_write ${watch_dir} | while read dir op file
44+
do
45+
if [[ "${file}" = "${filename}" ]] ; then
46+
echo "${dir}/${file}"
47+
cat ${dir}/${file}
48+
fi
49+
done
50+
`

pkg/scaffold/ansible/deploy_operator.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,25 @@ spec:
5454
spec:
5555
serviceAccountName: {{.ProjectName}}
5656
containers:
57-
- name: {{.ProjectName}}
57+
- name: ansible
58+
command:
59+
- /usr/local/bin/ao-logs
60+
- /tmp/ansible-operator/runner
61+
- stdout
5862
# Replace this with the built image name
5963
image: "{{ "{{ REPLACE_IMAGE }}" }}"
6064
imagePullPolicy: "{{ "{{ pull_policy|default('Always') }}"}}"
65+
volumeMounts:
66+
- mountPath: /tmp/ansible-operator/runner
67+
name: runner
68+
readOnly: true
69+
- name: operator
70+
# Replace this with the built image name
71+
image: "{{ "{{ REPLACE_IMAGE }}" }}"
72+
imagePullPolicy: "{{ "{{ pull_policy|default('Always') }}"}}"
73+
volumeMounts:
74+
- mountPath: /tmp/ansible-operator/runner
75+
name: runner
6176
env:
6277
- name: WATCH_NAMESPACE
6378
{{- if .IsClusterScoped }}
@@ -73,4 +88,7 @@ spec:
7388
fieldPath: metadata.name
7489
- name: OPERATOR_NAME
7590
value: "{{.ProjectName}}"
91+
volumes:
92+
- name: runner
93+
emptyDir: {}
7694
`

pkg/scaffold/ansible/dockerfilehybrid.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func (d *DockerfileHybrid) GetInput() (input.Input, error) {
4747
const dockerFileHybridAnsibleTmpl = `FROM ansible/ansible-runner
4848
4949
RUN yum remove -y ansible python-idna
50+
RUN yum install -y inotify-tools && yum clean all
5051
RUN pip uninstall ansible-runner -y
5152
5253
RUN pip install --upgrade setuptools

test/ansible-memcached/asserts.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,23 @@
179179
- name: get operator logs
180180
ignore_errors: yes
181181
failed_when: false
182-
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ namespace }}
182+
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ namespace }} -c operator
183183
vars:
184184
definition: "{{ lookup('file', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml }}"
185185
register: log
186186

187187
- debug: var=log.stdout_lines
188188

189+
- name: get ansible logs
190+
ignore_errors: yes
191+
failed_when: false
192+
command: kubectl logs deployment/{{ definition.metadata.name }} -n {{ namespace }} -c ansible
193+
vars:
194+
definition: "{{ lookup('file', '/'.join([deploy_dir, 'operator.yaml'])) | from_yaml }}"
195+
register: ansible_log
196+
197+
- debug: var=ansible_log.stdout_lines
198+
189199
- fail:
190200
msg: "Failed in asserts.yml"
191201

0 commit comments

Comments
 (0)