Class: Jarl::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/jarl/application.rb

Defined Under Namespace

Classes: Instance

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group, name, params, base_path) ⇒ Application

Create Application object from application definition:

app_name:

image: blabla
volumes:
  - /host/path:/container/path
ports:
  - 1234:5678
command: blabla


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
59
60
61
62
# File 'lib/jarl/application.rb', line 17

def initialize(group, name, params, base_path)
  @group = group
  @name = name
  @base_path = base_path
  @image = params['image'] || fail("Application '#{self}' has no 'image' defined")
  unless @image.is_a?(String)
    fail "Application '#{self}' has invalid 'image' definition, String is expected"
  end
  @scale = params['scale'] || 1
  unless @scale.is_a?(Integer) && @scale > 0
    fail "Application '#{self}' has invalid 'scale' definition, Integer > 0 is expected"
  end
  @volumes = params['volumes'] || []
  unless @volumes.is_a?(Array)
    fail "Application '#{self}' has invalid 'volumes' definition, Array is expected"
  end
  @ports = params['ports'] || []
  unless @ports.is_a?(Array)
    fail "Application '#{self}' has invalid 'ports' definition, Array is expected"
  end
  @environment = params['environment'] || {}
  unless @environment.is_a?(Hash)
    fail "Application '#{self}' has invalid 'environment' definition, Hash is expected"
  end
  @entrypoint = params['entrypoint']
  if @entrypoint && !@entrypoint.is_a?(String)
    fail "Application '#{self}' has invalid 'entrypoint' definition, String is expected"
  end
  @command = params['command']
  if @command && !@command.is_a?(String)
    fail "Application '#{self}' has invalid 'command' definition, String is expected"
  end
  @logging = (params['logging'] || {}).map { |k, v| [k.to_sym, v] }.to_h
  unless @logging.is_a?(Hash)
    fail "Application '#{self}' has invalid 'logging' definition, Hash is expected"
  end
  @logging = @logging.map { |k, v| [k.to_sym, v] }.to_h # .symbolize_keys
  if @logging[:driver] && !@logging[:driver].is_a?(String)
    fail "Application '#{self}' has invalid 'logging:driver' definition, String is expected"
  end
  if @logging[:options] && !@logging[:options].is_a?(Hash)
    fail "Application '#{self}' has invalid 'logging:options' definition, Hash is expected"
  end
  @serial = self.class.next_serial
  @hostname = @name
end

Instance Attribute Details

#base_pathObject (readonly)

Returns the value of attribute base_path.



3
4
5
# File 'lib/jarl/application.rb', line 3

def base_path
  @base_path
end

#commandObject (readonly)

Returns the value of attribute command.



4
5
6
# File 'lib/jarl/application.rb', line 4

def command
  @command
end

#entrypointObject (readonly)

Returns the value of attribute entrypoint.



4
5
6
# File 'lib/jarl/application.rb', line 4

def entrypoint
  @entrypoint
end

#environmentObject (readonly)

Returns the value of attribute environment.



4
5
6
# File 'lib/jarl/application.rb', line 4

def environment
  @environment
end

#groupObject (readonly)

Returns the value of attribute group.



3
4
5
# File 'lib/jarl/application.rb', line 3

def group
  @group
end

#hostnameObject (readonly)

Returns the value of attribute hostname.



3
4
5
# File 'lib/jarl/application.rb', line 3

def hostname
  @hostname
end

#imageObject (readonly)

Returns the value of attribute image.



4
5
6
# File 'lib/jarl/application.rb', line 4

def image
  @image
end

#loggingObject (readonly)

Returns the value of attribute logging.



4
5
6
# File 'lib/jarl/application.rb', line 4

def logging
  @logging
end

#nameObject (readonly)

Returns the value of attribute name.



3
4
5
# File 'lib/jarl/application.rb', line 3

def name
  @name
end

#portsObject (readonly)

Returns the value of attribute ports.



4
5
6
# File 'lib/jarl/application.rb', line 4

def ports
  @ports
end

#scaleObject (readonly)

Returns the value of attribute scale.



4
5
6
# File 'lib/jarl/application.rb', line 4

def scale
  @scale
end

#serialObject (readonly)

Returns the value of attribute serial.



5
6
7
# File 'lib/jarl/application.rb', line 5

def serial
  @serial
end

#volumesObject (readonly)

Returns the value of attribute volumes.



4
5
6
# File 'lib/jarl/application.rb', line 4

def volumes
  @volumes
end

Class Method Details

.next_serialObject



163
164
165
166
167
# File 'lib/jarl/application.rb', line 163

def self.next_serial
  @current_serial ||= 0
  @current_serial += 1
  @current_serial - 1
end

Instance Method Details

#buildObject



139
140
141
# File 'lib/jarl/application.rb', line 139

def build
  Docker::Image.new(image_name, image_full_path).build!
end

#execute(execute_command, args) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/jarl/application.rb', line 121

def execute(execute_command, args)
  Docker.execute(
    name: full_name,
    hostname: hostname,
    image: image_name,
    volumes: volumes,
    ports: ports,
    environment: environment,
    command: (execute_command || command || '') + ' ' + args.join(' '),
    logging: logging
  )
end

#full_nameObject



64
65
66
# File 'lib/jarl/application.rb', line 64

def full_name
  "#{group}.#{name}"
end

#image_full_pathObject



155
156
157
# File 'lib/jarl/application.rb', line 155

def image_full_path
  image_is_a_path? ? Pathname.new(base_path).join(image).expand_path : nil
end

#image_is_a_path?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/jarl/application.rb', line 68

def image_is_a_path?
  image =~ /^[~\.\/]/
end

#image_is_a_registry_path?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/jarl/application.rb', line 72

def image_is_a_registry_path?
  image =~ /^.+:\d+\//
end

#image_nameObject



147
148
149
# File 'lib/jarl/application.rb', line 147

def image_name
  image_is_a_path? ? File.basename(image) : image
end

#image_pathObject



151
152
153
# File 'lib/jarl/application.rb', line 151

def image_path
  image_is_a_path? ? image : nil
end

#instancesObject



80
81
82
# File 'lib/jarl/application.rb', line 80

def instances
  running_instances + stopped_instances
end

#pullObject



143
144
145
# File 'lib/jarl/application.rb', line 143

def pull
  Docker::Image.new(image_name, image_full_path).pull!
end

#running?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/jarl/application.rb', line 76

def running?
  instances.any?(&:running?)
end

#running_containersObject



84
85
86
87
88
# File 'lib/jarl/application.rb', line 84

def running_containers
  @running_containers ||= Docker.containers_running.select do |c|
    c.name =~ /^#{full_name}(\.\d+)?$/
  end
end

#running_instancesObject



90
91
92
93
94
95
96
# File 'lib/jarl/application.rb', line 90

def running_instances
  @running_instances ||= running_containers.map do |c|
    n = c.name.sub(/^#{full_name}\.?/, '')
    n = n.empty? ? nil : n.to_i
    Instance.new(self, n, c)
  end
end

#ssh(command = nil) ⇒ Object



134
135
136
137
# File 'lib/jarl/application.rb', line 134

def ssh(command = nil)
  fail 'Not a running application' unless running?
  instances.first.ssh(command)
end

#startObject

Start instances of the application



112
113
114
115
116
117
118
119
# File 'lib/jarl/application.rb', line 112

def start
  instances.map(&:stop!) if running?
  if scale > 1
    scale.times { |n| Instance.start(self, n + 1) }
  else
    Instance.start(self)
  end
end

#stopped_instancesObject



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/jarl/application.rb', line 98

def stopped_instances
  return @stopped_instances if @stopped_instances
  n_range = scale == 1 ? [nil] : (1..scale).to_a
  @stopped_instances = n_range.reject do |n|
    running_instances.map(&:n).include?(n)
  end
  @stopped_instances = @stopped_instances.map do |n|
    Instance.new(self, n, nil)
  end
  @stopped_instances
end

#to_sObject



159
160
161
# File 'lib/jarl/application.rb', line 159

def to_s
  full_name
end