kontena-cli 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5495634079f9438b5489ef1b059675ecd1b1816e
4
- data.tar.gz: 2f2d23237da702fe1dd1919a83621d004d129d9a
3
+ metadata.gz: 2c2841422fbf5d03c51d4d49abdd57bb99abb737
4
+ data.tar.gz: 619c1ef499ebd0e59ba480771631b08d7656c063
5
5
  SHA512:
6
- metadata.gz: e44eaeae82ce15d7e09cb238cca449c8d7cfcf9ce666018dc8daa89aceb5a8ddc00a5077d5dbfe81aaae71a7ccb61f4e410054bc2f59dcbe13ed94ff6eacae08
7
- data.tar.gz: 1a0ac1c623f49eb325c31d41cc108d0fabcce469848cca141b3b280827b6919f3f26a2456f4addac0ad378d74db41ed2ec47a86d67d62f5ad58018af620b95bd
6
+ metadata.gz: 12861ef60ea0076e51ec577927d3ef157d8d112ecf2649bc7bbd2cfac803ce2c2846bef9f194c9dabbc59b4a523d2370751811dfbaedb86fd67bc6e7d3110123
7
+ data.tar.gz: d2e105c2d20fbb5acac25907d2851e30d909a280282b3554906c24faad2fd4f9b1ec3311df9a89eb1f1350aebea3595846ed79975ba74009c247b28d79052330
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.9.1
@@ -80,5 +80,51 @@ module Kontena::Cli::Apps
80
80
  def dockerfile
81
81
  @dockerfile ||= File.new('Dockerfile') rescue nil
82
82
  end
83
+
84
+ def create_yml(services, file='kontena.yml')
85
+ yml = File.new(file, 'w')
86
+ yml.puts services.to_yaml
87
+ yml.close
88
+ end
89
+
90
+ def app_json
91
+ if !@app_json && File.exist?('app.json')
92
+ @app_json = JSON.parse(File.read('app.json'))
93
+ end
94
+ @app_json
95
+ end
96
+
97
+ def valid_addons(prefix=nil)
98
+ if prefix
99
+ prefix = "#{prefix}-"
100
+ end
101
+
102
+ {
103
+ 'openredis' => {
104
+ 'image' => 'redis:latest',
105
+ 'environment' => ["REDIS_URL=redis://#{prefix}openredis:6379"]
106
+ },
107
+ 'redis' => {
108
+ 'image' => 'redis:latest',
109
+ 'environment' => ["REDIS_URL=redis://#{prefix}redis:6379"]
110
+ },
111
+ 'rediscloud' => {
112
+ 'image' => 'redis:latest',
113
+ 'environment' => ["REDISCLOUD_URL=redis://#{prefix}rediscloud:6379"]
114
+ },
115
+ 'postgresql' => {
116
+ 'image' => 'postgres:latest',
117
+ 'environment' => ["DATABASE_URL=postgres://#{prefix}postgres:@postgresql:5432/postgres"]
118
+ },
119
+ 'mongolab' => {
120
+ 'image' => 'mongo:latest',
121
+ 'environment' => ["MONGOLAB_URI=#{prefix}mongolab:27017"]
122
+ },
123
+ 'memcachedcloud' => {
124
+ 'image' => 'memcached:latest',
125
+ 'environment' => ["MEMCACHEDCLOUD_SERVERS=#{prefix}memcachedcloud:11211"]
126
+ }
127
+ }
128
+ end
83
129
  end
84
130
  end
@@ -0,0 +1,46 @@
1
+ require 'yaml'
2
+ require_relative 'common'
3
+
4
+ module Kontena::Cli::Apps
5
+ class DockerComposeGenerator
6
+ include Common
7
+
8
+ attr_reader :docker_compose_file
9
+
10
+ def initialize(filename)
11
+ @docker_compose_file = filename
12
+ end
13
+
14
+ def generate(procfile, addons, env_file)
15
+ if procfile.keys.size > 0
16
+ # generate services found in Procfile
17
+ docker_compose = {}
18
+ procfile.keys.each do |service|
19
+ docker_compose[service] = {'build' => '.' }
20
+ docker_compose[service]['environment'] = ['PORT=5000'] if app_json && service == 'web' # Heroku generates PORT env variable so should we do too
21
+ docker_compose[service]['command'] = "/start #{service}" if service != 'web'
22
+ docker_compose[service]['env_file'] = env_file if env_file
23
+
24
+ # generate addon services
25
+ addons.each do |addon|
26
+ addon_service = addon.split(":")[0]
27
+ addon_service.slice!('heroku-')
28
+ if valid_addons.has_key?(addon_service)
29
+ docker_compose[service]['links'] = [] unless docker_compose[service]['links']
30
+ docker_compose[service]['links'] << "#{addon_service}:#{addon_service}"
31
+ docker_compose[service]['environment'] = [] unless docker_compose[service]['environment']
32
+ docker_compose[service]['environment'] += valid_addons[addon_service]['environment']
33
+ docker_compose[addon_service] = {'image' => valid_addons[addon_service]['image']}
34
+ end
35
+ end
36
+ end
37
+ else
38
+ # no Procfile found, create dummy web service
39
+ docker_compose = {'web' => { 'build' => '.'}}
40
+ docker_compose['web']['env_file'] = env_file if env_file
41
+ end
42
+ # create docker-compose.yml file
43
+ create_yml(docker_compose, docker_compose_file)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ require 'yaml'
2
+ require_relative 'common'
3
+
4
+ module Kontena::Cli::Apps
5
+ class DockerfileGenerator
6
+ include Common
7
+
8
+ def generate(base_image, maintainer)
9
+
10
+ dockerfile = File.new('Dockerfile', 'w')
11
+ dockerfile.puts "FROM #{base_image}"
12
+ dockerfile.puts "MAINTAINER #{maintainer}"
13
+ dockerfile.puts 'CMD ["/start", "web"]'
14
+ dockerfile.close
15
+ end
16
+ end
17
+ end
@@ -1,9 +1,15 @@
1
1
  require 'yaml'
2
2
  require 'securerandom'
3
+ require_relative 'common'
4
+ require_relative 'dockerfile_generator'
5
+ require_relative 'docker_compose_generator'
6
+ require_relative 'kontena_yml_generator'
7
+
3
8
 
4
9
  module Kontena::Cli::Apps
5
10
  class InitCommand < Clamp::Command
6
11
  include Kontena::Cli::Common
12
+ include Common
7
13
 
8
14
  option ["-f", "--file"], "FILE", "Specify a docker-compose file", attribute_name: :docker_compose_file, default: 'docker-compose.yml'
9
15
  option ["-i", "--image-name"], "IMAGE_NAME", "Specify a docker image name"
@@ -19,38 +25,40 @@ module Kontena::Cli::Apps
19
25
 
20
26
  if File.exist?('Dockerfile')
21
27
  puts 'Found Dockerfile'
22
- else
23
- create_dockerfile if create_dockerfile?
28
+ elsif create_dockerfile?
29
+ puts "Creating #{'Dockerfile'.colorize(:cyan)}"
30
+ DockerfileGenerator.new.generate(base_image, current_user['email'])
24
31
  end
25
32
 
26
- if File.exist?(docker_compose_file)
27
- puts "Found #{docker_compose_file}."
33
+ if File.exist?('Procfile')
34
+ procfile = YAML.load(File.read('Procfile'))
28
35
  else
29
- if File.exist?('Procfile')
30
- procfile = YAML.load(File.read('Procfile'))
31
- else
32
- procfile = {}
33
- end
34
-
35
- app_env = nil
36
- addons = []
36
+ procfile = {}
37
+ end
37
38
 
38
- if app_json
39
- app_env = create_env_file(app_json)
40
- addons = app_json['addons'] || []
41
- end
39
+ app_env = create_env_file(app_json)
40
+ addons = app_json['addons'] || []
42
41
 
43
- create_docker_compose_yml(procfile, addons, app_env) if create_docker_compose_yml?
42
+ if File.exist?(docker_compose_file)
43
+ puts "Found #{docker_compose_file}."
44
+ elsif create_docker_compose_yml?
45
+ puts "Creating #{docker_compose_file.colorize(:cyan)}"
46
+ docker_compose_generator = DockerComposeGenerator.new(docker_compose_file)
47
+ docker_compose_generator.generate(procfile, addons, app_env)
44
48
  end
45
49
 
46
- services = generate_kontena_services(docker_compose_file)
47
50
  if File.exist?('kontena.yml')
48
- merge_kontena_yml!(services)
49
- puts "#{'kontena.yml'.colorize(:cyan)} updated."
51
+ puts "Updating #{'kontena.yml'.colorize(:cyan)}"
50
52
  else
51
53
  puts "Creating #{'kontena.yml'.colorize(:cyan)}"
52
54
  end
53
- create_yml(services, 'kontena.yml')
55
+
56
+ kontena_yml_generator = KontenaYmlGenerator.new(image_name, service_prefix)
57
+ if File.exist?(docker_compose_file)
58
+ kontena_yml_generator.generate_from_compose_file(docker_compose_file)
59
+ else
60
+ kontena_yml_generator.generate(procfile, addons, app_env)
61
+ end
54
62
 
55
63
  puts "Your app is ready! Deploy with 'kontena app deploy'.".colorize(:green)
56
64
  end
@@ -58,13 +66,6 @@ module Kontena::Cli::Apps
58
66
 
59
67
  protected
60
68
 
61
- def app_json
62
- if !@app_json && File.exist?('app.json')
63
- @app_json = JSON.parse(File.read('app.json'))
64
- end
65
- @app_json
66
- end
67
-
68
69
  def create_dockerfile?
69
70
  ['', 'y', 'yes'].include? ask('Dockerfile not found. Do you want to create it? [Yn]: ').downcase
70
71
  end
@@ -92,130 +93,9 @@ module Kontena::Cli::Apps
92
93
  client(token).get('user') rescue ''
93
94
  end
94
95
 
95
- def create_dockerfile
96
- puts "Creating #{'Dockerfile'.colorize(:cyan)}"
97
- dockerfile = File.new('Dockerfile', 'w')
98
- dockerfile.puts "FROM #{base_image}"
99
- dockerfile.puts "MAINTAINER #{current_user['email']}"
100
- dockerfile.puts 'CMD ["/start", "web"]'
101
- dockerfile.close
102
- end
103
-
104
- def merge_kontena_yml!(services)
105
- puts "kontena.yml already exists. Merging changes."
106
- kontena_services = YAML.load(File.read('kontena.yml'))
107
- services.each do |name, options|
108
- if kontena_services[name]
109
- services[name].merge!(kontena_services[name])
110
- end
111
- end
112
- end
113
-
114
96
  def create_docker_compose_yml?
115
97
  ['', 'y', 'yes'].include? ask("#{docker_compose_file} not found. Do you want to create it? [Yn]: ").downcase
116
98
  end
117
99
 
118
- def create_docker_compose_yml(procfile, addons, env_file)
119
- puts "Creating #{docker_compose_file.colorize(:cyan)}"
120
- if procfile.keys.size > 0
121
- # generate services found in Procfile
122
- docker_compose = {}
123
- procfile.keys.each do |service|
124
- docker_compose[service] = {'build' => '.' }
125
- docker_compose[service]['environment'] = ['PORT=5000'] if app_json && service == 'web' # Heroku generates PORT env variable so should we do too
126
- docker_compose[service]['command'] = "/start #{service}" if service != 'web'
127
- docker_compose[service]['env_file'] = env_file if env_file
128
-
129
- # generate addon services
130
- addons.each do |addon|
131
- addon_service = addon.split(":")[0]
132
- addon_service.slice!('heroku-')
133
- if valid_addons.has_key?(addon_service)
134
- docker_compose[service]['links'] = [] unless docker_compose[service]['links']
135
- docker_compose[service]['links'] << "#{addon_service}:#{addon_service}"
136
- docker_compose[service]['environment'] = [] unless docker_compose[service]['environment']
137
- docker_compose[service]['environment'] += valid_addons[addon_service]['environment']
138
- docker_compose[addon_service] = {'image' => valid_addons[addon_service]['image']}
139
- end
140
- end
141
- end
142
- else
143
- # no Procfile found, create dummy web service
144
- docker_compose = {'web' => { 'build' => '.'}}
145
- docker_compose['web']['env_file'] = env_file if env_file
146
- end
147
- # create docker-compose.yml file
148
- create_yml(docker_compose, docker_compose_file)
149
- end
150
-
151
- def generate_kontena_services(docker_compose = nil)
152
- services = {}
153
- if docker_compose && File.exist?(docker_compose)
154
- # extend services from docker-compose.yml
155
- compose_services = YAML.load(File.read(docker_compose))
156
- compose_services.each do |name, options|
157
- services[name] = {'extends' => { 'file' => 'docker-compose.yml', 'service' => name }}
158
- if options.has_key?('build')
159
- image = image_name || "registry.kontena.local/#{File.basename(Dir.getwd)}:latest"
160
- services[name]['image'] = image
161
- end
162
-
163
- # we have to generate Kontena urls to env vars for Heroku addons
164
- # redis://openredis:6379 -> redis://project-name-openredis:6379
165
- if options['links']
166
- options['links'].each do |link|
167
- service_link = link.split(':').first
168
- if valid_addons.has_key?(service_link)
169
- services[name]['environment'] ||= []
170
- services[name]['environment'] += valid_addons(service_prefix)[service_link]['environment']
171
- end
172
- end
173
- end
174
- end
175
- else
176
- # no docker-compose.yml found, just create dummy service with image name
177
- services = {'web' => { 'image' => "registry.kontena.local/#{File.basename(Dir.getwd)}:latest" }}
178
- end
179
- services
180
- end
181
-
182
- def create_yml(services, file='kontena.yml')
183
- yml = File.new(file, 'w')
184
- yml.puts services.to_yaml
185
- yml.close
186
- end
187
-
188
- def valid_addons(prefix=nil)
189
- if prefix
190
- prefix = "#{prefix}-"
191
- end
192
-
193
- {
194
- 'openredis' => {
195
- 'image' => 'redis:latest',
196
- 'environment' => ["REDIS_URL=redis://#{prefix}openredis:6379"]
197
- },
198
- 'redis' => {
199
- 'image' => 'redis:latest',
200
- 'environment' => ["REDIS_URL=redis://#{prefix}redis:6379"]
201
- },
202
- 'rediscloud' => {
203
- 'image' => 'redis:latest',
204
- 'environment' => ["REDISCLOUD_URL=#{prefix}redis://rediscloud:6379"]
205
- },
206
- 'postgresql' => {
207
- 'image' => 'postgres:latest',
208
- 'environment' => ["DATABASE_URL=postgres://#{prefix}postgres:@postgresql:5432/postgres"]
209
- },
210
- 'mongolab' => {
211
- 'image' => 'mongo:latest',
212
- 'environment' => ["MONGOLAB_URI=#{prefix}mongolab:27017"]
213
- },
214
- 'memcachedcloud' => {
215
- 'image' => 'memcached:latest',
216
- 'enviroment' => ["MEMCACHEDCLOUD_SERVERS=#{prefix}memcachedcloud:11211"]
217
- }
218
- }
219
- end
220
100
  end
221
101
  end
@@ -0,0 +1,95 @@
1
+ require 'yaml'
2
+ require_relative 'common'
3
+
4
+ module Kontena::Cli::Apps
5
+ class KontenaYmlGenerator
6
+ include Common
7
+
8
+ attr_reader :image_name, :service_prefix
9
+
10
+ def initialize(image_name, service_prefix)
11
+ @image_name = image_name
12
+ @service_prefix = service_prefix
13
+ end
14
+
15
+ def generate_from_compose_file(docker_compose_file)
16
+ services = {}
17
+ # extend services from docker-compose.yml
18
+ file = File.read(docker_compose_file)
19
+ compose_services = YAML.load(file)
20
+ compose_services.each do |name, options|
21
+ services[name] = {'extends' => { 'file' => 'docker-compose.yml', 'service' => name }}
22
+ if options.has_key?('build')
23
+ image = image_name || "registry.kontena.local/#{File.basename(Dir.getwd)}:latest"
24
+ services[name]['image'] = image
25
+ end
26
+
27
+ # set Heroku addon service as stateful by default
28
+ if valid_addons.has_key?(name)
29
+ services[name]['stateful'] = true
30
+ end
31
+
32
+ # we have to generate Kontena urls to env vars for Heroku addons
33
+ # redis://openredis:6379 -> redis://project-name-openredis:6379
34
+ if options['links']
35
+ options['links'].each do |link|
36
+ service_link = link.split(':').first
37
+ if valid_addons.has_key?(service_link)
38
+ services[name]['environment'] ||= []
39
+ services[name]['environment'] += valid_addons(service_prefix)[service_link]['environment']
40
+ end
41
+ end
42
+ end
43
+ end
44
+ create_yml(services, 'kontena.yml')
45
+
46
+ end
47
+
48
+ def generate(procfile, addons, env_file)
49
+ image = image_name || "registry.kontena.local/#{File.basename(Dir.getwd)}:latest"
50
+ if procfile.keys.size > 0
51
+ # generate services found in Procfile
52
+ services = {}
53
+ procfile.keys.each do |name|
54
+ services[name] = {'image' => image}
55
+ services[name]['environment'] = ['PORT=5000'] if app_json && name == 'web' # Heroku generates PORT env variable so should we do too
56
+ services[name]['command'] = "/start #{name}" if name != 'web'
57
+ services[name]['env_file'] = env_file if env_file
58
+
59
+ # generate addon services
60
+ addons.each do |addon|
61
+ addon_service = addon.split(":")[0]
62
+ addon_service.slice!('heroku-')
63
+ if valid_addons.has_key?(addon_service)
64
+ services[name]['links'] ||= []
65
+ services[name]['links'] << "#{addon_service}:#{addon_service}"
66
+ services[name]['environment'] ||= []
67
+ services[name]['environment'] += valid_addons(service_prefix)[addon_service]['environment']
68
+ services[addon_service] = {'image' => valid_addons[addon_service]['image'], 'stateful' => true}
69
+ end
70
+ end
71
+ end
72
+ else
73
+ # no Procfile found, create dummy web service
74
+ services = {'web' => { 'image' => image}}
75
+ services['web']['env_file'] = env_file if env_file
76
+ end
77
+ # create kontena.yml file
78
+ create_yml(services, 'kontena.yml')
79
+ end
80
+
81
+ def create_yml(services, filename)
82
+ if File.exist?(filename)
83
+ kontena_services = YAML.load(File.read(filename))
84
+ services.each do |name, options|
85
+ if kontena_services[name]
86
+ services[name].merge!(kontena_services[name])
87
+ end
88
+ end
89
+ end
90
+ super(services, filename)
91
+ end
92
+
93
+
94
+ end
95
+ end
@@ -4,11 +4,12 @@ module Kontena::Cli::Master::Aws
4
4
 
5
5
  option "--access-key", "ACCESS_KEY", "AWS access key ID", required: true
6
6
  option "--secret-key", "SECRET_KEY", "AWS secret key", required: true
7
+ option "--key-pair", "KEY_PAIR", "EC2 Key Pair", required: true
8
+ option "--ssl-cert", "SSL CERT", "SSL certificate file"
7
9
  option "--region", "REGION", "EC2 Region", default: 'eu-west-1'
8
10
  option "--zone", "ZONE", "EC2 Availability Zone", default: 'a'
9
11
  option "--vpc-id", "VPC ID", "Virtual Private Cloud (VPC) ID"
10
12
  option "--subnet-id", "SUBNET ID", "VPC option to specify subnet to launch instance into"
11
- option "--key-pair", "KEY_PAIR", "EC2 Key Pair", required: true
12
13
  option "--type", "SIZE", "Instance type", default: 't2.small'
13
14
  option "--storage", "STORAGE", "Storage size (GiB)", default: '30'
14
15
  option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
@@ -23,6 +24,7 @@ module Kontena::Cli::Master::Aws
23
24
  vpc: vpc_id,
24
25
  zone: zone,
25
26
  subnet: subnet_id,
27
+ ssl_cert: ssl_cert,
26
28
  storage: storage,
27
29
  version: version,
28
30
  key_pair: key_pair,
@@ -30,4 +32,4 @@ module Kontena::Cli::Master::Aws
30
32
  )
31
33
  end
32
34
  end
33
- end
35
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kontena-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kontena, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-12 00:00:00.000000000 Z
11
+ date: 2015-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -130,8 +130,11 @@ files:
130
130
  - lib/kontena/cli/apps/build_command.rb
131
131
  - lib/kontena/cli/apps/common.rb
132
132
  - lib/kontena/cli/apps/deploy_command.rb
133
+ - lib/kontena/cli/apps/docker_compose_generator.rb
133
134
  - lib/kontena/cli/apps/docker_helper.rb
135
+ - lib/kontena/cli/apps/dockerfile_generator.rb
134
136
  - lib/kontena/cli/apps/init_command.rb
137
+ - lib/kontena/cli/apps/kontena_yml_generator.rb
135
138
  - lib/kontena/cli/apps/list_command.rb
136
139
  - lib/kontena/cli/apps/logs_command.rb
137
140
  - lib/kontena/cli/apps/remove_command.rb