vmc 0.3.23 → 0.4.0.beta.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.
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