qtc-sdk 0.1.0 → 0.2.0

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: df30db23cfd3384178524f6005f02033801dd00d
4
- data.tar.gz: f8ef66175ea3afc26af7d9d3d914659d9de7942c
3
+ metadata.gz: 7e04ff804e0c81442a6ba99cc7179825b7cd24fe
4
+ data.tar.gz: d3b0706e21e291fb8cbb5656d685098bef4961c4
5
5
  SHA512:
6
- metadata.gz: f019c0a37f010d511ddc5107fc7bd655a2017a3dfd9d046cf0c9c5b579ce8852d2eb987c97b2a0cfe4c860b909a1a17fde515a34fd403cd038b6ed4f36ab20b7
7
- data.tar.gz: 851b91ada6b47e1e7a1a4ff6d4d2d39ebc1b40c65ec48500940f3ec61f58439389bd38091af6abc53acad25e7a54b5c1b0cf23f2fe064be48f5a7dab2a8c4c69
6
+ metadata.gz: 2dca7fa4e70ad77280f2ab1b1d25b0a762bcbf2dd42dee0d9aa83183486247d96e72197d0e37ff57d5e89fe1c04e40e0012a30114073307141b905135d5dd94f
7
+ data.tar.gz: 316383e9626b39b9982338812c72d01cfe7e1ed01c360069ce5e0fedf7d068f7176fb4331abd9fbe6033b99c3144a0164715957df8fdcd38de4751e834d73a55
data/Changelog.md ADDED
@@ -0,0 +1,6 @@
1
+ 0.2.0
2
+ -----------
3
+
4
+ - Add support for executing ad-hoc commands inside MAR applications: qtc-cli mar exec
5
+ - Add support for local debugging of MAR applications (using docker): qtc-cli mar local:run
6
+ - Add initial MDB commands: qtc-cli mdb list/logs
@@ -12,3 +12,4 @@ never_trace!
12
12
  require_relative 'platform/commands'
13
13
  require_relative 'eds/commands'
14
14
  require_relative 'mar/commands'
15
+ require_relative 'mdb/commands'
@@ -98,6 +98,20 @@ module Qtc
98
98
  end
99
99
  end
100
100
 
101
+ def exec(command, options)
102
+ instance_id = resolve_instance_id(options)
103
+ instance_data = instance_info(instance_id)
104
+ if instance_data
105
+ token = instance_data['authorizations'][0]['access_token']
106
+ data = {
107
+ cmd: command,
108
+ processId: options.process
109
+ }
110
+ result = client.post("/apps/#{instance_id}/exec", data, {}, {'Authorization' => "Bearer #{token}"})
111
+ puts result['stdout']
112
+ end
113
+ end
114
+
101
115
  def size_mapping
102
116
  {
103
117
  '1' => 'mini',
@@ -3,6 +3,7 @@ require_relative 'domains'
3
3
  require_relative 'ssl_certificates'
4
4
  require_relative 'env'
5
5
  require_relative 'repository'
6
+ require_relative 'debug'
6
7
 
7
8
  command 'mar list' do |c|
8
9
  c.syntax = 'qtc-cli mar list'
@@ -165,4 +166,34 @@ command 'mar repo:reset' do |c|
165
166
  c.action do |args, options|
166
167
  Qtc::Cli::Mar::Repository.new.reset(options)
167
168
  end
169
+ end
170
+
171
+ command 'mar local:run' do |c|
172
+ c.syntax = 'qtc-cli mar local:run'
173
+ c.option '--clean', String, 'Force clean build'
174
+ c.description = 'Debug mar app locally (requires docker)'
175
+ c.action do |args, options|
176
+ Qtc::Cli::Mar::Debug.new.local_debug(args, options)
177
+ end
178
+ end
179
+
180
+ command 'mar local:build_slug' do |c|
181
+ c.syntax = 'qtc-cli mar local:build_slug'
182
+ c.description = 'Build mar app slug locally (requires docker)'
183
+ c.action do |args, options|
184
+ Qtc::Cli::Mar::Debug.new.local_build(options)
185
+ end
186
+ end
187
+
188
+ command 'mar exec' do |c|
189
+ c.syntax = 'qtc-cli mar exec <cmd>'
190
+ c.description = 'Execute command inside app process'
191
+ c.option '--process PROCESS_ID', String, 'App process id'
192
+ c.option '--app APP', String, 'App instance id'
193
+ c.option '--remote REMOTE', String, 'Git remote to use, eg "staging"'
194
+ c.action do |args, options|
195
+ raise ArgumentError.new("command required") if args.size == 0
196
+ raise ArgumentError.new("--process is required") unless options.process
197
+ Qtc::Cli::Mar::Apps.new.exec(args.join(" "), options)
198
+ end
168
199
  end
@@ -0,0 +1,86 @@
1
+ require_relative 'base'
2
+ require 'open3'
3
+
4
+ module Qtc
5
+ module Cli
6
+ class Mar::Debug < Mar::Base
7
+
8
+ def local_debug(commands, options)
9
+ app_home = File.realpath('.')
10
+ docker_id = nil
11
+ puts "-----> Starting to build MAR app locally"
12
+
13
+ if options.clean == true && File.exists?("#{app_home}/slug.tgz")
14
+ File.delete("#{app_home}/slug.tgz")
15
+ end
16
+
17
+ unless File.exists?("#{app_home}/slug.tgz")
18
+ docker_id = build_slug(app_home)
19
+ else
20
+ puts " Existing slug.tgz found, build not needed."
21
+ end
22
+ puts "-----> Starting app container"
23
+ run_opts = [
24
+ '-e PORT=5000',
25
+ '-e STACK=cedar',
26
+ '-e SLUG_URL=file:///tmp/fake_slug.tgz',
27
+ '-p 5000',
28
+ "-v #{app_home}/slug.tgz:/tmp/fake_slug.tgz"
29
+ ]
30
+ if File.exists?("#{app_home}/.env")
31
+ run_opts << "--env-file=#{app_home}/.env"
32
+ end
33
+ if commands.size == 0
34
+ cmd = 'start web'
35
+ else
36
+ cmd = commands.join(" ")
37
+ end
38
+
39
+ exec("docker run -it --rm #{run_opts.join(" ")} qtcs/slugrunner #{cmd}")
40
+ end
41
+
42
+ def local_build_slug(options)
43
+ app_home = File.realpath('.')
44
+ puts "-----> Starting to build MAR app locally"
45
+ build_slug(app_home)
46
+ end
47
+
48
+ def build_slug(app_home)
49
+ docker_id = nil
50
+ run_opts = ''
51
+ if File.exists?("#{app_home}/.env")
52
+ run_opts << "--env-file=#{app_home}/.env"
53
+ end
54
+ Open3.popen3("docker run -d #{run_opts} -v #{app_home}:/tmp/gitrepo:r qtcs/slugbuilder") {|stdin, stdout, stderr, wait_thr|
55
+ docker_id = stdout.gets
56
+ if docker_id
57
+ docker_id.strip!
58
+ else
59
+ puts stderr.gets
60
+ end
61
+ exit_status = wait_thr.value
62
+ unless exit_status.success?
63
+ raise "ERROR: build failed to start"
64
+ end
65
+ }
66
+ Open3.popen3('docker', 'attach', docker_id){|stdin, stdout, stderr, wait_thr|
67
+ stdin.close
68
+ while line = stdout.gets
69
+ puts line
70
+ end
71
+ exit_status = wait_thr.value
72
+ unless exit_status.success?
73
+ raise "ERROR: build failed to complete"
74
+ end
75
+ }
76
+ puts "-----> Extracting slug from build image to ./slug.tgz"
77
+ system("docker cp #{docker_id}:/tmp/slug.tgz . > /dev/null")
78
+
79
+ docker_id
80
+ rescue => exc
81
+ system("docker rm -f #{docker_id}") if docker_id
82
+ raise exc
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../../client'
2
+ require_relative '../common'
3
+
4
+ module Qtc
5
+ module Cli
6
+ module Mdb
7
+ class Base
8
+ include Cli::Common
9
+
10
+ protected
11
+
12
+ ##
13
+ # @param [String] instance_id
14
+ # @return [String,NilClass]
15
+ def resolve_datacenter_id(instance_id)
16
+ match = instance_id.to_s.match(/^(mdb-\w+-\w+)-\w+/)
17
+ if match[1]
18
+ match[1]
19
+ end
20
+ end
21
+
22
+ ##
23
+ # @return [Qtc::Client]
24
+ def client
25
+ if @client.nil?
26
+ @client = Qtc::Client.new(base_url)
27
+ end
28
+
29
+ @client
30
+ end
31
+
32
+ def base_url
33
+ datacenters = inifile['datacenters'] || {}
34
+ if !self.datacenter_id.nil? && datacenters.has_key?(self.datacenter_id)
35
+ "#{datacenters[self.datacenter_id]}/v1"
36
+ else
37
+ raise ArgumentError.new('Unknown datacenter. Please run qtc-cli datacenters to get latest list of your datacenters')
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'instances'
2
+
3
+ command 'mdb list' do |c|
4
+ c.syntax = 'qtc-cli mdb list'
5
+ c.description = 'List all MDB instances'
6
+ c.action do |args, options|
7
+ Qtc::Cli::Mdb::Instances.new.list
8
+ end
9
+ end
10
+
11
+ command 'mdb show' do |c|
12
+ c.syntax = 'qtc-cli mdb show'
13
+ c.description = 'Show MDB instance info'
14
+ c.option '--id ID', String, 'MDB instance id'
15
+ c.action do |args, options|
16
+ Qtc::Cli::Mdb::Instances.new.show(options)
17
+ end
18
+ end
19
+
20
+ command 'mdb logs' do |c|
21
+ c.syntax = 'qtc-cli mdb logs'
22
+ c.description = 'Show MDB logs'
23
+ c.option '--id ID', String, 'MDB instance id'
24
+ c.option '--timestamp', String, 'Include timestamp'
25
+ c.option '--stream', String, 'stdout or stderr'
26
+ c.option '--limit LIMIT', Integer, 'Limit'
27
+ c.option '--offset OFFSET', Integer, 'Offset'
28
+ c.action do |args, options|
29
+ Qtc::Cli::Mdb::Instances.new.logs(options)
30
+ end
31
+ end
@@ -0,0 +1,60 @@
1
+ require_relative 'base'
2
+
3
+ module Qtc
4
+ module Cli
5
+ class Mdb::Instances < Mdb::Base
6
+ include Qtc::Cli::Common
7
+
8
+ def list
9
+ accounts = platform_client.get('/user/accounts')
10
+ accounts['results'].each do |account|
11
+ print color("== #{account['name']}: #{account['id']}")
12
+ instances = platform_client.get("/accounts/#{account['id']}/instances", {provider: 'mdb'})
13
+ instances['results'].each do |instance|
14
+ say(" ~ <%= color('#{instance['id']}', :green) %> #{instance['name']} <%= color('#{instance['tags'].join(', ')}', :yellow) %>")
15
+ end
16
+ puts ''
17
+ end
18
+ end
19
+
20
+ def show(options)
21
+ raise ArgumentError.new('--id is required') if options.id.nil?
22
+
23
+ self.datacenter_id = self.resolve_datacenter_id(options.id)
24
+ instance_id = options.id
25
+ instance_data = instance_info(instance_id)
26
+ if instance_data
27
+ token = instance_data['authorizations'][0]['access_token']
28
+ result = client.get("/services/#{instance_id}", nil, {'Authorization' => "Bearer #{token}"})
29
+ puts "Id: #{result['id']}"
30
+ puts "Name: #{result['name']}"
31
+ puts "Type: #{result['image']['name']}"
32
+ puts "Size: #{result['size'].to_i * 256}MB"
33
+ puts "State: #{result['state']}"
34
+ end
35
+ end
36
+
37
+ def logs(options)
38
+ raise ArgumentError.new('--id is required') if options.id.nil?
39
+
40
+ self.datacenter_id = self.resolve_datacenter_id(options.id)
41
+ offset = options.offset || 0
42
+ limit = options.limit || 100
43
+ stream = options.stream || nil
44
+
45
+ instance_id = options.id
46
+ instance_data = instance_info(instance_id)
47
+ if instance_data
48
+ token = instance_data['authorizations'][0]['access_token']
49
+ result = client.get("/services/#{instance_id}/logs", {offset: offset, limit: limit}, {'Authorization' => "Bearer #{token}"})
50
+ result['results'].each do |r|
51
+ line = ''
52
+ line << "[#{r['time']}] " if options.timestamp == true
53
+ line << r['log']
54
+ puts line
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
data/lib/qtc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Qtc
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/qtc-sdk.gemspec CHANGED
@@ -22,10 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'bundler', '~> 1.5'
23
23
  spec.add_development_dependency 'rake'
24
24
  spec.add_development_dependency 'rspec', '~> 2.14.0'
25
- spec.add_development_dependency 'webmock'
26
- spec.add_development_dependency 'vcr'
27
25
  spec.add_runtime_dependency 'httpclient', '~> 2.3'
28
- spec.add_runtime_dependency 'faye-websocket'
29
26
  spec.add_runtime_dependency 'commander'
30
27
  spec.add_runtime_dependency 'inifile'
31
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qtc-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jari Kolehmainen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2015-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,34 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.14.0
55
- - !ruby/object:Gem::Dependency
56
- name: webmock
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: vcr
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: httpclient
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +66,6 @@ dependencies:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
68
  version: '2.3'
97
- - !ruby/object:Gem::Dependency
98
- name: faye-websocket
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
69
  - !ruby/object:Gem::Dependency
112
70
  name: commander
113
71
  requirement: !ruby/object:Gem::Requirement
@@ -145,6 +103,7 @@ extensions: []
145
103
  extra_rdoc_files: []
146
104
  files:
147
105
  - ".gitignore"
106
+ - Changelog.md
148
107
  - Gemfile
149
108
  - LICENSE.txt
150
109
  - README.md
@@ -159,10 +118,14 @@ files:
159
118
  - lib/qtc/cli/mar/apps.rb
160
119
  - lib/qtc/cli/mar/base.rb
161
120
  - lib/qtc/cli/mar/commands.rb
121
+ - lib/qtc/cli/mar/debug.rb
162
122
  - lib/qtc/cli/mar/domains.rb
163
123
  - lib/qtc/cli/mar/env.rb
164
124
  - lib/qtc/cli/mar/repository.rb
165
125
  - lib/qtc/cli/mar/ssl_certificates.rb
126
+ - lib/qtc/cli/mdb/base.rb
127
+ - lib/qtc/cli/mdb/commands.rb
128
+ - lib/qtc/cli/mdb/instances.rb
166
129
  - lib/qtc/cli/platform/clouds.rb
167
130
  - lib/qtc/cli/platform/commands.rb
168
131
  - lib/qtc/cli/platform/datacenters.rb
@@ -176,7 +139,6 @@ files:
176
139
  - lib/qtc/errors.rb
177
140
  - lib/qtc/mws/client.rb
178
141
  - lib/qtc/version.rb
179
- - lib/qtc_cli.rb
180
142
  - qtc-sdk.gemspec
181
143
  - spec/spec_helper.rb
182
144
  - spec/unit/qtc/client_spec.rb
data/lib/qtc_cli.rb DELETED
@@ -1,12 +0,0 @@
1
- require 'thor'
2
- require 'qtc/client'
3
- require 'qtc/cli/instances'
4
- require 'qtc/cli/mar'
5
-
6
- class QtcCli < Thor
7
- desc 'mar', 'Managed application runtime commands'
8
- subcommand 'mar', Qtc::Cli::Mar
9
-
10
- desc 'instances', 'Instances commands'
11
- subcommand 'instances', Qtc::Cli::Instances
12
- end