@ -21,41 +21,161 @@ short_description: Manage docker images.
version_added : " 1.5 "
description :
- Build , load or pull an image , making the image available for creating containers . Also supports tagging an
image into a repository and archiving an image to a . tar file .
- Build , load or pull an image , making the image available for creating containers . Also supports tagging an
image into a repository and archiving an image to a . tar file .
- Since Ansible 2.8 , it is recommended to explicitly specify the image ' s source (C(source=build),
C ( source = load ) , C ( source = pull ) or C ( source = local ) ) . This will be required from Ansible 2.12 on .
options :
source :
description :
- " Determines where the module will try to retrieve the image from. "
- " Use C(build) to build the image from a C(Dockerfile). I(path) must
be specified when this value is used . "
- " Use C(load) to load the image from a C(.tar) file. I(load_path) must
be specified when this value is used . "
- " Use C(pull) to pull the image from a registry. "
- " Use C(local) to make sure that the image is already available on the local
docker daemon , i . e . do not try to build , pull or load the image . "
- " Before Ansible 2.12, the value of this option will be auto-detected
to be backwards compatible , but a warning will be issued if it is not
explicitly specified . From Ansible 2.12 on , auto - detection will be disabled
and this option will be made mandatory . "
type : str
choices :
- build
- load
- pull
- local
version_added : " 2.8 "
build :
description :
- " Specifies options used for building images. "
type : dict
suboptions :
cache_from :
description :
- List of image names to consider as cache source .
type : list
dockerfile :
description :
- Use with state C ( present ) to provide an alternate name for the Dockerfile to use when building an image .
type : str
http_timeout :
description :
- Timeout for HTTP requests during the image build operation . Provide a positive integer value for the number of
seconds .
type : int
path :
description :
- Use with state ' present ' to build an image . Will be the path to a directory containing the context and
Dockerfile for building an image .
type : path
required : yes
pull :
description :
- When building an image downloads any updates to the FROM image in Dockerfile .
type : bool
default : yes
rm :
description :
- Remove intermediate containers after build .
type : bool
default : yes
network :
description :
- The network to use for C ( RUN ) build instructions .
type : str
nocache :
description :
- Do not use cache when building an image .
type : bool
default : no
args :
description :
- Provide a dictionary of C ( key : value ) build arguments that map to Dockerfile ARG directive .
- Docker expects the value to be a string . For convenience any non - string values will be converted to strings .
- Requires Docker API > = 1.21 .
type : dict
container_limits :
description :
- A dictionary of limits applied to each container created by the build process .
type : dict
suboptions :
memory :
description :
- Set memory limit for build .
type : int
memswap :
description :
- Total memory ( memory + swap ) , - 1 to disable swap .
type : int
cpushares :
description :
- CPU shares ( relative weight ) .
type : int
cpusetcpus :
description :
- CPUs in which to allow execution , e . g . , " 0-3 " , " 0,1 " .
type : str
version_added : " 2.8 "
archive_path :
description :
- Use with state C ( present ) to archive an image to a . tar file .
type : path
version_added : " 2.1 "
cache_from :
description :
- List of image names to consider as cache source .
type : list
version_added : " 2.8 "
load_path :
description :
- Use with state C ( present ) to load an image from a . tar file .
- Set I ( source ) to C ( load ) if you want to load the image . The option will
be set automatically before Ansible 2.12 if this option is used ( except
if I ( path ) is specified as well , in which case building will take precedence ) .
From Ansible 2.12 on , you have to set I ( source ) to C ( load ) .
type : path
version_added : " 2.2 "
dockerfile :
description :
- Use with state C ( present ) to provide an alternate name for the Dockerfile to use when building an image .
- Please use I ( build . dockerfile ) instead . This option will be removed in Ansible 2.12 .
type : str
version_added : " 2.0 "
force :
description :
- Use with state I ( absent ) to un - tag and remove all images matching the specified name . Use with state
C ( present ) to build , load or pull an image when the image already exists .
C ( present ) to build , load or pull an image when the image already exists . Also use with state C ( present )
to force tagging an image .
- Please stop using this option , and use the more specialized force options
I ( force_source ) , I ( force_absent ) and I ( force_tag ) instead .
- This option will be removed in Ansible 2.12 .
type : bool
default : no
version_added : " 2.1 "
force_source :
description :
- Use with state C ( present ) to build , load or pull an image ( depending on the
value of the I ( source ) option ) when the image already exists .
type : bool
default : false
version_added : " 2.8 "
force_absent :
description :
- Use with state I ( absent ) to un - tag and remove all images matching the specified name .
type : bool
default : false
version_added : " 2.8 "
force_tag :
description :
- Use with state C ( present ) to force tagging an image .
- Please stop using this option , and use the more specialized force options
I ( force_source ) , I ( force_absent ) and I ( force_tag ) instead .
- This option will be removed in Ansible 2.12 .
type : bool
default : false
version_added : " 2.8 "
http_timeout :
description :
- Timeout for HTTP requests during the image build operation . Provide a positive integer value for the number of
seconds .
- Please use I ( build . http_timeout ) instead . This option will be removed in Ansible 2.12 .
type : int
version_added : " 2.1 "
name :
@ -69,12 +189,17 @@ options:
description :
- Use with state ' present ' to build an image . Will be the path to a directory containing the context and
Dockerfile for building an image .
- Set I ( source ) to C ( build ) if you want to build the image . The option will
be set automatically before Ansible 2.12 if this option is used . From Ansible 2.12
on , you have to set I ( source ) to C ( build ) .
- Please use I ( build . path ) instead . This option will be removed in Ansible 2.12 .
type : path
aliases :
- build_path
pull :
description :
- When building an image downloads any updates to the FROM image in Dockerfile .
- Please use I ( build . pull ) instead . This option will be removed in Ansible 2.12 .
type : bool
default : yes
version_added : " 2.1 "
@ -87,17 +212,14 @@ options:
rm :
description :
- Remove intermediate containers after build .
- Please use I ( build . rm ) instead . This option will be removed in Ansible 2.12 .
type : bool
default : yes
version_added : " 2.1 "
network :
description :
- The network to use for C ( RUN ) build instructions .
type : str
version_added : " 2.8 "
nocache :
description :
- Do not use cache when building an image .
- Please use I ( build . nocache ) instead . This option will be removed in Ansible 2.12 .
type : bool
default : no
repository :
@ -136,11 +258,13 @@ options:
- Provide a dictionary of C ( key : value ) build arguments that map to Dockerfile ARG directive .
- Docker expects the value to be a string . For convenience any non - string values will be converted to strings .
- Requires Docker API > = 1.21 .
- Please use I ( build . args ) instead . This option will be removed in Ansible 2.12 .
type : dict
version_added : " 2.2 "
container_limits :
description :
- A dictionary of limits applied to each container created by the build process .
- Please use I ( build . container_limits ) instead . This option will be removed in Ansible 2.12 .
type : dict
suboptions :
memory :
@ -194,26 +318,30 @@ EXAMPLES = '''
- name : pull an image
docker_image :
name : pacur / centos - 7
source : pull
- name : Tag and push to docker hub
docker_image :
name : pacur / centos - 7 : 56
repository : dcoppenhagan / myimage : 7.56
push : yes
source : local
- name : Tag and push to local registry
docker_image :
# Image will be centos:7
name : centos
# Will be pushed to localhost:5000/centos:7
repository : localhost : 5000 / centos
tag : 7
push : yes
# Image will be centos:7
name : centos
# Will be pushed to localhost:5000/centos:7
repository : localhost : 5000 / centos
tag : 7
push : yes
source : local
- name : Add tag latest to image
docker_image :
name : myimage : 7.1 .2
repository : myimage : latest
source : local
- name : Remove image
docker_image :
@ -223,16 +351,19 @@ EXAMPLES = '''
- name : Build an image and push it to a private repo
docker_image :
path : . / sinatra
build :
path : . / sinatra
name : registry . ansible . com / chouseknecht / sinatra
tag : v1
push : yes
source : build
- name : Archive image
docker_image :
name : registry . ansible . com / chouseknecht / sinatra
tag : v1
archive_path : my_sinatra . tar
source : local
- name : Load image from archive and push to a private registry
docker_image :
@ -240,23 +371,28 @@ EXAMPLES = '''
tag : v1
push : yes
load_path : my_sinatra . tar
source : load
- name : Build image and with build args
- name : Build image and with build args
docker_image :
path : / path / to / build / dir
name : myimage
buildargs :
log_volume : / var / log / myapp
listen_port : 8080
name : myimage
build :
path : / path / to / build / dir
args :
log_volume : / var / log / myapp
listen_port : 8080
source : build
- name : Build image using cache source
docker_image :
name : myimage : latest
path : / path / to / build / dir
# Use as cache source for building myimage
cache_from :
- nginx : latest
- alpine : 3.8
build :
path : / path / to / build / dir
# Use as cache source for building myimage
cache_from :
- nginx : latest
- alpine : 3.8
source : build
'''
RETURN = '''
@ -296,24 +432,28 @@ class ImageManager(DockerBaseClass):
parameters = self . client . module . params
self . check_mode = self . client . check_mode
self . source = parameters [ ' source ' ]
build = parameters [ ' build ' ] or dict ( )
self . archive_path = parameters . get ( ' archive_path ' )
self . cache_from = parameters . get ( ' cache_from ' )
self . container_limits = parameters . get ( ' container_limits ' )
self . dockerfile = parameters . get ( ' dockerfile ' )
self . force = parameters . get ( ' force ' )
self . cache_from = build . get ( ' cache_from ' )
self . container_limits = build . get ( ' container_limits ' )
self . dockerfile = build . get ( ' dockerfile ' )
self . force_source = parameters . get ( ' force_source ' )
self . force_absent = parameters . get ( ' force_absent ' )
self . force_tag = parameters . get ( ' force_tag ' )
self . load_path = parameters . get ( ' load_path ' )
self . name = parameters . get ( ' name ' )
self . network = parameters . get ( ' network ' )
self . nocache = parameters . get ( ' nocache ' )
self . path = parameters . get ( ' path ' )
self . pull = parameters . get ( ' pull ' )
self . network = build . get ( ' network ' )
self . nocache = build . get ( ' nocache ' )
self . build_path = build . get ( ' path ' )
self . pull = build . get ( ' pull ' )
self . repository = parameters . get ( ' repository ' )
self . rm = parameters . get ( ' rm ' )
self . rm = build . get ( ' rm ' )
self . state = parameters . get ( ' state ' )
self . tag = parameters . get ( ' tag ' )
self . http_timeout = parameters . get ( ' http_timeout ' )
self . http_timeout = build . get ( ' http_timeout ' )
self . push = parameters . get ( ' push ' )
self . buildargs = parameters . get ( ' build args' )
self . buildargs = build . get ( ' args' )
# If name contains a tag, it takes precedence over tag parameter.
if not is_image_name_id ( self . name ) :
@ -322,7 +462,7 @@ class ImageManager(DockerBaseClass):
self . name = repo
self . tag = repo_tag
if self . state in [ ' present ' , ' build ' ] :
if self . state == ' present ' :
self . present ( )
elif self . state == ' absent ' :
self . absent ( )
@ -339,20 +479,20 @@ class ImageManager(DockerBaseClass):
'''
image = self . client . find_image ( name = self . name , tag = self . tag )
if not image or self . force :
if self . path :
if not image or self . force _source :
if self . source == ' build ' :
# Build the image
if not os . path . isdir ( self . path) :
self . fail ( " Requested build path %s could not be found or you do not have access. " % self . path)
if not os . path . isdir ( self . build_ path) :
self . fail ( " Requested build path %s could not be found or you do not have access. " % self . build_ path)
image_name = self . name
if self . tag :
image_name = " %s : %s " % ( self . name , self . tag )
self . log ( " Building image %s " % image_name )
self . results [ ' actions ' ] . append ( " Built image %s from %s " % ( image_name , self . path) )
self . results [ ' actions ' ] . append ( " Built image %s from %s " % ( image_name , self . build_ path) )
self . results [ ' changed ' ] = True
if not self . check_mode :
self . results [ ' image ' ] = self . build_image ( )
elif self . load_path :
elif self . source == ' load ' :
# Load the image from an archive
if not os . path . isfile ( self . load_path ) :
self . fail ( " Error loading image %s . Specified path %s does not exist. " % ( self . name ,
@ -364,12 +504,18 @@ class ImageManager(DockerBaseClass):
self . results [ ' changed ' ] = True
if not self . check_mode :
self . results [ ' image ' ] = self . load_image ( )
el se:
el if self. source == ' pull ' :
# pull the image
self . results [ ' actions ' ] . append ( ' Pulled image %s : %s ' % ( self . name , self . tag ) )
self . results [ ' changed ' ] = True
if not self . check_mode :
self . results [ ' image ' ] , dummy = self . client . pull_image ( self . name , tag = self . tag )
elif self . source == ' local ' :
if image is None :
name = self . name
if self . tag :
name = " %s : %s " % ( self . name , self . tag )
self . client . fail ( ' Cannot find the image %s locally. ' % name )
if not self . check_mode and image and image [ ' Id ' ] == self . results [ ' image ' ] [ ' Id ' ] :
self . results [ ' changed ' ] = False
@ -379,7 +525,7 @@ class ImageManager(DockerBaseClass):
if self . push and not self . repository :
self . push_image ( self . name , self . tag )
elif self . repository :
self . tag_image ( self . name , self . tag , self . repository , force= self . force , push= self . push )
self . tag_image ( self . name , self . tag , self . repository , push= self . push )
def absent ( self ) :
'''
@ -397,7 +543,7 @@ class ImageManager(DockerBaseClass):
if image :
if not self . check_mode :
try :
self . client . remove_image ( name , force = self . force )
self . client . remove_image ( name , force = self . force _absent )
except Exception as exc :
self . fail ( " Error removing image %s - %s " % ( name , str ( exc ) ) )
@ -491,14 +637,13 @@ class ImageManager(DockerBaseClass):
self . results [ ' image ' ] = dict ( )
self . results [ ' image ' ] [ ' push_status ' ] = status
def tag_image ( self , name , tag , repository , force= False , push= False ) :
def tag_image ( self , name , tag , repository , push= False ) :
'''
Tag an image into a repository .
: param name : name of the image . required .
: param tag : image tag .
: param repository : path to the repository . required .
: param force : bool . force tagging , even it image already exists with the repository path .
: param push : bool . push the image once it ' s tagged.
: return : None
'''
@ -511,7 +656,7 @@ class ImageManager(DockerBaseClass):
found = ' found ' if image else ' not found '
self . log ( " image %s was %s " % ( repo , found ) )
if not image or force :
if not image or self . force _tag :
self . log ( " tagging %s : %s to %s : %s " % ( name , tag , repo , repo_tag ) )
self . results [ ' changed ' ] = True
self . results [ ' actions ' ] . append ( " Tagged image %s : %s to %s : %s " % ( name , tag , repo , repo_tag ) )
@ -541,7 +686,7 @@ class ImageManager(DockerBaseClass):
: return : image dict
'''
params = dict (
path = self . path,
path = self . build_ path,
tag = self . name ,
rm = self . rm ,
nocache = self . nocache ,
@ -614,39 +759,70 @@ class ImageManager(DockerBaseClass):
def main ( ) :
argument_spec = dict (
source = dict ( type = ' str ' , choices = [ ' build ' , ' load ' , ' pull ' , ' local ' ] ) ,
build = dict ( type = ' dict ' , suboptions = dict (
cache_from = dict ( type = ' list ' , elements = ' str ' ) ,
container_limits = dict ( type = ' dict ' , options = dict (
memory = dict ( type = ' int ' ) ,
memswap = dict ( type = ' int ' ) ,
cpushares = dict ( type = ' int ' ) ,
cpusetcpus = dict ( type = ' str ' ) ,
) ) ,
dockerfile = dict ( type = ' str ' ) ,
http_timeout = dict ( type = ' int ' ) ,
network = dict ( type = ' str ' ) ,
nocache = dict ( type = ' bool ' , default = False ) ,
path = dict ( type = ' path ' , required = True ) ,
pull = dict ( type = ' bool ' , default = True ) ,
rm = dict ( type = ' bool ' , default = True ) ,
args = dict ( type = ' dict ' ) ,
) ) ,
archive_path = dict ( type = ' path ' ) ,
cache_from = dict ( type = ' list ' , elements = ' str ' ) ,
container_limits = dict ( type = ' dict ' , options = dict (
memory = dict ( type = ' int ' ) ,
memswap = dict ( type = ' int ' ) ,
cpushares = dict ( type = ' int ' ) ,
cpusetcpus = dict ( type = ' str ' ) ,
) ) ,
dockerfile = dict ( type = ' str ' ) ,
force = dict ( type = ' bool ' , default = False ) ,
http_timeout = dict ( type = ' int ' ) ,
) , removedin_version = ' 2.12 ' ) ,
dockerfile = dict ( type = ' str ' , removedin_version = ' 2.12 ' ) ,
force = dict ( type = ' bool ' , removed_in_version = ' 2.12 ' ) ,
force_source = dict ( type = ' bool ' , default = False ) ,
force_absent = dict ( type = ' bool ' , default = False ) ,
force_tag = dict ( type = ' bool ' , default = False ) ,
http_timeout = dict ( type = ' int ' , removedin_version = ' 2.12 ' ) ,
load_path = dict ( type = ' path ' ) ,
name = dict ( type = ' str ' , required = True ) ,
network = dict ( type = ' str ' ) ,
nocache = dict ( type = ' bool ' , default = False ) ,
path = dict ( type = ' path ' , aliases = [ ' build_path ' ] ) ,
pull = dict ( type = ' bool ' , default = True ) ,
nocache = dict ( type = ' bool ' , default = False , removedin_version = ' 2.12 ' ) ,
path = dict ( type = ' path ' , aliases = [ ' build_path ' ] , removedin_version = ' 2.12 ' ) ,
pull = dict ( type = ' bool ' , default = True , removedin_version = ' 2.12 ' ) ,
push = dict ( type = ' bool ' , default = False ) ,
repository = dict ( type = ' str ' ) ,
rm = dict ( type = ' bool ' , default = True ),
rm = dict ( type = ' bool ' , default = True , removedin_version = ' 2.12 ' ),
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' absent ' , ' present ' , ' build ' ] ) ,
tag = dict ( type = ' str ' , default = ' latest ' ) ,
use_tls = dict ( type = ' str ' , choices = [ ' no ' , ' encrypt ' , ' verify ' ] , removed_in_version = ' 2.11 ' ) ,
buildargs = dict ( type = ' dict ' ),
buildargs = dict ( type = ' dict ' , removedin_version = ' 2.12 ' ),
)
option_minimal_versions = dict (
cache_from = dict ( docker_py_version = ' 2.1.0 ' , docker_api_version = ' 1.25 ' ) ,
network = dict ( docker_py_version = ' 2.4.0 ' , docker_api_version = ' 1.25 ' ) ,
)
required_if = [
# ('state', 'present', ['source']), -- enable in Ansible 2.12.
# ('source', 'build', ['build']), -- enable in Ansible 2.12.
( ' source ' , ' load ' , [ ' load_path ' ] ) ,
]
def detect_build_cache_from ( client ) :
return bool ( client . params [ ' build ' ] and client . params [ ' build ' ] [ ' cache_from ' ] is not None )
def detect_build_network ( client ) :
return bool ( client . params [ ' build ' ] and client . params [ ' build ' ] [ ' network ' ] is not None )
option_minimal_versions = dict ( )
option_minimal_versions [ " build.cache_from " ] = dict ( docker_py_version = ' 2.1.0 ' , docker_api_version = ' 1.25 ' , detect_usage = detect_build_cache_from )
option_minimal_versions [ " build.network " ] = dict ( docker_py_version = ' 2.4.0 ' , docker_api_version = ' 1.25 ' , detect_usage = detect_build_network )
client = AnsibleDockerClient (
argument_spec = argument_spec ,
required_if = required_if ,
supports_check_mode = True ,
min_docker_version = ' 1.8.0 ' ,
min_docker_api_version = ' 1.20 ' ,
@ -657,11 +833,60 @@ def main():
client . module . warn ( ' The " build " state has been deprecated for a long time '
' and will be removed in Ansible 2.11. Please use '
' " present " , which has the same meaning as " build " . ' )
client . module . params [ ' state ' ] = ' present '
if client . module . params [ ' use_tls ' ] :
client . module . warn ( ' The " use_tls " option has been deprecated for a long time '
' and will be removed in Ansible 2.11. Please use the '
' " tls " and " tls_verify " options instead. ' )
build_options = dict (
container_limits = ' container_limits ' ,
dockerfile = ' dockerfile ' ,
http_timeout = ' http_timeout ' ,
nocache = ' nocache ' ,
path = ' path ' ,
pull = ' pull ' ,
rm = ' rm ' ,
buildargs = ' args ' ,
)
for option , build_option in build_options . items ( ) :
default_value = None
if option in ( ' pull ' , ' rm ' ) :
default_value = True
elif option in ( ' nocache ' , ) :
default_value = False
if client . module . params [ option ] != default_value :
if client . module . params [ ' build ' ] is None :
client . module . params [ ' build ' ] = dict ( )
if client . module . params [ ' build ' ] . get ( build_option ) != default_value :
client . fail ( ' Cannot specify both %s and build. %s ! ' % ( option , build_option ) )
client . module . params [ ' build ' ] [ build_option ] = client . module . params [ option ]
client . module . warn ( ' Please specify build. %s instead of %s . The %s option '
' has been renamed and will be removed in Ansible 2.12. ' % ( build_option , option , option ) )
if client . module . params [ ' source ' ] == ' build ' and \
( not client . module . params [ ' build ' ] or not client . module . params [ ' build ' ] . get ( ' path ' ) ) :
client . module . fail ( ' If " source " is set to " build " , the " build.path " option must be specified. ' )
if client . module . params [ ' state ' ] == ' present ' and client . module . params [ ' source ' ] is None :
# Autodetection. To be removed in Ansible 2.12.
if ( client . module . params [ ' build ' ] or dict ( ) ) . get ( ' path ' ) :
client . module . params [ ' source ' ] = ' build '
elif client . module . params [ ' load_path ' ] :
client . module . params [ ' source ' ] = ' load '
else :
client . module . params [ ' source ' ] = ' pull '
client . module . warn ( ' The value of the " source " option was determined to be " %s " . '
' Please set the " source " option explicitly. Autodetection will '
' be removed in Ansible 2.12. ' % client . module . params [ ' source ' ] )
if client . module . params [ ' force ' ] :
client . module . params [ ' force_source ' ] = True
client . module . params [ ' force_absent ' ] = True
client . module . params [ ' force_tag ' ] = True
client . module . warn ( ' The " force " option will be removed in Ansible 2.12. Please '
' use the " force_source " , " force_absent " or " force_tag " option '
' instead, depending on what you want to force. ' )
results = dict (
changed = False ,
actions = [ ] ,