static 1.0.1 → 1.0.3

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
- data.tar.gz: 78795a9f53837b619fdac866b2bf1c302da5c70a
4
- metadata.gz: e022dc68ad9da82b96382dd86345c1ed9e227f22
3
+ data.tar.gz: 1d0ada09d0360211b786bcf7ff9c5ef2be62787e
4
+ metadata.gz: dcca2c9b5ce9d104bd6ae2f92ac31c27d02ddde8
5
5
  SHA512:
6
- data.tar.gz: 5a792f60ab45a2a865617366aa229d787e45dba03c0aac568a28c1c91422d4b44f9517e5a7ecf3c1c7b33a18c8fb06b90cef19415bb503767d3b442b4392893c
7
- metadata.gz: e65608af9b295e5fd1135c0f314f23a97c300ff0f32a0ba23c420da5bcd56adb69af852e8a5bccb7b706a0e0b820d9d376b5042b9b8c435a222b4962613f5879
6
+ data.tar.gz: 8c8b8c0a88deae4d41645eb58f9c279736805f26c4c420aeec6a43e1e4a3cdfb0d756172279d55b2eb3469b116d34b0040392d654dea88613eec4257ff0e232d
7
+ metadata.gz: bffcb48976513c0fd30eff1bb4752e8b55535c1d3a68f8d2798948c09b37fd92def78503074bb244dcbed2389371c93e0b85380e7feb417ca4c4344e5f1ce90f
data/LICENSE CHANGED
@@ -205,9 +205,9 @@
205
205
  SOFTWARE DISTRIBUTED WITH THE Static Cloud Command Line Client :
206
206
 
207
207
  The Static Cloud Command Line Client includes a number of subcomponents with
208
- separate copyright notices and license terms. Your use of the source
209
- code for the these subcomponents is subject to the terms and
210
- conditions of the following licenses:
208
+ separate copyright notices and license terms. Your use of the source code
209
+ for the these subcomponents is subject to the terms and conditions of the
210
+ following licenses:
211
211
 
212
- Apache 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt
213
- MIT http://www.opensource.org/licenses/mit-license.php
212
+ Apache 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt
213
+ MIT http://www.opensource.org/licenses/mit-license.php
data/Rakefile CHANGED
@@ -1,3 +1,17 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
1
15
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
16
 
3
17
  require "rake"
@@ -40,5 +54,5 @@ namespace "test" do
40
54
  end
41
55
 
42
56
  CLEAN.include [
43
- '.bundle', 'Gemfile.lock', '*.gem'
57
+ '.bundle', '*.gem'
44
58
  ]
@@ -1,3 +1,17 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
1
15
  require "static/version"
2
16
  require "static/cli"
3
17
 
@@ -1,3 +1,17 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
1
15
  require "vmc"
2
16
  require "vmc/cli"
3
17
 
@@ -1,3 +1,17 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
1
15
  require "vmc/cli/app/base"
2
16
  require "pp"
3
17
 
@@ -1,5 +1,19 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
1
15
  module Static
2
16
  module Cmd
3
- VERSION = "1.0.1".freeze
17
+ VERSION = "1.0.3".freeze
4
18
  end
5
19
  end
@@ -0,0 +1,38 @@
1
+ require "rake"
2
+ require "rspec/core/rake_task"
3
+
4
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
5
+ require "manifests-vmc-plugin/version"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ task :default => :spec
9
+
10
+ namespace :deploy do
11
+ def last_staging_sha
12
+ `git rev-parse latest-staging`.strip
13
+ end
14
+
15
+ def last_release_sha
16
+ `git rev-parse latest-release`.strip
17
+ end
18
+
19
+ def last_staging_ref_was_released?
20
+ last_staging_sha == last_release_sha
21
+ end
22
+
23
+ task :staging, :version do |_, args|
24
+ sh "gem bump --push #{"--version #{args.version}" if args.version}" if last_staging_ref_was_released?
25
+ sh "git tag -f latest-staging"
26
+ sh "git push origin :latest-staging"
27
+ sh "git push origin latest-staging"
28
+ end
29
+
30
+ task :gem do
31
+ sh "git fetch"
32
+ sh "git checkout #{last_staging_sha}"
33
+ sh "gem release --tag"
34
+ sh "git tag -f latest-release"
35
+ sh "git push origin :latest-release"
36
+ sh "git push origin latest-release"
37
+ end
38
+ end
@@ -0,0 +1,313 @@
1
+ require "yaml"
2
+ require "set"
3
+
4
+ require "manifests-vmc-plugin/loader"
5
+
6
+
7
+ module VMCManifests
8
+ MANIFEST_FILE = "manifest.yml"
9
+
10
+ @@showed_manifest_usage = false
11
+
12
+ def manifest
13
+ return @manifest if @manifest
14
+
15
+ if manifest_file && File.exists?(manifest_file)
16
+ @manifest = load_manifest(manifest_file)
17
+ end
18
+ end
19
+
20
+ def save_manifest(save_to = manifest_file)
21
+ fail "No manifest to save!" unless @manifest
22
+
23
+ File.open(save_to, "w") do |io|
24
+ YAML.dump(@manifest, io)
25
+ end
26
+ end
27
+
28
+ # find the manifest file to work with
29
+ def manifest_file
30
+ return @manifest_file if @manifest_file
31
+
32
+ unless path = input[:manifest]
33
+ where = Dir.pwd
34
+ while true
35
+ if File.exists?(File.join(where, MANIFEST_FILE))
36
+ path = File.join(where, MANIFEST_FILE)
37
+ break
38
+ elsif File.basename(where) == "/"
39
+ path = nil
40
+ break
41
+ else
42
+ where = File.expand_path("../", where)
43
+ end
44
+ end
45
+ end
46
+
47
+ return unless path
48
+
49
+ @manifest_file = File.expand_path(path)
50
+ end
51
+
52
+ # load and resolve a given manifest file
53
+ def load_manifest(file)
54
+ Loader.new(file, self).manifest
55
+ end
56
+
57
+ # dynamic symbol resolution
58
+ def resolve_symbol(sym)
59
+ case sym
60
+ when "target-url"
61
+ client_target
62
+
63
+ when "target-base"
64
+ target_base
65
+
66
+ when "random-word"
67
+ sprintf("%04x", rand(0x0100000))
68
+
69
+ when /^ask (.+)/
70
+ ask($1)
71
+ end
72
+ end
73
+
74
+ # find apps by an identifier, which may be either a tag, a name, or a path
75
+ def find_apps(identifier)
76
+ return [] unless manifest
77
+
78
+ apps = apps_by(:name, identifier)
79
+
80
+ if apps.empty?
81
+ apps = apps_by(:path, from_manifest(identifier))
82
+ end
83
+
84
+ apps
85
+ end
86
+
87
+ # return all the apps described by the manifest
88
+ def all_apps
89
+ manifest[:applications]
90
+ end
91
+
92
+ def current_apps
93
+ manifest[:applications].select do |app|
94
+ next unless app[:path]
95
+ from_manifest(app[:path]) == Dir.pwd
96
+ end
97
+ end
98
+
99
+ # splits the user's input, resolving paths with the manifest,
100
+ # into internal/external apps
101
+ #
102
+ # internal apps are returned as their data in the manifest
103
+ #
104
+ # external apps are the strings that the user gave, to be
105
+ # passed along wholesale to the wrapped command
106
+ def apps_in_manifest(input = nil, use_name = true, &blk)
107
+ names_or_paths =
108
+ if input.has?(:apps)
109
+ # names may be given but be [], which will still cause
110
+ # interaction, so use #direct instead of #[] here
111
+ input.direct(:apps)
112
+ elsif input.has?(:app)
113
+ [input.direct(:app)]
114
+ elsif input.has?(:name)
115
+ [input.direct(:name)]
116
+ else
117
+ []
118
+ end
119
+
120
+ internal = []
121
+ external = []
122
+
123
+ names_or_paths.each do |x|
124
+ if x.is_a?(String)
125
+ if x =~ %r([/\\])
126
+ apps = find_apps(File.expand_path(x))
127
+
128
+ if apps.empty?
129
+ fail("Path #{b(x)} is not present in manifest #{b(relative_manifest_file)}.")
130
+ end
131
+ else
132
+ apps = find_apps(x)
133
+ end
134
+
135
+ if !apps.empty?
136
+ internal += apps
137
+ else
138
+ external << x
139
+ end
140
+ else
141
+ external << x
142
+ end
143
+ end
144
+
145
+ [internal, external]
146
+ end
147
+
148
+ def create_manifest_for(app, path)
149
+ meta = {
150
+ "name" => app.name,
151
+ "framework" => app.framework.name,
152
+ "runtime" => app.runtime.name,
153
+ "memory" => human_size(app.memory * 1024 * 1024, 0),
154
+ "instances" => app.total_instances,
155
+ "url" => app.url ? app.url.sub(target_base, '${target-base}') : "none",
156
+ "path" => path
157
+ }
158
+
159
+ services = app.services
160
+
161
+ unless services.empty?
162
+ meta["services"] = {}
163
+
164
+ services.each do |i|
165
+ if v2?
166
+ p = i.service_plan
167
+ s = p.service
168
+
169
+ meta["services"][i.name] = {
170
+ "label" => s.label,
171
+ "provider" => s.provider,
172
+ "version" => s.version,
173
+ "plan" => p.name
174
+ }
175
+ else
176
+ meta["services"][i.name] = {
177
+ "vendor" => i.vendor,
178
+ "version" => i.version,
179
+ "tier" => i.tier
180
+ }
181
+ end
182
+ end
183
+ end
184
+
185
+ if cmd = app.command
186
+ meta["command"] = cmd
187
+ end
188
+
189
+ meta
190
+ end
191
+
192
+ private
193
+
194
+ def relative_manifest_file
195
+ Pathname.new(manifest_file).relative_path_from(Pathname.pwd)
196
+ end
197
+
198
+ def show_manifest_usage
199
+ return if @@showed_manifest_usage
200
+
201
+ path = relative_manifest_file
202
+ line "Using manifest file #{c(path, :name)}"
203
+ line
204
+
205
+ @@showed_manifest_usage = true
206
+ end
207
+
208
+ def no_apps
209
+ fail "No applications or manifest to operate on."
210
+ end
211
+
212
+ def warn_reset_changes
213
+ line c("Not applying manifest changes without --reset", :warning)
214
+ line "See `vmc diff` for more details."
215
+ line
216
+ end
217
+
218
+ def apps_by(attr, val)
219
+ manifest[:applications].select do |info|
220
+ info[attr] == val
221
+ end
222
+ end
223
+
224
+ # expand a path relative to the manifest file's directory
225
+ def from_manifest(path)
226
+ File.expand_path(path, File.dirname(manifest_file))
227
+ end
228
+
229
+
230
+ def ask_to_save(input, app)
231
+ return if manifest_file
232
+ return unless ask("Save configuration?", :default => false)
233
+
234
+ manifest = create_manifest_for(app, input[:path])
235
+
236
+ with_progress("Saving to #{c("manifest.yml", :name)}") do
237
+ File.open("manifest.yml", "w") do |io|
238
+ YAML.dump(
239
+ { "applications" => [manifest] },
240
+ io)
241
+ end
242
+ end
243
+ end
244
+
245
+ def env_hash(val)
246
+ if val.is_a?(Hash)
247
+ val
248
+ else
249
+ hash = {}
250
+
251
+ val.each do |pair|
252
+ name, val = pair.split("=", 2)
253
+ hash[name] = val
254
+ end
255
+
256
+ hash
257
+ end
258
+ end
259
+
260
+ def setup_env(app, info)
261
+ return unless info[:env]
262
+ app.env = env_hash(info[:env])
263
+ end
264
+
265
+ def setup_services(app, info)
266
+ return if !info[:services] || info[:services].empty?
267
+
268
+ offerings = client.services
269
+
270
+ to_bind = []
271
+
272
+ info[:services].each do |name, svc|
273
+ name = name.to_s
274
+
275
+ if instance = client.service_instance_by_name(name)
276
+ to_bind << instance
277
+ else
278
+ offering = offerings.find { |o|
279
+ o.label == (svc[:label] || svc[:type] || svc[:vendor]) &&
280
+ (!svc[:version] || o.version == svc[:version]) &&
281
+ (o.provider == (svc[:provider] || "core"))
282
+ }
283
+
284
+ fail "Unknown service offering: #{svc.inspect}." unless offering
285
+
286
+ if v2?
287
+ plan = offering.service_plans.find { |p|
288
+ p.name == (svc[:plan] || "D100")
289
+ }
290
+
291
+ fail "Unknown service plan: #{svc[:plan]}." unless plan
292
+ end
293
+
294
+ invoke :create_service,
295
+ :name => name,
296
+ :offering => offering,
297
+ :plan => plan,
298
+ :app => app
299
+ end
300
+ end
301
+
302
+ to_bind.each do |s|
303
+ next if app.binds?(s)
304
+
305
+ # TODO: splat
306
+ invoke :bind_service, :app => app, :service => s
307
+ end
308
+ end
309
+
310
+ def target_base
311
+ client_target.sub(/^[^\.]+\./, "")
312
+ end
313
+ end