Pushes images to a Docker registry. Returns dict containing attributes used to push images.

def push_images(base_path, image_namespace, engine_obj, config, **kwargs):
    """ Pushes images to a Docker registry. Returns dict containing attributes used to push images. """
    config_path = kwargs.get('config_path', engine_obj.auth_config_path)
    username = kwargs.get('username')
    password = kwargs.get('password')
    push_to = kwargs.get('push_to')
    url = engine_obj.default_registry_url
    registry_name = engine_obj.default_registry_name
    namespace = image_namespace
    save_conductor = config.save_conductor
    repository_prefix = None
    pull_from_url = None

    if push_to:
        if config.get('registries', dict()).get(push_to):
            url = config['registries'][push_to].get('url')
            namespace = config['registries'][push_to].get('namespace', namespace)
            repository_prefix = config['registries'][push_to].get('repository_prefix')
            pull_from_url = config['registries'][push_to].get('pull_from_url')
            if not url:
                raise AnsibleContainerRegistryAttributeException(
                    u"Registry {} missing required attribute 'url'".format(push_to)
                )
        else:
            url, namespace = resolve_push_to(push_to, engine_obj.default_registry_url, namespace)

    if username and not password:
        # If a username was supplied without a password, prompt for it
        if url != engine_obj.default_registry_url:
            registry_name = url
        while not password:
            password = getpass.getpass(u"Enter password for {0} at {1}: ".format(username, registry_name))

    if config_path:
        # Make sure the config_path exists
        #  - gives us a chance to create the file with correct permissions, if it does not exists
        #  - makes sure we mount a path to the conductor for a specific file
        config_path = os.path.normpath(os.path.expanduser(config_path))
        if os.path.exists(config_path) and os.path.isdir(config_path):
            raise AnsibleContainerException(
                u"Expecting --config-path to be a path to a file, not a directory"
            )
        elif not os.path.exists(config_path):
            # Make sure the directory path exists
            if not os.path.exists(os.path.dirname(config_path)):
                try:
                    os.makedirs(os.path.dirname(config_path), 0o750)
                except OSError:
                    raise AnsibleContainerException(
                        u"Failed to create the requested the path {}".format(os.path.dirname(config_path))
                    )
            # Touch the file
            open(config_path, 'w').close()

    # If you ran build with --save-build-container, then you're broken without first removing
    #  the old build container.
    remove_existing_container(engine_obj, 'conductor', remove_volumes=True)

    push_params = {}
    push_params.update(kwargs)
    push_params['config_path'] = config_path
    push_params['password'] = password
    push_params['url'] = url
    push_params['namespace'] = namespace
    push_params['repository_prefix'] = repository_prefix
    push_params['pull_from_url'] = pull_from_url

    # Push
    engine_obj.await_conductor_command('push', dict(config), base_path, push_params, save_container=save_conductor)

    return {'url': url,
            'namespace': namespace,
            'repository_prefix': repository_prefix,
            'pull_from_url': pull_from_url }