Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address several documented usability issues #181

Merged
merged 2 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion ansible_builder/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import sys
import yaml
import os

from . import __version__, constants

Expand All @@ -26,7 +27,10 @@ def run():
action = getattr(ab, ab.action)
try:
if action():
print(MessageColors.OKGREEN + "Complete! The build context can be found at: {0}".format(ab.build_context) + MessageColors.ENDC)
print(
MessageColors.OKGREEN + "Complete! The build context can be found at: {0}".format(
os.path.abspath(ab.build_context)
) + MessageColors.ENDC)
sys.exit(0)
except DefinitionError as e:
logger.error(e.args[0])
Expand Down Expand Up @@ -104,6 +108,14 @@ def parse_args(args=sys.argv[1:]):
', '.join(constants.build_arg_defaults.keys()))
)

p.add_argument('--output-filename',
choices=list(constants.runtime_files.values()),
default=None,
help='Name of file to write image definition to '
'(default depends on --container-runtime, {0})'.format(
' and '.join([' for '.join([v, k]) for k, v in constants.runtime_files.items()]))
)

p.add_argument('-v', '--verbosity',
dest='verbosity',
type=int,
Expand Down
8 changes: 7 additions & 1 deletion ansible_builder/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(self, action=None,
build_context=constants.default_build_context,
tag=constants.default_tag,
container_runtime=constants.default_container_runtime,
output_filename=None,
verbosity=constants.default_verbosity):
self.action = action
self.definition = UserDefinition(filename=filename)
Expand All @@ -53,6 +54,7 @@ def __init__(self, action=None,
definition=self.definition,
build_context=self.build_context,
container_runtime=self.container_runtime,
output_filename=output_filename,
tag=self.tag)
self.verbosity = verbosity

Expand Down Expand Up @@ -305,13 +307,17 @@ class Containerfile:
def __init__(self, definition,
build_context=None,
container_runtime=None,
output_filename=None,
tag=None):

self.build_context = build_context
self.build_outputs_dir = os.path.join(
build_context, constants.user_content_subfolder)
self.definition = definition
filename = constants.runtime_files[container_runtime]
if output_filename is None:
filename = constants.runtime_files[container_runtime]
else:
filename = output_filename
self.path = os.path.join(self.build_context, filename)
self.container_runtime = container_runtime
self.tag = tag
Expand Down
18 changes: 17 additions & 1 deletion ansible_builder/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from collections import deque

from .colors import MessageColors
from . import constants


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -69,7 +70,22 @@ def run_command(command, capture_output=False, allow_error=False):
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
except FileNotFoundError:
logger.error(f"You do not have {command[0]} installed, please specify a different container runtime for this command.")
msg = f"You do not have {command[0]} installed."
if command[0] in constants.runtime_files:
install_summary = ', '.join([
'{runtime}: {blurb}'.format(
runtime=runtime,
blurb={True: 'installed', False: 'not installed'}.get(bool(shutil.which(runtime)))
) for runtime in constants.runtime_files
])
msg += (
f'\nYou do not have {command[0]} installed.\n'
f'Please either install {command[0]} or specify an alternative container '
f'runtime by passing --container-runtime on the command line.\n'
f'Below are the supported container runtimes and whether '
f'or not they were found on your system.\n{install_summary}'
)
logger.error(msg)
sys.exit(1)

output = []
Expand Down
16 changes: 16 additions & 0 deletions test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ def test_ansible_config_for_galaxy(exec_env_definition_file, tmpdir):
assert f'ADD {constants.user_content_subfolder}/ansible.cfg ~/.ansible.cfg' in content


def test_use_dockerfile_with_podman(exec_env_definition_file, tmpdir):
path = exec_env_definition_file(content={'version': 1})
aee = AnsibleBuilder(
filename=path, build_context=tmpdir.mkdir('bc'),
container_runtime='podman', output_filename='Dockerfile'
)
aee.build()

assert aee.containerfile.path.endswith('Dockerfile')

with open(aee.containerfile.path) as f:
content = f.read()

assert 'FROM' in content


class TestDefinitionErrors:

def test_definition_syntax_error(self, data_dir):
Expand Down
21 changes: 21 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path

import pytest
from unittest import mock

from ansible_builder.utils import write_file, copy_file, run_command

Expand Down Expand Up @@ -84,3 +85,23 @@ def test_failed_command_with_allow_error():
allow_error=True
)
assert rc == 1, f'Failed on iteration {i}'


@pytest.mark.run_command
def test_invalid_non_docker_command(caplog):
with pytest.raises(SystemExit):
run_command(['thisisnotacommand'], capture_output=True)
record = caplog.records[-1] # final log message emitted
assert 'You do not have thisisnotacommand installed' in record.msg
assert 'container-runtime' not in record.msg


@pytest.mark.run_command
def test_invalid_docker_command(caplog):
with mock.patch('ansible_builder.utils.subprocess.Popen', side_effect=FileNotFoundError):
with mock.patch('ansible_builder.utils.shutil.which', return_value=False):
with pytest.raises(SystemExit):
run_command(['docker', 'history', 'quay.io/foo/fooooo'], capture_output=True)
record = caplog.records[-1] # final log message emitted
assert 'You do not have docker installed' in record.msg
assert 'podman: not installed, docker: not installed' in record.msg