vmc 0.3.23 → 0.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/bin/vmc +11 -2
  2. data/vmc-ng/LICENSE +746 -0
  3. data/vmc-ng/Rakefile +11 -0
  4. data/vmc-ng/bin/vmc +14 -0
  5. data/vmc-ng/lib/vmc.rb +2 -0
  6. data/vmc-ng/lib/vmc/cli.rb +327 -0
  7. data/vmc-ng/lib/vmc/cli/app.rb +622 -0
  8. data/vmc-ng/lib/vmc/cli/better_help.rb +193 -0
  9. data/vmc-ng/lib/vmc/cli/command.rb +523 -0
  10. data/vmc-ng/lib/vmc/cli/dots.rb +133 -0
  11. data/vmc-ng/lib/vmc/cli/service.rb +122 -0
  12. data/vmc-ng/lib/vmc/cli/user.rb +72 -0
  13. data/vmc-ng/lib/vmc/constants.rb +10 -0
  14. data/vmc-ng/lib/vmc/detect.rb +64 -0
  15. data/vmc-ng/lib/vmc/errors.rb +17 -0
  16. data/vmc-ng/lib/vmc/plugin.rb +40 -0
  17. data/vmc-ng/lib/vmc/version.rb +3 -0
  18. data/{LICENSE → vmc/LICENSE} +0 -0
  19. data/{README.md → vmc/README.md} +1 -5
  20. data/{Rakefile → vmc/Rakefile} +0 -0
  21. data/vmc/bin/vmc +6 -0
  22. data/{caldecott_helper → vmc/caldecott_helper}/Gemfile +0 -0
  23. data/{caldecott_helper → vmc/caldecott_helper}/Gemfile.lock +0 -0
  24. data/{caldecott_helper → vmc/caldecott_helper}/server.rb +0 -0
  25. data/{config → vmc/config}/clients.yml +0 -0
  26. data/{config → vmc/config}/micro/offline.conf +0 -0
  27. data/{config → vmc/config}/micro/paths.yml +0 -0
  28. data/{config → vmc/config}/micro/refresh_ip.rb +0 -0
  29. data/{lib → vmc/lib}/cli.rb +0 -0
  30. data/{lib → vmc/lib}/cli/commands/admin.rb +0 -0
  31. data/{lib → vmc/lib}/cli/commands/apps.rb +0 -0
  32. data/{lib → vmc/lib}/cli/commands/base.rb +0 -0
  33. data/{lib → vmc/lib}/cli/commands/manifest.rb +0 -0
  34. data/{lib → vmc/lib}/cli/commands/micro.rb +0 -0
  35. data/{lib → vmc/lib}/cli/commands/misc.rb +0 -0
  36. data/{lib → vmc/lib}/cli/commands/services.rb +0 -0
  37. data/{lib → vmc/lib}/cli/commands/user.rb +2 -6
  38. data/{lib → vmc/lib}/cli/config.rb +0 -0
  39. data/{lib → vmc/lib}/cli/console_helper.rb +4 -14
  40. data/{lib → vmc/lib}/cli/core_ext.rb +0 -0
  41. data/{lib → vmc/lib}/cli/errors.rb +0 -0
  42. data/{lib → vmc/lib}/cli/frameworks.rb +1 -1
  43. data/{lib → vmc/lib}/cli/manifest_helper.rb +0 -0
  44. data/{lib → vmc/lib}/cli/runner.rb +0 -0
  45. data/{lib → vmc/lib}/cli/services_helper.rb +0 -0
  46. data/{lib → vmc/lib}/cli/tunnel_helper.rb +0 -0
  47. data/{lib → vmc/lib}/cli/usage.rb +0 -0
  48. data/{lib → vmc/lib}/cli/version.rb +1 -1
  49. data/{lib → vmc/lib}/cli/zip_util.rb +0 -0
  50. data/{lib → vmc/lib}/vmc.rb +0 -0
  51. data/{lib → vmc/lib}/vmc/client.rb +0 -0
  52. data/{lib → vmc/lib}/vmc/const.rb +0 -0
  53. data/{lib → vmc/lib}/vmc/micro.rb +0 -0
  54. data/{lib → vmc/lib}/vmc/micro/switcher/base.rb +0 -0
  55. data/{lib → vmc/lib}/vmc/micro/switcher/darwin.rb +0 -0
  56. data/{lib → vmc/lib}/vmc/micro/switcher/dummy.rb +0 -0
  57. data/{lib → vmc/lib}/vmc/micro/switcher/linux.rb +0 -0
  58. data/{lib → vmc/lib}/vmc/micro/switcher/windows.rb +0 -0
  59. data/{lib → vmc/lib}/vmc/micro/vmrun.rb +1 -11
  60. metadata +177 -93
@@ -0,0 +1,133 @@
1
+ module VMC
2
+ module Dots
3
+ DOT_COUNT = 3
4
+ DOT_TICK = 0.15
5
+
6
+ class Skipper
7
+ def initialize(&ret)
8
+ @return = ret
9
+ end
10
+
11
+ def skip(&callback)
12
+ @return.call("SKIPPED", :yellow, callback)
13
+ end
14
+
15
+ def give_up(&callback)
16
+ @return.call("GAVE UP", :red, callback)
17
+ end
18
+
19
+ def fail(&callback)
20
+ @return.call("FAILED", :red, callback)
21
+ end
22
+ end
23
+
24
+ def with_progress(message)
25
+ unless simple_output?
26
+ print message
27
+ dots!
28
+ end
29
+
30
+ skipper = Skipper.new do |status, color, callback|
31
+ unless simple_output?
32
+ stop_dots!
33
+ puts "... #{c(status, color)}"
34
+ end
35
+
36
+ return callback && callback.call
37
+ end
38
+
39
+ begin
40
+ res = yield skipper
41
+ unless simple_output?
42
+ stop_dots!
43
+ puts "... #{c("OK", :green)}"
44
+ end
45
+ res
46
+ rescue
47
+ unless simple_output?
48
+ stop_dots!
49
+ puts "... #{c("FAILED", :red)}"
50
+ end
51
+
52
+ raise
53
+ end
54
+ end
55
+
56
+ def color?
57
+ $stdout.tty?
58
+ end
59
+
60
+ COLOR_CODES = {
61
+ :black => 0,
62
+ :red => 1,
63
+ :green => 2,
64
+ :yellow => 3,
65
+ :blue => 4,
66
+ :magenta => 5,
67
+ :cyan => 6,
68
+ :white => 7
69
+ }
70
+
71
+ # colored text
72
+ #
73
+ # shouldn't use bright colors, as some color themes abuse
74
+ # the bright palette (I'm looking at you, Solarized)
75
+ def c(str, color)
76
+ return str unless color?
77
+ "\e[3#{COLOR_CODES[color]}m#{str}\e[0m"
78
+ end
79
+ module_function :c
80
+
81
+ # bold text
82
+ def b(str)
83
+ return str unless color?
84
+ "\e[1m#{str}\e[0m"
85
+ end
86
+ module_function :b
87
+
88
+ def dots!
89
+ @dots ||=
90
+ Thread.new do
91
+ before_sync = $stdout.sync
92
+
93
+ $stdout.sync = true
94
+
95
+ printed = false
96
+ i = 1
97
+ until @stop_dots
98
+ if printed
99
+ print "\b" * DOT_COUNT
100
+ end
101
+
102
+ print ("." * i).ljust(DOT_COUNT)
103
+ printed = true
104
+
105
+ if i == DOT_COUNT
106
+ i = 0
107
+ else
108
+ i += 1
109
+ end
110
+
111
+ sleep DOT_TICK
112
+ end
113
+
114
+ if printed
115
+ print "\b" * DOT_COUNT
116
+ print " " * DOT_COUNT
117
+ print "\b" * DOT_COUNT
118
+ end
119
+
120
+ $stdout.sync = before_sync
121
+ @stop_dots = nil
122
+ end
123
+ end
124
+
125
+ def stop_dots!
126
+ return unless @dots
127
+ return if @stop_dots
128
+ @stop_dots = true
129
+ @dots.join
130
+ @dots = nil
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,122 @@
1
+ require "vmc/cli/command"
2
+
3
+ module VMC
4
+ class Service < Command
5
+ desc "create", "Create a service"
6
+ group :services, :manage
7
+ flag(:type) { |choices|
8
+ ask "What kind?", :choices => choices
9
+ }
10
+ flag(:name) { |vendor|
11
+ random = sprintf("%x", rand(1000000))
12
+ ask "Name?", :default => "#{vendor}-#{random}"
13
+ }
14
+ def create
15
+ choices = []
16
+ manifests = {}
17
+ client.system_services.each do |type, vendors|
18
+ vendors.each do |vendor, versions|
19
+ versions.each do |version, _|
20
+ choice = "#{vendor} #{version}"
21
+ manifests[choice] = {
22
+ :type => type,
23
+ :vendor => vendor,
24
+ :version => version
25
+ }
26
+
27
+ choices << choice
28
+ end
29
+ end
30
+ end
31
+
32
+ type = input(:type, choices)
33
+ meta = manifests[type]
34
+
35
+ # --type redis should work, and just ignore version
36
+ unless meta
37
+ _, meta = manifests.find { |k, _| k.split.first == type }
38
+ fail "Unknown service type." unless meta
39
+ end
40
+
41
+ service = client.service(input(:name, meta[:vendor]))
42
+ service.type = meta[:type]
43
+ service.vendor = meta[:vendor]
44
+ service.version = meta[:version]
45
+ service.tier = "free"
46
+
47
+ with_progress("Creating service") do
48
+ service.create!
49
+ end
50
+ end
51
+
52
+ desc "bind", "Bind a service to an application"
53
+ group :services, :manage
54
+ flag(:name) { |choices|
55
+ ask "Which service?", :choices => choices
56
+ }
57
+ flag(:app) { |choices|
58
+ ask "Which application?", :choices => choices
59
+ }
60
+ def bind(name = nil, appname = nil)
61
+ name ||= input(:name, client.services.collect(&:name))
62
+ appname ||= input(:app, client.apps.collect(&:name))
63
+
64
+ with_progress("Binding #{c(name, :blue)} to #{c(appname, :blue)}") do
65
+ client.app(appname).bind(name)
66
+ end
67
+ end
68
+
69
+ desc "unbind", "Unbind a service from an application"
70
+ group :services, :manage
71
+ flag(:name) { |choices|
72
+ ask "Which service?", :choices => choices
73
+ }
74
+ flag(:app) { |choices|
75
+ ask "Which application?", :choices => choices
76
+ }
77
+ def unbind(name = nil, appname = nil)
78
+ appname ||= input(:app, client.apps.collect(&:name))
79
+
80
+ app = client.app(appname)
81
+ name ||= input(:name, app.services)
82
+
83
+ with_progress("Unbinding #{c(name, :blue)} from #{c(appname, :blue)}") do
84
+ app.unbind(name)
85
+ end
86
+ end
87
+
88
+ desc "delete", "Delete a service"
89
+ group :services, :manage
90
+ flag(:really) { |name, color|
91
+ force? || ask("Really delete #{c(name, color)}?", :default => false)
92
+ }
93
+ flag(:name) { |choices|
94
+ ask "Delete which service?", :choices => choices
95
+ }
96
+ flag(:all, :default => false)
97
+ def delete(name = nil)
98
+ if input(:all)
99
+ return unless input(:really, "ALL SERVICES", :red)
100
+
101
+ with_progress("Deleting all services") do
102
+ client.services.collect(&:delete!)
103
+ end
104
+
105
+ return
106
+ end
107
+
108
+ unless name
109
+ services = client.services
110
+ fail "No services." if services.empty?
111
+
112
+ name = input(:name, services.collect(&:name))
113
+ end
114
+
115
+ return unless input(:really, name, :blue)
116
+
117
+ with_progress("Deleting #{c(name, :blue)}") do
118
+ client.service(name).delete!
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,72 @@
1
+ require "vmc/cli/command"
2
+
3
+ module VMC
4
+ class User < Command
5
+ desc "create [EMAIL]", "Create a user"
6
+ group :admin, :user, :hidden => true
7
+ flag(:email) {
8
+ ask("Email")
9
+ }
10
+ flag(:password) {
11
+ ask("Password", :echo => "*", :forget => true)
12
+ }
13
+ flag(:verify) {
14
+ ask("Verify Password", :echo => "*", :forget => true)
15
+ }
16
+ def create(email = nil)
17
+ email ||= input(:email)
18
+ password = input(:password)
19
+ verify = input(:verify)
20
+
21
+ if password != verify
22
+ fail "Passwords don't match."
23
+ end
24
+
25
+ with_progress("Creating user") do
26
+ client.register(email, password)
27
+ end
28
+ end
29
+
30
+ desc "delete [EMAIL]", "Delete a user"
31
+ group :admin, :user, :hidden => true
32
+ flag(:really) { |email|
33
+ force? || ask("Really delete user #{c(email, :blue)}?", :default => false)
34
+ }
35
+ def delete(email)
36
+ return unless input(:really, email)
37
+
38
+ with_progress("Deleting #{c(email, :blue)}") do
39
+ client.user(email).delete!
40
+ end
41
+ ensure
42
+ forget(:really)
43
+ end
44
+
45
+ desc "passwd [EMAIL]", "Update a user's password"
46
+ group :admin, :user, :hidden => true
47
+ flag(:email) {
48
+ ask("Email")
49
+ }
50
+ flag(:password) {
51
+ ask("Password", :echo => "*", :forget => true)
52
+ }
53
+ flag(:verify) {
54
+ ask("Verify Password", :echo => "*", :forget => true)
55
+ }
56
+ def passwd(email = nil)
57
+ email ||= input(:email)
58
+ password = input(:password)
59
+ verify = input(:verify)
60
+
61
+ if password != verify
62
+ fail "Passwords don't match."
63
+ end
64
+
65
+ with_progress("Changing password") do
66
+ user = client.user(email)
67
+ user.password = password
68
+ user.update!
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,10 @@
1
+ module VMC
2
+ OLD_TARGET_FILE = "~/.vmc_target"
3
+ OLD_TOKENS_FILE = "~/.vmc_token"
4
+
5
+ CONFIG_DIR = "~/.vmc"
6
+ PLUGINS_FILE = "#{CONFIG_DIR}/plugins.yml"
7
+ TARGET_FILE = "#{CONFIG_DIR}/target"
8
+ TOKENS_FILE = "#{CONFIG_DIR}/tokens.yml"
9
+ CRASH_FILE = "#{CONFIG_DIR}/crash"
10
+ end
@@ -0,0 +1,64 @@
1
+ module VMC
2
+ class Detector
3
+ def initialize(client, path)
4
+ @client = client
5
+ @path = path
6
+ end
7
+
8
+ def all_frameworks
9
+ info = @client.info
10
+ info["frameworks"] || {}
11
+ end
12
+
13
+ def frameworks
14
+ info = @client.info
15
+
16
+ matches = {}
17
+ all_frameworks.each do |name, meta|
18
+ matched = false
19
+
20
+ # e.g. standalone has no detection
21
+ next if meta["detection"].nil?
22
+
23
+ meta["detection"].first.each do |file, match|
24
+ files =
25
+ if File.file? @path
26
+ if File.fnmatch(file, @path)
27
+ [@path]
28
+ else
29
+ []
30
+ end
31
+ else
32
+ Dir.glob("#@path/#{file}")
33
+ end
34
+
35
+ unless files.empty?
36
+ if match == true
37
+ matched = true
38
+ elsif match == false
39
+ matched = false
40
+ break
41
+ else
42
+ files.each do |f|
43
+ contents = File.open(f, &:read)
44
+ if contents =~ Regexp.new(match)
45
+ matched = true
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ if matched
53
+ matches[name] = meta
54
+ end
55
+ end
56
+
57
+ if matches.size == 1
58
+ default = matches.keys.first
59
+ end
60
+
61
+ [matches, default]
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ module VMC
2
+ class UserError < RuntimeError
3
+ def initialize(msg)
4
+ @message = msg
5
+ end
6
+
7
+ def to_s
8
+ @message
9
+ end
10
+ end
11
+
12
+ class NotAuthorized < UserError
13
+ def initialize
14
+ @message = "Not authorized."
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ require "set"
2
+ require "yaml"
3
+
4
+ require "vmc/constants"
5
+ require "vmc/cli"
6
+
7
+ module VMC
8
+ module Plugin
9
+ @@plugins = []
10
+
11
+ def self.load_all
12
+ # auto-load gems with 'vmc-plugin' in their name
13
+ enabled =
14
+ Set.new(
15
+ Gem::Specification.find_all { |s|
16
+ s.name =~ /vmc-plugin/
17
+ }.collect(&:name))
18
+
19
+ # allow explicit enabling/disabling of gems via config
20
+ plugins = File.expand_path(VMC::PLUGINS_FILE)
21
+ if File.exists?(plugins) && yaml = YAML.load_file(plugins)
22
+ enabled += yaml["enabled"] if yaml["enabled"]
23
+ enabled -= yaml["disabled"] if yaml["disabled"]
24
+ end
25
+
26
+ # load up each gem's 'plugin' file
27
+ #
28
+ # we require this file specifically so people can require the gem
29
+ # without it plugging into VMC
30
+ enabled.each do |gemname|
31
+ require "#{gemname}/plugin"
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.Plugin(target = CLI, &blk)
37
+ # SUPER FANCY PLUGIN SYSTEM
38
+ target.class_eval &blk
39
+ end
40
+ end