Class: Decking::Container

Inherits:
Object
  • Object
show all
Extended by:
Helpers, Enumerable
Includes:
Helpers
Defined in:
lib/decking/containers.rb,
lib/decking/container/stop.rb,
lib/decking/container/start.rb,
lib/decking/container/attach.rb,
lib/decking/container/create.rb,
lib/decking/container/delete.rb

Constant Summary collapse

@@logger =
Log4r::Logger.new('decking::container::attach')

Constants included from Helpers

Helpers::CONSOLE_LENGTH

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers

clear_progressline, run_with_progress, run_with_threads_multiplexed

Constructor Details

#initialize(name, params) ⇒ Container

Returns a new instance of Container.



58
59
60
61
# File 'lib/decking/containers.rb', line 58

def initialize name, params
  @name   = name
  @config = params
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/decking/containers.rb', line 63

def method_missing method, *args, &block
  if config.key? method
    config[method]
  else
    super
  end
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



56
57
58
# File 'lib/decking/containers.rb', line 56

def config
  @config
end

#containerObject (readonly)

Returns the value of attribute container.



56
57
58
# File 'lib/decking/containers.rb', line 56

def container
  @container
end

#nameObject (readonly)

Returns the value of attribute name.



56
57
58
# File 'lib/decking/containers.rb', line 56

def name
  @name
end

Class Method Details

.[](name) ⇒ Object



47
48
49
# File 'lib/decking/containers.rb', line 47

def [](name)
  instances[name] ||= new(name, @containers[name])
end

.add(params) ⇒ Object



42
43
44
45
# File 'lib/decking/containers.rb', line 42

def add params
  containers.update params.name => params
  self[params.name]
end

.attach_allObject



26
27
28
# File 'lib/decking/containers.rb', line 26

def attach_all 
  run_with_threads_multiplexed :attach, instances
end

.containersObject



34
35
36
# File 'lib/decking/containers.rb', line 34

def containers
  @containers ||= Hash.new
end

.create_allObject



18
# File 'lib/decking/containers.rb', line 18

def create_all ; map{|n, c| c.create  }; end

.create_all!Object



19
# File 'lib/decking/containers.rb', line 19

def create_all!; map{|n, c| c.create! }; end

.delete_allObject



15
# File 'lib/decking/containers.rb', line 15

def delete_all ; map{|n, c| c.delete  }; end

.delete_all!Object



16
# File 'lib/decking/containers.rb', line 16

def delete_all!; map{|n, c| c.delete! }; end

.each(&block) ⇒ Object



51
52
53
# File 'lib/decking/containers.rb', line 51

def each &block
  @instances.each(&block)
end

.instancesObject



38
39
40
# File 'lib/decking/containers.rb', line 38

def instances
  @instances ||= Hash.new
end

.start_allObject



21
# File 'lib/decking/containers.rb', line 21

def start_all  ; map{|n, c| c.start   }; end

.stop_allObject



23
# File 'lib/decking/containers.rb', line 23

def stop_all   ; map{|n, c| c.stop    }; end

.stop_all!Object



24
# File 'lib/decking/containers.rb', line 24

def stop_all!  ; map{|n, c| c.stop!   }; end

.tail_all_logs(*args) ⇒ Object



30
31
32
# File 'lib/decking/containers.rb', line 30

def tail_all_logs *args
  run_with_threads_multiplexed :tail_logs, instances, *args
end

Instance Method Details

#create(force = false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
# File 'lib/decking/container/create.rb', line 3

def create force = false
  run_with_progress("#{"Forcefully " if force}Creating #{name}") do
    begin
      exposed_ports = Hash.new
      port.each do |val|
        vars = val.split(':')
        if vars.size == 3
          exposed_ports[vars[-2]] = Hash.new
        else
          exposed_ports[vars[-1]] = Hash.new
        end
      end
      @container = Docker::Container.create 'name'         => name,
                                            'Image'        => image,
                                            'Hostname'     => hostname,
                                            'Domainname'   => domainname,
                                            'Entrypoint'   => entrypoint,
                                            'Memory'       => memory,
                                            'MemorySwap'   => memory_swap,
                                            'CpuShares'    => cpu_shares,
                                            'Cpuset'       => cpu_set,
                                            'AttachStdout' => attach_stdout,
                                            'AttachStderr' => attach_stderr,
                                            'AttachStdin'  => attach_stdin,
                                            'Tty'          => tty,
                                            'OpenStdin'    => open_stdin,
                                            'StdinOnce'    => stdin_once,
                                            'Cmd'          => command.scan(/(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^'" ])+/).map{|val| val.gsub(/^['"]/,"").gsub(/['"]$/,"")},
                                            'Env'          => env.map { |k, v| "#{k}=#{v}" },
                                            'ExposedPorts' => exposed_ports
    rescue Docker::Error::ConflictError
      clear_progressline
      puts "Container #{name} already exists".yellow
      if force
        delete!
        retry
      else
        exit
      end
    rescue Docker::Error::NotFoundError
      clear_progressline
      puts "Image #{image} not found".yellow
      exit
    rescue Docker::Error::ServerError => e
      clear_progressline
      puts "Container #{name} encountered a ServerError".red
      puts e.message.red
      exit
    rescue Exception => e
      clear_progressline
      puts "Unhandled Exception #{e.message}"
      e.backtrace.map{|msg| puts "  #{msg}"}
      exit
    end
  end
end

#create!Object



60
61
62
# File 'lib/decking/container/create.rb', line 60

def create!
  create true
end

#delete(force = false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/decking/container/delete.rb', line 3

def delete force = false
  run_with_progress("#{'Forcefully ' if force}Deleting #{name}") do
    begin
      Docker::Container.get(name).remove('force' => force)
    rescue Docker::Error::NotFoundError
      clear_progressline
      @@logger.warn "Container #{name} does not exist, nothing to delete".yellow
    rescue Docker::Error::ServerError => e
      clear_progressline
      @@logger.error e.message.red
    end
  end
end

#delete!Object



17
18
19
# File 'lib/decking/container/delete.rb', line 17

def delete!
  delete true
end

#startObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/decking/container/start.rb', line 3

def start
  run_with_progress("Starting #{name}") do
    begin
      port_bindings = Hash.new
      port.each do |val|
        vars = val.split(':')
        case vars.size
        when 3
          port_bindings[vars[-1]] = [ { 'HostIp' => vars[0], 'HostPort' => vars[1] } ]
        when 2
          port_bindings[vars[-1]] = [ { 'HostIp' => '',      'HostPort' => vars[0] } ]
        else
          port_bindings[vars[0]]  = [ { 'HostPort' => vars[0] } ]
        end
      end

      start_links = Array.new
      if links.is_a? Array
        links.each do |val|
          start_links << val.dep + ':' + val.alias
        end
      end

      Docker::Container.get(name).start! 'Links'        => start_links,
                                         'Binds'        => binds,
                                         'LxcConf'      => lxc_conf,
                                         'PortBindings' => port_bindings
    rescue Docker::Error::NotFoundError
      clear_progressline
      puts "Container #{name} not found".red
      exit
    rescue Docker::Error::ServerError => e
      clear_progressline
      puts "Container #{name} encountered a ServerError".red
      puts e.message.red
      exit
    rescue Exception => e
      clear_progressline
      puts "Unhandled Exception #{e.message}"
      e.backtrace.map{|msg| puts "  #{msg}"}
      exit
    end
  end
end

#stop(time_to_kill = 30) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/decking/container/stop.rb', line 4

def stop time_to_kill = 30
  run_with_progress("Stopping #{name}") do
    begin
      Docker::Container.get(name).stop('t' => time_to_kill)
    rescue Docker::Error::NotFoundError
      clear_progressline
      puts "Container #{name} does not exist, nothing to stop".yellow
    rescue Docker::Error::ServerError => e
      clear_progressline
      puts "Container #{name} encountered a ServerError".red
      puts e.message.red
      exit
    end
  end
end

#stop!Object



20
21
22
# File 'lib/decking/container/stop.rb', line 20

def stop!
  stop 1      
end

#tail_logs(timestamps = false, lines = 0, follow = true) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/decking/container/attach.rb', line 4

def tail_logs timestamps = false, lines = 0, follow = true
  @@logger.info "Grabbing logs from #{name}... stop with ^C".yellow
  begin
    Docker::Container.get(name).streaming_logs(follow: follow, stdout: true, stderr: true, tail: lines, timestamps: timestamps) do |stream, chunk|
      case stream
        when :stdout
          $stdout.print "(#{name}) #{chunk}"
          $stdout.flush
        when :stderr
          $stdout.print "(#{name}) #{chunk}".red
          $stdout.flush
      end
    end
  rescue Docker::Error::NotFoundError
    @@logger.error "Container #{name} does not exist"
  end
end