ansible / ansible-container

DEPRECATED -- Ansible Container was a tool to build Docker images and orchestrate containers using only Ansible playbooks.
GNU Lesser General Public License v3.0
2.19k stars 394 forks source link

Custom role path only works with --roles-path, not with overwriting ansible.cfg #366

Open HontoNoRoger opened 7 years ago

HontoNoRoger commented 7 years ago
ISSUE TYPE
container.yml
version: "1"
services:
  jenkins-build-test:
    image: ubuntu:xenial
    command: ['/bin/sleep', 'infinity']
  #   dev_overrides:
  #     environment:
  #       - "DEBUG=1"
  #
registries: {}
  # Add optional registries used for deployment. For example:
  #  google:
  #    url: https://gcr.io
  #    namespace: my-cool-project-xxxxxx
main.yml
# This should be your Ansible playbooks to provision your containers.
# An inventory will be automatically created using the names of the services
# from your container.yml file.
# Add any roles or other modules you'll need to this directory too.
# For many examples of roles, check out Ansible Galaxy: https://galaxy.ansible.com/
#
---
- hosts: jenkins-build-test
  gather_facts: false

  roles:
    - bundles/common
OS / ENVIRONMENT
Ansible Container, version 0.2.0
Linux, rechenknecht, 4.4.0-59-generic, #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017, x86_64
2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] /usr/bin/python
No DOCKER_HOST environment variable found. Assuming UNIX socket at /var/run/docker.sock
{u'Architecture': u'x86_64',
 u'BridgeNfIp6tables': True,
 u'BridgeNfIptables': True,
 u'CPUSet': True,
 u'CPUShares': True,
 u'CgroupDriver': u'cgroupfs',
 u'ClusterAdvertise': u'',
 u'ClusterStore': u'',
 u'ContainerdCommit': {u'Expected': u'03e5862ec0d8d3b3f750e19fca3ee367e13c090e',
                       u'ID': u'03e5862ec0d8d3b3f750e19fca3ee367e13c090e'},
 u'Containers': 28,
 u'ContainersPaused': 0,
 u'ContainersRunning': 0,
 u'ContainersStopped': 28,
 u'CpuCfsPeriod': True,
 u'CpuCfsQuota': True,
 u'Debug': False,
 u'DefaultRuntime': u'runc',
 u'DockerRootDir': u'/var/lib/docker',
 u'Driver': u'aufs',
 u'DriverStatus': [[u'Root Dir', u'/var/lib/docker/aufs'],
                   [u'Backing Filesystem', u'extfs'],
                   [u'Dirs', u'463'],
                   [u'Dirperm1 Supported', u'true']],
 u'ExperimentalBuild': False,
 u'HttpProxy': u'',
 u'HttpsProxy': u'',
 u'ID': u'47ZH:DV7R:K46H:ZAGA:6OTS:TAVW:U4XG:WETG:EHVX:Y3SH:AZDR:FPYU',
 u'IPv4Forwarding': True,
 u'Images': 58,
 u'IndexServerAddress': u'https://index.docker.io/v1/',
 u'InitBinary': u'docker-init',
 u'InitCommit': {u'Expected': u'949e6fa', u'ID': u'949e6fa'},
 u'Isolation': u'',
 u'KernelMemory': True,
 u'KernelVersion': u'4.4.0-59-generic',
 u'Labels': None,
 u'LiveRestoreEnabled': False,
 u'LoggingDriver': u'json-file',
 u'MemTotal': 16808607744,
 u'MemoryLimit': True,
 u'NCPU': 4,
 u'NEventsListener': 0,
 u'NFd': 16,
 u'NGoroutines': 24,
 u'Name': u'rechenknecht',
 u'NoProxy': u'',
 u'OSType': u'linux',
 u'OomKillDisable': True,
 u'OperatingSystem': u'Ubuntu 16.04.1 LTS',
 u'Plugins': {u'Authorization': None,
              u'Network': [u'bridge',
                           u'host',
                           u'macvlan',
                           u'null',
                           u'overlay'],
              u'Volume': [u'local']},
 u'RegistryConfig': {u'IndexConfigs': {u'docker.io': {u'Mirrors': None,
                                                      u'Name': u'docker.io',
                                                      u'Official': True,
                                                      u'Secure': True}},
                     u'InsecureRegistryCIDRs': [u'127.0.0.0/8'],
                     u'Mirrors': []},
 u'RuncCommit': {u'Expected': u'2f7393a47307a16f8cee44a37b262e8b81021e3e',
                 u'ID': u'2f7393a47307a16f8cee44a37b262e8b81021e3e'},
 u'Runtimes': {u'runc': {u'path': u'docker-runc'}},
 u'SecurityOptions': [u'name=apparmor', u'name=seccomp,profile=default'],
 u'ServerVersion': u'1.13.0',
 u'SwapLimit': False,
 u'Swarm': {u'Cluster': {u'CreatedAt': u'0001-01-01T00:00:00Z',
                         u'ID': u'',
                         u'Spec': {u'CAConfig': {},
                                   u'Dispatcher': {},
                                   u'EncryptionConfig': {u'AutoLockManagers': False},
                                   u'Orchestration': {},
                                   u'Raft': {u'ElectionTick': 0,
                                             u'HeartbeatTick': 0},
                                   u'TaskDefaults': {}},
                         u'UpdatedAt': u'0001-01-01T00:00:00Z',
                         u'Version': {}},
            u'ControlAvailable': False,
            u'Error': u'',
            u'LocalNodeState': u'inactive',
            u'Managers': 0,
            u'NodeAddr': u'',
            u'NodeID': u'',
            u'Nodes': 0,
            u'RemoteManagers': None},
 u'SystemStatus': None,
 u'SystemTime': u'2017-02-01T16:37:59.113897745+01:00'}
{u'ApiVersion': u'1.25',
 u'Arch': u'amd64',
 u'BuildTime': u'2017-01-17T09:58:26.273203038+00:00',
 u'GitCommit': u'49bf474',
 u'GoVersion': u'go1.7.3',
 u'KernelVersion': u'4.4.0-59-generic',
 u'MinAPIVersion': u'1.12',
 u'Os': u'linux',
 u'Version': u'1.13.0'}
SUMMARY

Currently, the custom role path only works with --roles-path when executing an ansible-container build command, not with overwriting the roles_path in ansible.cfg.

STEPS TO REPRODUCE
  1. use ansible-container init for general configuration.
  2. in ansible.cfg, put something like:
    [defaults]
    roles_path = /home/roger/aws/ansible/roles
  3. sudo ansible-container build
EXPECTED RESULTS

The same as with sudo ansible-container build --roles-path /home/roger/aws/ansible/roles which is:

roger@rechenknecht ~/ansible-container-test $ sudo ansible-container build --roles-path /home/roger/aws/ansible/roles
No DOCKER_HOST environment variable found. Assuming UNIX socket at /var/run/docker.sock
Starting Docker Compose engine to build your images...
Attaching to ansible_ansible-container_1
Cleaning up Ansible Container builder...
No image found for tag ansible-container-test-jenkins-build-test:latest, so building from scratch
Attaching to ansible_ansible-container_1, ansible_jenkins-build-test_1
ansible-container_1   | Host jenkins-build-test running
ansible-container_1   | 
ansible-container_1   | PLAY [jenkins-build-test] ******************************************************
ansible-container_1   | 
ansible-container_1   | TASK [base/sysctl : Deploy basic TCP/IP-tuning and security] *******************
…
ACTUAL RESULTS

Role can't be found despite having the proper path at the end of the used configuration.

roger@rechenknecht ~/ansible-container-test $ sudo ansible-container build
No DOCKER_HOST environment variable found. Assuming UNIX socket at /var/run/docker.sock
Starting Docker Compose engine to build your images...
Attaching to ansible_ansible-container_1
Cleaning up Ansible Container builder...
No image found for tag ansible-container-test-jenkins-build-test:latest, so building from scratch
Attaching to ansible_ansible-container_1, ansible_jenkins-build-test_1
ansible-container_1   | Host jenkins-build-test running
ansible-container_1   | ERROR! the role 'bundles/common' was not found in /ansible-container/ansible/roles:/ansible-container/ansible:/home/roger/aws/ansible/roles
ansible-container_1   | 
ansible-container_1   | The error appears to have been in '/ansible-container/ansible/main.yml': line 12, column 7, but may
ansible-container_1   | be elsewhere in the file depending on the exact syntax problem.
ansible-container_1   | 
ansible-container_1   | The offending line appears to be:
ansible-container_1   | 
ansible-container_1   |   roles:
ansible-container_1   |     - bundles/common
ansible-container_1   |       ^ here
ansible_ansible-container_1 exited with code 1
Aborting on container exit...
Stopping ansible_jenkins-build-test_1 ... done
Ansible playbook run failed.
Cleaning up Ansible Container builder...
Ansible build failed
chouseknecht commented 7 years ago

@HontoNoRoger

Thank your for your interest in Ansible Container! We appreciate the time you've taken to try it, and to open an issue.

I'm labeling this as a question, simply because it's not really a bug. Maybe it could become an enhancement. What I mean is that, --roles-path is the intended vehicle for enabling users to bring their own roles into the build container without copying them to ansible/roles within the project.

I believe that adding a roles_path to ansible.cfg is not working, because the specified paths need to be available inside the build container. In other words /home/roger/aws/ansible/roles, has to be made available as a volume in the build container. You could do that using --with-volumes, and specifying roles_path in ansible.cfg, but --roles-path is the shortcut.

Hopefully my explanation makes sense. If not, please let me know. Also, if you feel that this is not clear in our documentation, please share your thoughts there as well. Perhaps we need to document this better.

HontoNoRoger commented 7 years ago

@chouseknecht Oh I see, so basically Ansible Container automatically provides the roles (usually in the configuration directory) to the container and executes it locally (i.e. in the container itself, not from the outside). Without using the shortcut --roles-path or the default path in my Ansible Container configuration directory, the roles won't be available inside the container and therefore can't be found, right?

I'm still a little bit confused, reading the getting started I got the idea that Ansible Container would simply run Ansible from outside the container with a generated inventory file based on the container.yml. So I didn't see the need of actually making my roles available inside the containers.

gregdek commented 7 years ago

Changing this from "question" to "documentation" for potential docs enhancement.

brucellino commented 7 years ago

hi @chouseknecht - referring to your reply above, this doesn't work for me.

I have a directory structure which looks like this :

├── Ansible │   |── group_vars │   ├── host_vars │   ├── inventories │   └── roles ├── Containers │   ├── Ansible-Container │   ├── Docker-Compose │   └── Dockerfiles

The Ansible Container projects are in the Containers/Ansible-Container part while the roles are in Ansible/roles path.

In one of my Ansible Container projects, I want to use roles from the local filesystem, by passing --roles-path, like this :

ansible-container --engine docker --debug build --roles-path /home/becker/Ops/AAROC/DevOps/Ansible/roles/

However, that gives an error saying that the role that I want in the container.yml cannot be found

Traceback (most recent call last):
  File "/usr/bin/conductor", line 11, in <module>
    load_entry_point('ansible-container', 'console_scripts', 'conductor')()
  File "/_ansible/container/__init__.py", line 19, in __wrapped__
    return fn(*args, **kwargs)
  File "/_ansible/container/cli.py", line 341, in conductor_commandline
    conductor_config = AnsibleContainerConductorConfig(containers_config)
  File "/_ansible/container/__init__.py", line 19, in __wrapped__
    return fn(*args, **kwargs)
  File "/_ansible/container/config.py", line 222, in __init__
    self._process_services()
  File "/_ansible/container/config.py", line 285, in _process_services
    role_metadata = get_metadata_from_role(role_name)
  File "/_ansible/container/__init__.py", line 19, in __wrapped__
    return fn(*args, **kwargs)
  File "/_ansible/container/utils/__init__.py", line 257, in get_metadata_from_role
    return get_content_from_role(role_name, os.path.join('meta', 'container.yml'))
  File "/_ansible/container/__init__.py", line 19, in __wrapped__
    return fn(*args, **kwargs)
  File "/_ansible/container/utils/__init__.py", line 246, in get_content_from_role
    role_path = resolve_role_to_path(role_name)
  File "/_ansible/container/__init__.py", line 19, in __wrapped__
    return fn(*args, **kwargs)
  File "/_ansible/container/utils/__init__.py", line 198, in resolve_role_to_path
    loader=loader)
  File "/usr/lib/python2.7/site-packages/ansible/playbook/role/include.py", line 59, in load
    return ri.load_data(data, variable_manager=variable_manager, loader=loader)
  File "/usr/lib/python2.7/site-packages/ansible/playbook/base.py", line 241, in load_data
    ds = self.preprocess_data(ds)
  File "/usr/lib/python2.7/site-packages/ansible/playbook/role/definition.py", line 94, in preprocess_data
    (role_name, role_path) = self._load_role_path(role_name)
  File "/usr/lib/python2.7/site-packages/ansible/playbook/role/definition.py", line 187, in _load_role_path
    raise AnsibleError("the role '%s' was not found in %s" % (role_name, ":".join(role_search_paths)), obj=self._ds)
ansible.errors.AnsibleError: the role 'CODE-RADE-container' was not found in ./roles:/src/roles:/etc/ansible/roles:.

This role is definitely in the roles-path I asked for. What gives ?

chouseknecht commented 7 years ago

@brucellino

I assume you're using the latest Ansible Container installed via pip. If so there is a bug, and --roles-path is being ignored. See #449. This is now fixed. To get the update, you'll need to run from source.

flaub commented 7 years ago

I'd prefer that roles_path defined in ansible.cfg work if it's specified. From a users point of view, I'd like to checkin the custom path to my roles relative to wherever the ansible.cfg lives in my repository. From an implementation point of view, ansible-container could inspect ansible.cfg to see if roles_path is specified and if so, do the same behavior that is being done with --roles-path specified on the command line. I also think that if both are specified, the --roles-path from the command line would take precedence.