def test_build_collection_no_galaxy_yaml(): fake_path = u'/fake/ÅÑŚÌβŁÈ/path' expected = to_native( "The collection galaxy.yml path '%s/galaxy.yml' does not exist." % fake_path) with pytest.raises(AnsibleError, match=expected): collection.build_collection(fake_path, u'output', False)
def test_build_existing_output_file(collection_input): input_dir, output_dir = collection_input existing_output_dir = os.path.join(output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') os.makedirs(existing_output_dir) expected = "The output collection artifact '%s' already exists, but is a directory - aborting" \ % to_native(existing_output_dir) with pytest.raises(AnsibleError, match=expected): collection.build_collection(to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), False)
def test_build_with_symlink_inside_collection(collection_input): input_dir, output_dir = collection_input os.makedirs(os.path.join(input_dir, 'playbooks', 'roles')) roles_link = os.path.join(input_dir, 'playbooks', 'roles', 'linked') file_link = os.path.join(input_dir, 'docs', 'README.md') roles_target = os.path.join(input_dir, 'roles', 'linked') roles_target_tasks = os.path.join(roles_target, 'tasks') os.makedirs(roles_target_tasks) with open(os.path.join(roles_target_tasks, 'main.yml'), 'w+') as tasks_main: tasks_main.write("---\n- hosts: localhost\n tasks:\n - ping:") tasks_main.flush() os.symlink(roles_target, roles_link) os.symlink(os.path.join(input_dir, 'README.md'), file_link) collection.build_collection(input_dir, output_dir, False) output_artifact = os.path.join( output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') assert tarfile.is_tarfile(output_artifact) with tarfile.open(output_artifact, mode='r') as actual: members = actual.getmembers() linked_members = [ m for m in members if m.path.startswith('playbooks/roles/linked/tasks') ] assert len(linked_members) == 2 assert linked_members[0].name == 'playbooks/roles/linked/tasks' assert linked_members[0].isdir() assert linked_members[ 1].name == 'playbooks/roles/linked/tasks/main.yml' assert linked_members[1].isreg() linked_task = actual.extractfile(linked_members[1].name) actual_task = secure_hash_s(linked_task.read()) linked_task.close() assert actual_task == 'f4dcc52576b6c2cd8ac2832c52493881c4e54226' linked_file = [m for m in members if m.path == 'docs/README.md'] assert len(linked_file) == 1 assert linked_file[0].isreg() linked_file_obj = actual.extractfile(linked_file[0].name) actual_file = secure_hash_s(linked_file_obj.read()) linked_file_obj.close() assert actual_file == '63444bfc766154e1bc7557ef6280de20d03fcd81'
def test_build_existing_output_with_force(collection_input): input_dir, output_dir = collection_input existing_output = os.path.join(output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') with open(existing_output, 'w+') as out_file: out_file.write("random garbage") out_file.flush() collection.build_collection(to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), True) # Verify the file was replaced with an actual tar file assert tarfile.is_tarfile(existing_output)
def test_build_existing_output_without_force(collection_input): input_dir, output_dir = collection_input existing_output = os.path.join(output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') with open(existing_output, 'w+') as out_file: out_file.write("random garbage") out_file.flush() expected = "The file '%s' already exists. You can use --force to re-create the collection artifact." \ % to_native(existing_output) with pytest.raises(AnsibleError, match=expected): collection.build_collection(to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), False)
def execute_build(self): """ Build an Ansible Galaxy collection artifact that can be stored in a central repository like Ansible Galaxy. """ force = context.CLIARGS['force'] output_path = GalaxyCLI._resolve_path(context.CLIARGS['output_path']) b_output_path = to_bytes(output_path, errors='surrogate_or_strict') if not os.path.exists(b_output_path): os.makedirs(b_output_path) elif os.path.isfile(b_output_path): raise AnsibleError("- the output collection directory %s is a file - aborting" % to_native(output_path)) for collection_path in context.CLIARGS['args']: collection_path = GalaxyCLI._resolve_path(collection_path) build_collection(collection_path, output_path, force)
def execute_build(self): """ Build an Ansible Galaxy collection artifact that can be stored in a central repository like Ansible Galaxy. By default, this command builds from the current working directory. You can optionally pass in the collection input path (where the ``galaxy.yml`` file is). """ force = context.CLIARGS['force'] output_path = GalaxyCLI._resolve_path(context.CLIARGS['output_path']) b_output_path = to_bytes(output_path, errors='surrogate_or_strict') if not os.path.exists(b_output_path): os.makedirs(b_output_path) elif os.path.isfile(b_output_path): raise AnsibleError("- the output collection directory %s is a file - aborting" % to_native(output_path)) for collection_path in context.CLIARGS['args']: collection_path = GalaxyCLI._resolve_path(collection_path) build_collection(collection_path, output_path, force)
def test_build_with_symlink_inside_collection(collection_input): input_dir, output_dir = collection_input os.makedirs(os.path.join(input_dir, 'playbooks', 'roles')) roles_link = os.path.join(input_dir, 'playbooks', 'roles', 'linked') file_link = os.path.join(input_dir, 'docs', 'README.md') roles_target = os.path.join(input_dir, 'roles', 'linked') roles_target_tasks = os.path.join(roles_target, 'tasks') os.makedirs(roles_target_tasks) with open(os.path.join(roles_target_tasks, 'main.yml'), 'w+') as tasks_main: tasks_main.write("---\n- hosts: localhost\n tasks:\n - ping:") tasks_main.flush() os.symlink(roles_target, roles_link) os.symlink(os.path.join(input_dir, 'README.md'), file_link) collection.build_collection( to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), False) output_artifact = os.path.join( output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') assert tarfile.is_tarfile(output_artifact) with tarfile.open(output_artifact, mode='r') as actual: members = actual.getmembers() linked_folder = next(m for m in members if m.path == 'playbooks/roles/linked') assert linked_folder.type == tarfile.SYMTYPE assert linked_folder.linkname == '../../roles/linked' linked_file = next(m for m in members if m.path == 'docs/README.md') assert linked_file.type == tarfile.SYMTYPE assert linked_file.linkname == '../README.md' linked_file_obj = actual.extractfile(linked_file.name) actual_file = secure_hash_s(linked_file_obj.read()) linked_file_obj.close() assert actual_file == '63444bfc766154e1bc7557ef6280de20d03fcd81'
def test_build_with_existing_files_and_manifest(collection_input): input_dir, output_dir = collection_input with open(os.path.join(input_dir, 'MANIFEST.json'), "wb") as fd: fd.write(b'{"collection_info": {"version": "6.6.6"}, "version": 1}') with open(os.path.join(input_dir, 'FILES.json'), "wb") as fd: fd.write(b'{"files": [], "format": 1}') with open(os.path.join(input_dir, "plugins", "MANIFEST.json"), "wb") as fd: fd.write(b"test data that should be in build") collection.build_collection( to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), False) output_artifact = os.path.join( output_dir, 'ansible_namespace-collection-0.1.0.tar.gz') assert tarfile.is_tarfile(output_artifact) with tarfile.open(output_artifact, mode='r') as actual: members = actual.getmembers() manifest_file = next(m for m in members if m.path == "MANIFEST.json") manifest_file_obj = actual.extractfile(manifest_file.name) manifest_file_text = manifest_file_obj.read() manifest_file_obj.close() assert manifest_file_text != b'{"collection_info": {"version": "6.6.6"}, "version": 1}' json_file = next(m for m in members if m.path == "MANIFEST.json") json_file_obj = actual.extractfile(json_file.name) json_file_text = json_file_obj.read() json_file_obj.close() assert json_file_text != b'{"files": [], "format": 1}' sub_manifest_file = next(m for m in members if m.path == "plugins/MANIFEST.json") sub_manifest_file_obj = actual.extractfile(sub_manifest_file.name) sub_manifest_file_text = sub_manifest_file_obj.read() sub_manifest_file_obj.close() assert sub_manifest_file_text == b"test data that should be in build"