kontena-cli 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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