<s> """<STR_LIT>""" <EOL> import os <EOL> import shutil <EOL> import logging <EOL> import tempfile <EOL> import json <EOL> import docker <EOL> from docker . errors import APIError <EOL> from atomic_reactor . constants import CONTAINER_SHARE_PATH , CONTAINER_SHARE_SOURCE_SUBDIR , BUILD_JSON , DOCKER_SOCKET_PATH <EOL> from atomic_reactor . source import get_source_instance_for <EOL> from atomic_reactor . util import ImageName , wait_for_command , clone_git_repo , figure_out_dockerfile <EOL> logger = logging . getLogger ( __name__ ) <EOL> class LastLogger ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . _last_logs = [ ] <EOL> @ property <EOL> def last_logs ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _last_logs <EOL> @ last_logs . setter <EOL> def last_logs ( self , value ) : <EOL> self . _last_logs = value <EOL> class BuildContainerFactory ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . tasker = DockerTasker ( ) <EOL> def _check_build_input ( self , image , args_path ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> with open ( os . path . join ( args_path , BUILD_JSON ) ) as json_args : <EOL> logger . debug ( "<STR_LIT>" , image , json_args . read ( ) ) <EOL> except ( IOError , OSError ) as ex : <EOL> logger . error ( "<STR_LIT>" , ex ) <EOL> raise RuntimeError ( "<STR_LIT>" % ex ) <EOL> if not self . tasker . image_exists ( image ) : <EOL> logger . error ( "<STR_LIT>" , image ) <EOL> raise RuntimeError ( "<STR_LIT>" % image ) <EOL> def _obtain_source_from_path_if_needed ( self , local_path , container_path = CONTAINER_SHARE_PATH ) : <EOL> build_json_path = os . path . join ( local_path , BUILD_JSON ) <EOL> with open ( build_json_path , '<STR_LIT:r>' ) as fp : <EOL> build_json = json . load ( fp ) <EOL> source = get_source_instance_for ( build_json [ '<STR_LIT:source>' ] , tmpdir = local_path ) <EOL> if source . provider == '<STR_LIT:path>' : <EOL> logger . debug ( '<STR_LIT>' , source . schemeless_path , local_path ) <EOL> source . get ( ) <EOL> logger . debug ( '<STR_LIT>' , local_path , os . path . exists ( local_path ) ) <EOL> build_json [ '<STR_LIT:source>' ] [ '<STR_LIT>' ] = '<STR_LIT>' + os . path . join ( container_path , CONTAINER_SHARE_SOURCE_SUBDIR ) <EOL> with open ( build_json_path , '<STR_LIT:w>' ) as fp : <EOL> json . dump ( build_json , fp ) <EOL> @ staticmethod <EOL> def _volume_bind_understands_mode ( ) : <EOL> bind = docker . utils . convert_volume_binds ( { '<STR_LIT>' : { '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : '<STR_LIT>' } } ) <EOL> if bind and len ( bind [ <NUM_LIT:0> ] . split ( '<STR_LIT::>' ) ) > <NUM_LIT:2> and bind [ <NUM_LIT:0> ] . split ( '<STR_LIT::>' ) [ <NUM_LIT:2> ] == '<STR_LIT>' : <EOL> return True <EOL> return False <EOL> def build_image_dockerhost ( self , build_image , json_args_path ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , build_image ) <EOL> self . _check_build_input ( build_image , json_args_path ) <EOL> self . _obtain_source_from_path_if_needed ( json_args_path , CONTAINER_SHARE_PATH ) <EOL> if not os . path . exists ( DOCKER_SOCKET_PATH ) : <EOL> logger . error ( "<STR_LIT>" , DOCKER_SOCKET_PATH ) <EOL> raise RuntimeError ( "<STR_LIT>" % DOCKER_SOCKET_PATH ) <EOL> volume_bindings = { <EOL> DOCKER_SOCKET_PATH : { <EOL> '<STR_LIT>' : DOCKER_SOCKET_PATH , <EOL> } , <EOL> json_args_path : { <EOL> '<STR_LIT>' : CONTAINER_SHARE_PATH , <EOL> } , <EOL> } <EOL> if self . _volume_bind_understands_mode ( ) : <EOL> volume_bindings [ DOCKER_SOCKET_PATH ] [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> volume_bindings [ json_args_path ] [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> else : <EOL> volume_bindings [ DOCKER_SOCKET_PATH ] [ '<STR_LIT>' ] = True <EOL> volume_bindings [ json_args_path ] [ '<STR_LIT>' ] = True <EOL> logger . debug ( '<STR_LIT>' , <EOL> open ( os . path . join ( json_args_path , BUILD_JSON ) ) . read ( ) ) <EOL> container_id = self . tasker . run ( <EOL> ImageName . parse ( build_image ) , <EOL> create_kwargs = { '<STR_LIT>' : [ DOCKER_SOCKET_PATH , json_args_path ] } , <EOL> start_kwargs = { '<STR_LIT>' : volume_bindings , <EOL> '<STR_LIT>' : True } <EOL> ) <EOL> return container_id <EOL> def build_image_privileged_container ( self , build_image , json_args_path ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , build_image ) <EOL> self . _check_build_input ( build_image , json_args_path ) <EOL> self . _obtain_source_from_path_if_needed ( json_args_path , CONTAINER_SHARE_PATH ) <EOL> volume_bindings = { <EOL> json_args_path : { <EOL> '<STR_LIT>' : CONTAINER_SHARE_PATH , <EOL> } , <EOL> } <EOL> if self . _volume_bind_understands_mode ( ) : <EOL> volume_bindings [ json_args_path ] [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> else : <EOL> volume_bindings [ json_args_path ] [ '<STR_LIT>' ] = True <EOL> logger . debug ( '<STR_LIT>' , <EOL> open ( os . path . join ( json_args_path , BUILD_JSON ) ) . read ( ) ) <EOL> container_id = self . tasker . run ( <EOL> ImageName . parse ( build_image ) , <EOL> create_kwargs = { '<STR_LIT>' : [ json_args_path ] } , <EOL> start_kwargs = { '<STR_LIT>' : volume_bindings , <EOL> '<STR_LIT>' : True } <EOL> ) <EOL> return container_id <EOL> class DockerTasker ( LastLogger ) : <EOL> def __init__ ( self , base_url = None , timeout = <NUM_LIT> , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( DockerTasker , self ) . __init__ ( ** kwargs ) <EOL> client_kwargs = { } <EOL> if base_url : <EOL> client_kwargs [ '<STR_LIT>' ] = base_url <EOL> elif os . environ . get ( '<STR_LIT>' ) : <EOL> client_kwargs [ '<STR_LIT>' ] = os . environ [ '<STR_LIT>' ] <EOL> if hasattr ( docker , '<STR_LIT>' ) : <EOL> client_kwargs [ '<STR_LIT:version>' ] = '<STR_LIT>' <EOL> self . d = docker . Client ( timeout = timeout , ** client_kwargs ) <EOL> def build_image_from_path ( self , path , image , stream = False , use_cache = False , remove_im = True ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image , path ) <EOL> try : <EOL> response = self . d . build ( path = path , tag = image . to_str ( ) , stream = stream , nocache = not use_cache , <EOL> rm = remove_im , pull = False ) <EOL> except TypeError : <EOL> response = self . d . build ( path = path , tag = image . to_str ( ) , stream = stream , nocache = not use_cache , <EOL> rm = remove_im ) <EOL> return response <EOL> def build_image_from_git ( self , url , image , git_path = None , git_commit = None , copy_dockerfile_to = None , <EOL> stream = False , use_cache = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , <EOL> image , git_path , url ) <EOL> logger . info ( "<STR_LIT>" , copy_dockerfile_to ) <EOL> temp_dir = tempfile . mkdtemp ( ) <EOL> response = None <EOL> try : <EOL> clone_git_repo ( url , temp_dir , git_commit ) <EOL> df_path , df_dir = figure_out_dockerfile ( temp_dir , git_path ) <EOL> if copy_dockerfile_to : <EOL> shutil . copyfile ( df_path , copy_dockerfile_to ) <EOL> response = self . build_image_from_path ( df_dir , image , stream = stream , use_cache = use_cache ) <EOL> finally : <EOL> try : <EOL> shutil . rmtree ( temp_dir ) <EOL> except ( IOError , OSError ) as ex : <EOL> logger . warning ( "<STR_LIT>" , temp_dir , ex ) <EOL> logger . info ( "<STR_LIT>" ) <EOL> return response <EOL> def run ( self , image , command = None , create_kwargs = None , start_kwargs = None ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image ) <EOL> create_kwargs = create_kwargs or { } <EOL> start_kwargs = start_kwargs or { } <EOL> logger . debug ( "<STR_LIT>" , <EOL> image , command , create_kwargs , start_kwargs ) <EOL> if isinstance ( image , ImageName ) : <EOL> image = image . to_str ( ) <EOL> container_dict = self . d . create_container ( image , command = command , ** create_kwargs ) <EOL> container_id = container_dict [ '<STR_LIT>' ] <EOL> logger . debug ( "<STR_LIT>" , container_id ) <EOL> self . d . start ( container_id , ** start_kwargs ) <EOL> return container_id <EOL> def commit_container ( self , container_id , image = None , message = None ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , container_id ) <EOL> logger . debug ( "<STR_LIT>" , <EOL> container_id , image , message ) <EOL> tag = None <EOL> if image : <EOL> tag = image . tag <EOL> image = image . to_str ( tag = False ) <EOL> response = self . d . commit ( container_id , repository = image , tag = tag , message = message ) <EOL> logger . debug ( "<STR_LIT>" , response ) <EOL> try : <EOL> return response [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> logger . error ( "<STR_LIT>" ) <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> def get_image_info_by_image_id ( self , image_id ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image_id ) <EOL> logger . debug ( "<STR_LIT>" , image_id ) <EOL> images = self . d . images ( ) <EOL> try : <EOL> image_dict = [ i for i in images if i [ '<STR_LIT>' ] == image_id ] [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> logger . info ( "<STR_LIT>" ) <EOL> return None <EOL> else : <EOL> return image_dict <EOL> def get_image_info_by_image_name ( self , image , exact_tag = True ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image ) <EOL> logger . debug ( "<STR_LIT>" , image ) <EOL> images = self . d . images ( name = image . to_str ( tag = False ) ) <EOL> if exact_tag : <EOL> for found_image in images : <EOL> if image . to_str ( explicit_tag = True ) in found_image [ '<STR_LIT>' ] : <EOL> logger . debug ( "<STR_LIT>" , image ) <EOL> return [ found_image ] <EOL> images = [ ] <EOL> logger . debug ( "<STR_LIT>" , len ( images ) ) <EOL> return images <EOL> def pull_image ( self , image , insecure = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image ) <EOL> logger . debug ( "<STR_LIT>" , image , insecure ) <EOL> try : <EOL> logs_gen = self . d . pull ( image . to_str ( tag = False ) , tag = image . tag , insecure_registry = insecure , stream = True ) <EOL> except TypeError : <EOL> logs_gen = self . d . pull ( image . to_str ( tag = False ) , tag = image . tag , stream = True ) <EOL> command_result = wait_for_command ( logs_gen ) <EOL> self . last_logs = command_result . logs <EOL> return image . to_str ( ) <EOL> def tag_image ( self , image , target_image , force = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image , target_image ) <EOL> logger . debug ( "<STR_LIT>" , image , target_image ) <EOL> if not isinstance ( image , ImageName ) : <EOL> image = ImageName . parse ( image ) <EOL> if image != target_image : <EOL> response = self . d . tag ( <EOL> image . to_str ( ) , <EOL> target_image . to_str ( tag = False ) , <EOL> tag = target_image . tag , <EOL> force = force ) <EOL> if not response : <EOL> logger . error ( "<STR_LIT>" ) <EOL> raise RuntimeError ( "<STR_LIT>" % <EOL> image . to_str ( ) , target_image ) <EOL> else : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> return target_image . to_str ( ) <EOL> def push_image ( self , image , insecure = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image ) <EOL> logger . debug ( "<STR_LIT>" , image , insecure ) <EOL> try : <EOL> logs = self . d . push ( image . to_str ( tag = False ) , tag = image . tag , insecure_registry = insecure , stream = True ) <EOL> except TypeError : <EOL> logs = self . d . push ( image . to_str ( tag = False ) , tag = image . tag , stream = True ) <EOL> command_result = wait_for_command ( logs ) <EOL> self . last_logs = command_result . logs <EOL> if command_result . is_failed ( ) : <EOL> raise RuntimeError ( "<STR_LIT>" % image ) <EOL> return command_result . parsed_logs <EOL> def tag_and_push_image ( self , image , target_image , insecure = False , force = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image , target_image ) <EOL> logger . debug ( "<STR_LIT>" , image , target_image ) <EOL> self . tag_image ( image , target_image , force = force ) <EOL> return self . push_image ( target_image , insecure = insecure ) <EOL> def inspect_image ( self , image_id ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image_id ) <EOL> logger . debug ( "<STR_LIT>" , image_id ) <EOL> if isinstance ( image_id , ImageName ) : <EOL> image_id = image_id . to_str ( ) <EOL> image_metadata = self . d . inspect_image ( image_id ) <EOL> return image_metadata <EOL> def remove_image ( self , image_id , force = False , noprune = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image_id ) <EOL> logger . debug ( "<STR_LIT>" , image_id ) <EOL> if isinstance ( image_id , ImageName ) : <EOL> image_id = image_id . to_str ( ) <EOL> self . d . remove_image ( image_id , force = force , noprune = noprune ) <EOL> def remove_container ( self , container_id , force = False ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , container_id ) <EOL> logger . debug ( "<STR_LIT>" , container_id ) <EOL> self . d . remove_container ( container_id , force = force ) <EOL> def logs ( self , container_id , stderr = True , stream = True ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , container_id ) <EOL> logger . debug ( "<STR_LIT>" , container_id , stream ) <EOL> response = self . d . logs ( container_id , stdout = True , stderr = stderr , stream = stream ) <EOL> if not stream : <EOL> response = response . decode ( "<STR_LIT:utf-8>" ) <EOL> response = [ line for line in response . split ( '<STR_LIT:\n>' ) if line ] <EOL> return response <EOL> def wait ( self , container_id ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , container_id ) <EOL> logger . debug ( "<STR_LIT>" , container_id ) <EOL> response = self . d . wait ( container_id ) <EOL> logger . debug ( "<STR_LIT>" , response ) <EOL> return response <EOL> def image_exists ( self , image_id ) : <EOL> """<STR_LIT>""" <EOL> logger . info ( "<STR_LIT>" , image_id ) <EOL> logger . debug ( "<STR_LIT>" , image_id ) <EOL> try : <EOL> response = self . d . inspect_image ( image_id ) <EOL> except APIError as ex : <EOL> logger . warning ( repr ( ex ) ) <EOL> response = False <EOL> else : <EOL> response = response is not None <EOL> logger . debug ( "<STR_LIT>" , response ) <EOL> return response <EOL> def get_info ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . d . info ( ) <EOL> def get_version ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . d . version ( ) </s>
