Class: Freighter::Deploy

Inherits:
Object
  • Object
show all
Defined in:
lib/freighter/deploy.rb

Defined Under Namespace

Classes: PortMap

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDeploy

Returns a new instance of Deploy.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/freighter/deploy.rb', line 9

def initialize
  @parser = Parser.new OPTIONS.config_path
  @logger = LOGGER
  @config = OPTIONS.config
  @connection_config = @config.fetch('connection')
  environments = @config.fetch('environments')
  @environment = environments.fetch(OPTIONS.environment) rescue logger.config_error("environments/#{OPTIONS.environment}")

  connection_type = @connection_config['type']
  case connection_type
  when 'ssh'
    deploy_with_ssh
  else
    logger.error "Unknown configuration option for type: #{connection_type}"
  end
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



7
8
9
# File 'lib/freighter/deploy.rb', line 7

def config
  @config
end

#loggerObject (readonly)

Returns the value of attribute logger.



7
8
9
# File 'lib/freighter/deploy.rb', line 7

def logger
  @logger
end

Instance Method Details

#deploy_with_sshObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/freighter/deploy.rb', line 26

def deploy_with_ssh
  ssh_options = @connection_config.fetch('ssh_options')
  ssh_options.extend Helpers::Hash
  ssh_options = ssh_options.symbolize_keys

  @environment.fetch('hosts').each_with_index do |host, i|
    host_name = host.fetch('host')
    @current_host_name = host_name
    images = @parser.images(host_name)

    ssh = SSH.new(host_name, ssh_options)
    local_port = 7000 + i
    # docker_api = DockerRestAPI.new("http://localhost:#{local_port}")

    ssh.tunneled_proxy(local_port) do |session|

      logger.debug msg "Connected"
      begin
        # The timeout is needed in the case that we are unable to communicate with the docker REST API
        Timeout::timeout(5) do
          setup_docker_client(local_port)
        end
      rescue Timeout::Error
        ssh.thread.exit
        logger.error msg "Could not reach the docker REST API"
      end

      
      images.each do |image|
        image_name = image['name']
        # pull image
        if OPTIONS.pull_image
          logger.info msg "Pulling image: #{image_name}" 
          pull_response = Docker::Image.create 'fromImage' => image_name
        else
          logger.info msg "Skip pull image"
          logger.error msg "Skipping is not yet implemented. Please run again without the --no-pull option"
        end

        # find existing images on the machine
        image_ids = Docker::Image.all.select do |img|
          img.info['RepoTags'].member?(image_name)
        end.map { |img| img.id[0...12] }

        logger.info msg "Existing image(s) found #{image_ids.join(', ')}"

        # determine if a the latest version of the image is currently running
        matching_containers = containers_matching_port_map(Docker::Container.all, image['containers'].map { |c| c['port_mapping'] })

        # stop previous container and start up a new container with the latest image
        stopped_containers = []
        current_running_containers = []
        matching_containers.each do |container|
          if pull_response.id =~ /^#{container.info['Image']}/
            current_running_containers << container
          else
            Docker::Container.get(container.id).stop
            stopped_containers << container
          end
        end
        if !current_running_containers.empty? and stopped_containers.empty?
          logger.info msg "Container already running with the latest image: #{pull_response.id}"
        else 
          logger.info msg "Stopped containers: #{stopped_containers.map(&:info).map(&:to_json)}"
          results = update_containers matching_containers, image
          logger.info msg "Finished:"
          logger.info msg "  started: #{results[:started]}"
          logger.info msg "  stopped: #{results[:stopped]}"
          logger.info msg "  started container ids: #{results[:container_ids_started]}"
          
          # cleanup old containers
          cleanup_old_containers
          # cleanup unused/outdated images
          cleanup_dangling_images
        end
      end
    end
  end
end