Add push parameter. Let API handle registry authentication check.
This commit is contained in:
parent
4002caf60e
commit
7ffa6a43c5
1 changed files with 58 additions and 40 deletions
|
@ -32,26 +32,26 @@ description:
|
||||||
options:
|
options:
|
||||||
archive_path:
|
archive_path:
|
||||||
description:
|
description:
|
||||||
- Use with state 'present' to archive an image to a .tar file.
|
- Use with state C(presen) to archive an image to a .tar file.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
dockerfile:
|
dockerfile:
|
||||||
description:
|
description:
|
||||||
- Use with state 'present' to provide an alternate name for the Dockerfile to use when building an image.
|
- Use with state C(present) to provide an alternate name for the Dockerfile to use when building an image.
|
||||||
default: Dockerfile
|
default: Dockerfile
|
||||||
|
required: false
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- Use with absent state to un-tag and remove all images matching the specified name. Use with states 'present'
|
- Use with absent state to un-tag and remove all images matching the specified name. Use with states C(present)
|
||||||
and 'tagged' to take action even when an image already exists.
|
and C(tagged) to take action even when an image already exists.
|
||||||
default: false
|
default: false
|
||||||
|
required: false
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
http_timeout:
|
http_timeout:
|
||||||
description:
|
description:
|
||||||
- Timeout for HTTP requests during the image build operation. Provide a positive integer value for the number of
|
- Timeout for HTTP requests during the image build operation. Provide a positive integer value for the number of
|
||||||
seconds.
|
seconds.
|
||||||
default: null
|
|
||||||
required: false
|
required: false
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
name:
|
name:
|
||||||
|
@ -65,39 +65,47 @@ options:
|
||||||
Dockerfile for building an image.
|
Dockerfile for building an image.
|
||||||
aliases:
|
aliases:
|
||||||
- build_path
|
- build_path
|
||||||
default: null
|
|
||||||
required: false
|
required: false
|
||||||
pull:
|
pull:
|
||||||
description:
|
description:
|
||||||
- When building an image downloads any updates to the FROM image in Dockerfile.
|
- When building an image downloads any updates to the FROM image in Dockerfile.
|
||||||
default: true
|
default: true
|
||||||
|
required: false
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
|
push:
|
||||||
|
description:
|
||||||
|
- Push the image to the registry. Specify the registry as part of the I(name) or I(repository) parameter.
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
|
version_added: "2.2"
|
||||||
rm:
|
rm:
|
||||||
description:
|
description:
|
||||||
- Remove intermediate containers after build.
|
- Remove intermediate containers after build.
|
||||||
default: true
|
default: true
|
||||||
|
required: false
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
nocache:
|
nocache:
|
||||||
description:
|
description:
|
||||||
- Do not use cache when building an image.
|
- Do not use cache when building an image.
|
||||||
default: false
|
default: false
|
||||||
|
required: false
|
||||||
repository:
|
repository:
|
||||||
description:
|
description:
|
||||||
- Full path to a repository. Use with state 'present' to tag the image into the repository.
|
- Full path to a repository. Use with state C(present) to tag the image into the repository.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Make assertions about the state of an image.
|
- Make assertions about the state of an image.
|
||||||
- When 'absent' an image will be removed. Use the force option to un-tag and remove all images
|
- When C(absent) an image will be removed. Use the force option to un-tag and remove all images
|
||||||
matching the provided name.
|
matching the provided name.
|
||||||
- When 'present' check if an image exists using the provided name and tag. If the image is not found or the
|
- When C(present) check if an image exists using the provided name and tag. If the image is not found or the
|
||||||
force option is used, the image will either be pulled, built or loaded. By default the image will be pulled
|
force option is used, the image will either be pulled, built or loaded. By default the image will be pulled
|
||||||
from Docker Hub. To build the image, provide a path value set to a directory containing a context and
|
from Docker Hub. To build the image, provide a path value set to a directory containing a context and
|
||||||
Dockerfile. To load an image, specify load_path to provide a path to an archive file. To tag an image to a
|
Dockerfile. To load an image, specify load_path to provide a path to an archive file. To tag an image to a
|
||||||
repository, provide a repository path. If the name contains a repository path, it will be pushed.
|
repository, provide a repository path. If the name contains a repository path, it will be pushed.
|
||||||
- "NOTE: 'build' is DEPRECATED. Specifying 'build' will behave the same as 'present'."
|
- "NOTE: C(build) is DEPRECATED. Specifying C(build) will behave the same as C(present)."
|
||||||
|
required: false
|
||||||
default: present
|
default: present
|
||||||
choices:
|
choices:
|
||||||
- absent
|
- absent
|
||||||
|
@ -106,13 +114,13 @@ options:
|
||||||
tag:
|
tag:
|
||||||
description:
|
description:
|
||||||
- Used to select an image when pulling. Will be added to the image when pushing, tagging or building. Defaults to
|
- Used to select an image when pulling. Will be added to the image when pushing, tagging or building. Defaults to
|
||||||
'latest' when pulling an image.
|
C(latest).
|
||||||
default: latest
|
default: latest
|
||||||
|
required: false
|
||||||
container_limits:
|
container_limits:
|
||||||
description:
|
description:
|
||||||
- A dictionary of limits applied to each container created by the build process.
|
- A dictionary of limits applied to each container created by the build process.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
|
||||||
version_added: "2.1"
|
version_added: "2.1"
|
||||||
type: complex
|
type: complex
|
||||||
contains:
|
contains:
|
||||||
|
@ -130,17 +138,17 @@ options:
|
||||||
type: str
|
type: str
|
||||||
use_tls:
|
use_tls:
|
||||||
description:
|
description:
|
||||||
- "DEPRECATED. Whether to use tls to connect to the docker server. Set to 'no' when TLS will not be used. Set to
|
- "DEPRECATED. Whether to use tls to connect to the docker server. Set to C(no) when TLS will not be used. Set to
|
||||||
'encrypt' to use TLS. And set to 'verify' to use TLS and verify that the server's certificate is valid for the
|
C(encrypt) to use TLS. And set to C(verify) to use TLS and verify that the server's certificate is valid for the
|
||||||
server. NOTE: If you specify this option, it will set the value of the tls or tls_verify parameters."
|
server. NOTE: If you specify this option, it will set the value of the tls or tls_verify parameters."
|
||||||
choices:
|
choices:
|
||||||
- no
|
- no
|
||||||
- encrypt
|
- encrypt
|
||||||
- verify
|
- verify
|
||||||
default: no
|
default: no
|
||||||
|
required: false
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
|
|
||||||
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
|
@ -162,11 +170,19 @@ EXAMPLES = '''
|
||||||
docker_image:
|
docker_image:
|
||||||
name: pacur/centos-7
|
name: pacur/centos-7
|
||||||
|
|
||||||
- name: Tag to repository to a private registry and push it
|
- name: Tag and push to docker hub
|
||||||
docker_image:
|
docker_image:
|
||||||
name: pacur/centos-7
|
name: pacur/centos-7
|
||||||
repository: registry.ansible.com/chouseknecht/centos_images
|
repository: dcoppenhagan/myimage
|
||||||
tag: 7.0
|
tag: 7.0
|
||||||
|
push: yes
|
||||||
|
|
||||||
|
- name: Tag and push to local registry
|
||||||
|
docker_image:
|
||||||
|
name: centos
|
||||||
|
repository: localhost:5000/centos
|
||||||
|
tag: 7
|
||||||
|
push: yes
|
||||||
|
|
||||||
- name: Remove image
|
- name: Remove image
|
||||||
docker_image:
|
docker_image:
|
||||||
|
@ -186,10 +202,11 @@ EXAMPLES = '''
|
||||||
tag: v1
|
tag: v1
|
||||||
archive_path: my_sinatra.tar
|
archive_path: my_sinatra.tar
|
||||||
|
|
||||||
- name: Load image from archive and push it to a private registry
|
- name: Load image from archive and push to a private registry
|
||||||
docker_image:
|
docker_image:
|
||||||
name: registry.ansible.com/chouseknecht/sinatra
|
name: localhost:5000/myimages/sinatra
|
||||||
tag: v1
|
tag: v1
|
||||||
|
push: yes
|
||||||
load_path: my_sinatra.tar
|
load_path: my_sinatra.tar
|
||||||
push: True
|
push: True
|
||||||
'''
|
'''
|
||||||
|
@ -205,8 +222,8 @@ image:
|
||||||
from ansible.module_utils.docker_common import *
|
from ansible.module_utils.docker_common import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from docker import auth
|
from docker.auth.auth import resolve_repository_name
|
||||||
from docker import utils
|
from docker.utils.utils import parse_repository_tag
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# missing docker-py handled in docker_common
|
# missing docker-py handled in docker_common
|
||||||
pass
|
pass
|
||||||
|
@ -237,8 +254,7 @@ class ImageManager(DockerBaseClass):
|
||||||
self.state = parameters.get('state')
|
self.state = parameters.get('state')
|
||||||
self.tag = parameters.get('tag')
|
self.tag = parameters.get('tag')
|
||||||
self.http_timeout = parameters.get('http_timeout')
|
self.http_timeout = parameters.get('http_timeout')
|
||||||
self.debug = parameters.get('debug')
|
self.push = parameters.get('push')
|
||||||
self.push = False
|
|
||||||
|
|
||||||
if self.state in ['present', 'build']:
|
if self.state in ['present', 'build']:
|
||||||
self.present()
|
self.present()
|
||||||
|
@ -295,7 +311,7 @@ class ImageManager(DockerBaseClass):
|
||||||
if self.push and not self.repository:
|
if self.push and not self.repository:
|
||||||
self.push_image(self.name, self.tag)
|
self.push_image(self.name, self.tag)
|
||||||
elif self.repository:
|
elif self.repository:
|
||||||
self.tag_image(self.name, self.tag, self.repository, force=self.force)
|
self.tag_image(self.name, self.tag, self.repository, force=self.force, push=self.push)
|
||||||
|
|
||||||
def absent(self):
|
def absent(self):
|
||||||
'''
|
'''
|
||||||
|
@ -366,18 +382,13 @@ class ImageManager(DockerBaseClass):
|
||||||
|
|
||||||
repository = name
|
repository = name
|
||||||
if not tag:
|
if not tag:
|
||||||
repository, tag = utils.parse_repository_tag(name)
|
repository, tag = parse_repository_tag(name)
|
||||||
registry, repo_name = auth.resolve_repository_name(repository)
|
registry, repo_name = resolve_repository_name(repository)
|
||||||
|
|
||||||
|
self.log("push %s to %s/%s:%s" % (self.name, registry, repo_name, tag))
|
||||||
|
|
||||||
if re.search('/', repository):
|
|
||||||
if registry:
|
if registry:
|
||||||
config = auth.load_config()
|
self.results['actions'].append("Pushed image %s to %s/%s:%s" % (self.name, registry, repo_name, tag))
|
||||||
if not auth.resolve_authconfig(config, registry):
|
|
||||||
self.fail("Error: configuration for %s not found. Try logging into %s first." % (registry,
|
|
||||||
registry))
|
|
||||||
|
|
||||||
self.log("pushing image %s" % repository)
|
|
||||||
self.results['actions'].append("Pushed image %s to %s:%s" % (self.name, self.repository, self.tag))
|
|
||||||
self.results['changed'] = True
|
self.results['changed'] = True
|
||||||
if not self.check_mode:
|
if not self.check_mode:
|
||||||
status = None
|
status = None
|
||||||
|
@ -390,14 +401,19 @@ class ImageManager(DockerBaseClass):
|
||||||
status = line.get('status')
|
status = line.get('status')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
if re.search('unauthorized', str(exc)):
|
if re.search('unauthorized', str(exc)):
|
||||||
self.fail("Error pushing image %s: %s. Does the repository exist?" % (repository, str(exc)))
|
if re.search('authentication required', str(exc)):
|
||||||
|
self.fail("Error pushing image %s/%s:%s - %s. Try logging into %s first." %
|
||||||
|
(registry, repo_name, tag, str(exc), registry))
|
||||||
|
else:
|
||||||
|
self.fail("Error pushing image %s/%s:%s - %s. Does the repository exist?" %
|
||||||
|
(registry, repo_name, tag, str(exc)))
|
||||||
self.fail("Error pushing image %s: %s" % (repository, str(exc)))
|
self.fail("Error pushing image %s: %s" % (repository, str(exc)))
|
||||||
self.results['image'] = self.client.find_image(name=repository, tag=tag)
|
self.results['image'] = self.client.find_image(name=repository, tag=tag)
|
||||||
if not self.results['image']:
|
if not self.results['image']:
|
||||||
self.results['image'] = dict()
|
self.results['image'] = dict()
|
||||||
self.results['image']['push_status'] = status
|
self.results['image']['push_status'] = status
|
||||||
|
|
||||||
def tag_image(self, name, tag, repository, force=False):
|
def tag_image(self, name, tag, repository, force=False, push=False):
|
||||||
'''
|
'''
|
||||||
Tag an image into a repository.
|
Tag an image into a repository.
|
||||||
|
|
||||||
|
@ -408,7 +424,7 @@ class ImageManager(DockerBaseClass):
|
||||||
:param push: bool. push the image once it's tagged.
|
:param push: bool. push the image once it's tagged.
|
||||||
:return: None
|
:return: None
|
||||||
'''
|
'''
|
||||||
repo, repo_tag = utils.parse_repository_tag(repository)
|
repo, repo_tag = parse_repository_tag(repository)
|
||||||
image = self.client.find_image(name=repo, tag=repo_tag)
|
image = self.client.find_image(name=repo, tag=repo_tag)
|
||||||
found = 'found' if image else 'not found'
|
found = 'found' if image else 'not found'
|
||||||
self.log("image %s was %s" % (repo, found))
|
self.log("image %s was %s" % (repo, found))
|
||||||
|
@ -429,6 +445,7 @@ class ImageManager(DockerBaseClass):
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.fail("Error: failed to tag image %s - %s" % (name, str(exc)))
|
self.fail("Error: failed to tag image %s - %s" % (name, str(exc)))
|
||||||
self.results['image'] = self.client.find_image(name=repository, tag=tag)
|
self.results['image'] = self.client.find_image(name=repository, tag=tag)
|
||||||
|
if push:
|
||||||
self.push_image(repository, tag)
|
self.push_image(repository, tag)
|
||||||
|
|
||||||
def build_image(self):
|
def build_image(self):
|
||||||
|
@ -504,6 +521,7 @@ def main():
|
||||||
nocache=dict(type='str', default=False),
|
nocache=dict(type='str', default=False),
|
||||||
path=dict(type='path', aliases=['build_path']),
|
path=dict(type='path', aliases=['build_path']),
|
||||||
pull=dict(type='bool', default=True),
|
pull=dict(type='bool', default=True),
|
||||||
|
push=dict(type='bool', default=False),
|
||||||
repository=dict(type='str'),
|
repository=dict(type='str'),
|
||||||
rm=dict(type='bool', default=True),
|
rm=dict(type='bool', default=True),
|
||||||
state=dict(type='str', choices=['absent', 'present'], default='present'),
|
state=dict(type='str', choices=['absent', 'present'], default='present'),
|
||||||
|
|
Loading…
Reference in a new issue