vmc 0.3.16.beta.3 → 0.3.16.beta.5
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.
- data/README.md +9 -0
- data/config/micro/offline.conf +2 -0
- data/config/micro/paths.yml +22 -0
- data/config/micro/refresh_ip.rb +20 -0
- data/lib/cli/commands/apps.rb +18 -19
- data/lib/cli/commands/micro.rb +115 -0
- data/lib/cli/config.rb +13 -0
- data/lib/cli/frameworks.rb +6 -2
- data/lib/cli/manifest_helper.rb +1 -1
- data/lib/cli/runner.rb +11 -0
- data/lib/cli/usage.rb +9 -0
- data/lib/cli/version.rb +1 -1
- data/lib/cli.rb +14 -1
- data/lib/vmc/micro/switcher/base.rb +97 -0
- data/lib/vmc/micro/switcher/darwin.rb +19 -0
- data/lib/vmc/micro/switcher/dummy.rb +15 -0
- data/lib/vmc/micro/switcher/linux.rb +16 -0
- data/lib/vmc/micro/switcher/windows.rb +31 -0
- data/lib/vmc/micro/vmrun.rb +158 -0
- data/lib/vmc/micro.rb +56 -0
- metadata +13 -2
data/README.md
CHANGED
@@ -75,6 +75,15 @@ MIT license, please see the LICENSE file. All rights reserved._
|
|
75
75
|
runtimes Display the supported runtimes of the target system
|
76
76
|
frameworks Display the recognized frameworks of the target system
|
77
77
|
|
78
|
+
Micro Cloud Foundry
|
79
|
+
micro status Display Micro Cloud Foundry VM status
|
80
|
+
mciro offline Configure Micro Cloud Foundry VM for offline mode
|
81
|
+
micro online Configure Micro Cloud Foundry VM for online mode
|
82
|
+
[--vmx file] Path to micro.vmx
|
83
|
+
[--vmrun executable] Path to vmrun executable
|
84
|
+
[--password cleartext] Cleartext password for guest VM vcap user
|
85
|
+
[--save] Save cleartext password in ~/.vmc_micro
|
86
|
+
|
78
87
|
Misc
|
79
88
|
aliases List aliases
|
80
89
|
alias <alias[=]command> Create an alias for a command
|
@@ -0,0 +1,22 @@
|
|
1
|
+
darwin:
|
2
|
+
vmrun:
|
3
|
+
- "/Applications/VMware Fusion.app/Contents/Library/"
|
4
|
+
- "/Applications/Fusion.app/Contents/Library/"
|
5
|
+
vmx:
|
6
|
+
- "~/Documents/Virtual Machines.localized/"
|
7
|
+
- "~/Documents/Virtual Machines/"
|
8
|
+
- "~/Desktop/"
|
9
|
+
|
10
|
+
linux:
|
11
|
+
vmrun:
|
12
|
+
- "/usr/bin/"
|
13
|
+
vmx:
|
14
|
+
- "~/"
|
15
|
+
|
16
|
+
windows:
|
17
|
+
vmrun:
|
18
|
+
- "c:\\Program Files (x86)\\"
|
19
|
+
- "c:\\Program Files\\"
|
20
|
+
vmx:
|
21
|
+
- "~\\Documents\\"
|
22
|
+
- "~\\Desktop\\"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/var/vcap/bosh/bin/ruby
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
A_ROOT_SERVER = '198.41.0.4'
|
5
|
+
|
6
|
+
begin
|
7
|
+
retries ||= 0
|
8
|
+
route ||= A_ROOT_SERVER
|
9
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
10
|
+
ip_address = UDPSocket.open {|s| s.connect(route, 1); s.addr.last }
|
11
|
+
rescue Errno::ENETUNREACH
|
12
|
+
# happens on boot when dhcp hasn't completed when we get here
|
13
|
+
sleep 3
|
14
|
+
retries += 1
|
15
|
+
retry if retries < 10
|
16
|
+
ensure
|
17
|
+
Socket.do_not_reverse_lookup = orig
|
18
|
+
end
|
19
|
+
|
20
|
+
File.open("/tmp/ip.txt", 'w') { |file| file.write(ip_address) }
|
data/lib/cli/commands/apps.rb
CHANGED
@@ -193,7 +193,7 @@ module VMC::Cli::Command
|
|
193
193
|
instance = @options[:instance] || '0'
|
194
194
|
content = client.app_files(appname, path, instance)
|
195
195
|
display content
|
196
|
-
rescue VMC::Client::TargetError
|
196
|
+
rescue VMC::Client::NotFound, VMC::Client::TargetError
|
197
197
|
err 'No such file or directory'
|
198
198
|
end
|
199
199
|
|
@@ -675,10 +675,6 @@ module VMC::Cli::Command
|
|
675
675
|
end
|
676
676
|
end
|
677
677
|
|
678
|
-
def log_file_paths
|
679
|
-
%w[logs/stderr.log logs/stdout.log logs/startup.log]
|
680
|
-
end
|
681
|
-
|
682
678
|
def grab_all_logs(appname)
|
683
679
|
instances_info_envelope = client.app_instances(appname)
|
684
680
|
return if instances_info_envelope.is_a?(Array)
|
@@ -689,15 +685,23 @@ module VMC::Cli::Command
|
|
689
685
|
end
|
690
686
|
|
691
687
|
def grab_logs(appname, instance)
|
692
|
-
|
688
|
+
files_under(appname, instance, "/logs").each do |path|
|
693
689
|
begin
|
694
690
|
content = client.app_files(appname, path, instance)
|
695
691
|
display_logfile(path, content, instance)
|
696
|
-
rescue VMC::Client::TargetError
|
692
|
+
rescue VMC::Client::NotFound, VMC::Client::TargetError
|
697
693
|
end
|
698
694
|
end
|
699
695
|
end
|
700
696
|
|
697
|
+
def files_under(appname, instance, path)
|
698
|
+
client.app_files(appname, path, instance).split("\n").collect do |l|
|
699
|
+
"#{path}/#{l.split[0]}"
|
700
|
+
end
|
701
|
+
rescue VMC::Client::NotFound, VMC::Client::TargetError
|
702
|
+
[]
|
703
|
+
end
|
704
|
+
|
701
705
|
def grab_crash_logs(appname, instance, was_staged=false)
|
702
706
|
# stage crash info
|
703
707
|
crashes(appname, false) unless was_staged
|
@@ -706,16 +710,11 @@ module VMC::Cli::Command
|
|
706
710
|
map = VMC::Cli::Config.instances
|
707
711
|
instance = map[instance] if map[instance]
|
708
712
|
|
709
|
-
|
710
|
-
/
|
711
|
-
/app/
|
712
|
-
|
713
|
-
|
714
|
-
begin
|
715
|
-
content = client.app_files(appname, path, instance)
|
716
|
-
display_logfile(path, content, instance)
|
717
|
-
rescue VMC::Client::TargetError
|
718
|
-
end
|
713
|
+
(files_under(appname, instance, "/logs") +
|
714
|
+
files_under(appname, instance, "/app/logs") +
|
715
|
+
files_under(appname, instance, "/app/log")).each do |path|
|
716
|
+
content = client.app_files(appname, path, instance)
|
717
|
+
display_logfile(path, content, instance)
|
719
718
|
end
|
720
719
|
end
|
721
720
|
|
@@ -732,7 +731,7 @@ module VMC::Cli::Command
|
|
732
731
|
display tail.join("\n") if new_lines > 0
|
733
732
|
end
|
734
733
|
since + new_lines
|
735
|
-
rescue VMC::Client::TargetError
|
734
|
+
rescue VMC::Client::NotFound, VMC::Client::TargetError
|
736
735
|
0
|
737
736
|
end
|
738
737
|
|
@@ -1064,7 +1063,7 @@ module VMC::Cli::Command
|
|
1064
1063
|
entry[:index],
|
1065
1064
|
"====> [#{entry[:index]}: #{path}] <====\n".bold
|
1066
1065
|
)
|
1067
|
-
rescue VMC::Client::TargetError
|
1066
|
+
rescue VMC::Client::NotFound, VMC::Client::TargetError
|
1068
1067
|
end
|
1069
1068
|
end
|
1070
1069
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module VMC::Cli::Command
|
2
|
+
class Micro < Base
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
super(args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def offline(mode)
|
9
|
+
command('offline')
|
10
|
+
end
|
11
|
+
|
12
|
+
def online(mode)
|
13
|
+
command('online')
|
14
|
+
end
|
15
|
+
|
16
|
+
def status(mode)
|
17
|
+
command('status')
|
18
|
+
end
|
19
|
+
|
20
|
+
def command(cmd)
|
21
|
+
config = build_config
|
22
|
+
switcher(config).send(cmd)
|
23
|
+
store_config(config)
|
24
|
+
end
|
25
|
+
|
26
|
+
def switcher(config)
|
27
|
+
case Micro.platform
|
28
|
+
when :darwin
|
29
|
+
switcher = VMC::Micro::Switcher::Darwin.new(config)
|
30
|
+
when :linux
|
31
|
+
switcher = VMC::Micro::Switcher::Linux.new(config)
|
32
|
+
when :windows
|
33
|
+
switcher = VMC::Micro::Switcher::Windows.new(config)
|
34
|
+
when :dummy # for testing only
|
35
|
+
switcher = VMC::Micro::Switcher::Dummy.new(config)
|
36
|
+
else
|
37
|
+
err "unsupported platform: #{Micro.platform}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the configuration needed to run the micro related subcommands.
|
42
|
+
# First loads saved config from file (if there is any), then overrides
|
43
|
+
# loaded values with command line arguments, and finally tries to guess
|
44
|
+
# in case neither was used:
|
45
|
+
# vmx location of micro.vmx file
|
46
|
+
# vmrun location of vmrun command
|
47
|
+
# password password for vcap user (in the guest vm)
|
48
|
+
# platform current platform
|
49
|
+
def build_config
|
50
|
+
conf = VMC::Cli::Config.micro # returns {} if there isn't a saved config
|
51
|
+
|
52
|
+
override(conf, 'vmx', true) do
|
53
|
+
locate_vmx(Micro.platform)
|
54
|
+
end
|
55
|
+
|
56
|
+
override(conf, 'vmrun', true) do
|
57
|
+
VMC::Micro::VMrun.locate(Micro.platform)
|
58
|
+
end
|
59
|
+
|
60
|
+
override(conf, 'password') do
|
61
|
+
@password = ask("Please enter your Micro Cloud Foundry VM password (vcap user) password", :echo => "*")
|
62
|
+
end
|
63
|
+
|
64
|
+
conf['platform'] = Micro.platform
|
65
|
+
|
66
|
+
conf
|
67
|
+
end
|
68
|
+
|
69
|
+
# Save the cleartext password if --save is supplied.
|
70
|
+
# Note: it is due to vix we have to use a cleartext password :(
|
71
|
+
# Only if --password is used and not --save is the password deleted from the
|
72
|
+
# config file before it is stored to disk.
|
73
|
+
def store_config(config)
|
74
|
+
if @options[:save]
|
75
|
+
warn("cleartext password saved in: #{VMC::Cli::Config::MICRO_FILE}")
|
76
|
+
elsif @options[:password] || @password
|
77
|
+
config.delete('password')
|
78
|
+
end
|
79
|
+
|
80
|
+
VMC::Cli::Config.store_micro(config)
|
81
|
+
end
|
82
|
+
|
83
|
+
# override with command line arguments and yield the block in case the option isn't set
|
84
|
+
def override(config, option, escape=false, &blk)
|
85
|
+
# override if given on the command line
|
86
|
+
if opt = @options[option.to_sym]
|
87
|
+
opt = VMC::Micro.escape_path(opt) if escape
|
88
|
+
config[option] = opt
|
89
|
+
end
|
90
|
+
config[option] = yield unless config[option]
|
91
|
+
end
|
92
|
+
|
93
|
+
def locate_vmx(platform)
|
94
|
+
paths = YAML.load_file(VMC::Micro.config_file('paths.yml'))
|
95
|
+
vmx_paths = paths[platform.to_s]['vmx']
|
96
|
+
vmx = VMC::Micro.locate_file('micro.vmx', 'micro', vmx_paths)
|
97
|
+
err "Unable to locate micro.vmx, please supply --vmx option" unless vmx
|
98
|
+
vmx
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.platform
|
102
|
+
case RUBY_PLATFORM
|
103
|
+
when /darwin/ # x86_64-darwin11.2.0
|
104
|
+
:darwin
|
105
|
+
when /linux/ # x86_64-linux
|
106
|
+
:linux
|
107
|
+
when /mingw|mswin32|cygwin/ # i386-mingw32
|
108
|
+
:windows
|
109
|
+
else
|
110
|
+
RUBY_PLATFORM
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
data/lib/cli/config.rb
CHANGED
@@ -14,6 +14,7 @@ module VMC::Cli
|
|
14
14
|
INSTANCES_FILE = '~/.vmc_instances'
|
15
15
|
ALIASES_FILE = '~/.vmc_aliases'
|
16
16
|
CLIENTS_FILE = '~/.vmc_clients'
|
17
|
+
MICRO_FILE = '~/.vmc_micro'
|
17
18
|
|
18
19
|
STOCK_CLIENTS = File.expand_path("../../../config/clients.yml", __FILE__)
|
19
20
|
|
@@ -102,6 +103,18 @@ module VMC::Cli
|
|
102
103
|
File.open(aliases_file, 'wb') {|f| f.write(aliases.to_yaml)}
|
103
104
|
end
|
104
105
|
|
106
|
+
def micro
|
107
|
+
micro_file = File.expand_path(MICRO_FILE)
|
108
|
+
return {} unless File.exists? micro_file
|
109
|
+
contents = lock_and_read(micro_file).strip
|
110
|
+
JSON.parse(contents)
|
111
|
+
end
|
112
|
+
|
113
|
+
def store_micro(micro)
|
114
|
+
micro_file = File.expand_path(MICRO_FILE)
|
115
|
+
lock_and_write(micro_file, micro.to_json)
|
116
|
+
end
|
117
|
+
|
105
118
|
def deep_merge(a, b)
|
106
119
|
merge = proc do |_, old, new|
|
107
120
|
if new.is_a?(Hash) and old.is_a?(Hash)
|
data/lib/cli/frameworks.rb
CHANGED
@@ -17,6 +17,7 @@ module VMC::Cli
|
|
17
17
|
'Erlang/OTP Rebar' => ['otp_rebar', { :mem => '64M', :description => 'Erlang/OTP Rebar Application'}],
|
18
18
|
'WSGI' => ['wsgi', { :mem => '64M', :description => 'Python WSGI Application'}],
|
19
19
|
'Django' => ['django', { :mem => '128M', :description => 'Python Django Application'}],
|
20
|
+
'Rack' => ['rack', { :mem => '128M', :description => 'Rack Application'}]
|
20
21
|
}
|
21
22
|
|
22
23
|
class << self
|
@@ -35,13 +36,16 @@ module VMC::Cli
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
def detect(path)
|
39
|
+
def detect(path, available_frameworks)
|
39
40
|
Dir.chdir(path) do
|
40
|
-
|
41
41
|
# Rails
|
42
42
|
if File.exist?('config/environment.rb')
|
43
43
|
return Framework.lookup('Rails')
|
44
44
|
|
45
|
+
# Rack
|
46
|
+
elsif File.exist?('config.ru') && available_frameworks.include?(["rack"])
|
47
|
+
return Framework.lookup('Rack')
|
48
|
+
|
45
49
|
# Java
|
46
50
|
elsif Dir.glob('*.war').first || File.exist?('WEB-INF/web.xml')
|
47
51
|
war_file = Dir.glob('*.war').first
|
data/lib/cli/manifest_helper.rb
CHANGED
@@ -165,7 +165,7 @@ module VMC::Cli::ManifestHelper
|
|
165
165
|
|
166
166
|
# Detect the appropriate framework.
|
167
167
|
def detect_framework(prompt_ok = true)
|
168
|
-
framework = VMC::Cli::Framework.detect(@application)
|
168
|
+
framework = VMC::Cli::Framework.detect(@application, frameworks_info)
|
169
169
|
framework_correct = ask("Detected a #{framework}, is this correct?", :default => true) if prompt_ok && framework
|
170
170
|
if prompt_ok && (framework.nil? || !framework_correct)
|
171
171
|
display "#{"[WARNING]".yellow} Can't determine the Application Type." unless framework
|
data/lib/cli/runner.rb
CHANGED
@@ -59,6 +59,11 @@ class VMC::Cli::Runner
|
|
59
59
|
|
60
60
|
opts.on('-q', '--quiet') { @options[:quiet] = true }
|
61
61
|
|
62
|
+
# micro cloud options
|
63
|
+
opts.on('--vmx FILE') { |file| @options[:vmx] = file }
|
64
|
+
opts.on('--vmrun FILE') { |file| @options[:vmrun] = file }
|
65
|
+
opts.on('--save') { @options[:save] = true }
|
66
|
+
|
62
67
|
# Don't use builtin zip
|
63
68
|
opts.on('--no-zip') { @options[:nozip] = true }
|
64
69
|
opts.on('--nozip') { @options[:nozip] = true }
|
@@ -380,6 +385,12 @@ class VMC::Cli::Runner
|
|
380
385
|
usage('vmc rails-console <appname>')
|
381
386
|
set_cmd(:apps, :console, 1)
|
382
387
|
|
388
|
+
when 'micro'
|
389
|
+
usage('vmc micro <online|offline|status> [--password password] [--save] [--vmx file] [--vmrun executable]')
|
390
|
+
if %w[online offline status].include?(@args[0])
|
391
|
+
set_cmd(:micro, @args[0].to_sym, 1)
|
392
|
+
end
|
393
|
+
|
383
394
|
when 'help'
|
384
395
|
display_help if @args.size == 0
|
385
396
|
@help_only = true
|
data/lib/cli/usage.rb
CHANGED
@@ -91,6 +91,15 @@ Currently available vmc commands are:
|
|
91
91
|
runtimes Display the supported runtimes of the target system
|
92
92
|
frameworks Display the recognized frameworks of the target system
|
93
93
|
|
94
|
+
Micro Cloud Foundry
|
95
|
+
micro status Display Micro Cloud Foundry VM status
|
96
|
+
micro offline Configure Micro Cloud Foundry VM for offline mode
|
97
|
+
micro online Configure Micro Cloud Foundry VM for online mode
|
98
|
+
[--vmx file] Path to micro.vmx
|
99
|
+
[--vmrun executable] Path to vmrun executable
|
100
|
+
[--password cleartext] Cleartext password for guest VM vcap user
|
101
|
+
[--save] Save cleartext password in ~/.vmc_micro
|
102
|
+
|
94
103
|
Misc
|
95
104
|
aliases List aliases
|
96
105
|
alias <alias[=]command> Create an alias for a command
|
data/lib/cli/version.rb
CHANGED
data/lib/cli.rb
CHANGED
@@ -4,6 +4,18 @@ WINDOWS = !!(RUBY_PLATFORM =~ /mingw|mswin32|cygwin/)
|
|
4
4
|
|
5
5
|
module VMC
|
6
6
|
autoload :Client, "#{ROOT}/vmc/client"
|
7
|
+
autoload :Micro, "#{ROOT}/vmc/micro"
|
8
|
+
|
9
|
+
module Micro
|
10
|
+
module Switcher
|
11
|
+
autoload :Base, "#{ROOT}/vmc/micro/switcher/base"
|
12
|
+
autoload :Darwin, "#{ROOT}/vmc/micro/switcher/darwin"
|
13
|
+
autoload :Dummy, "#{ROOT}/vmc/micro/switcher/dummy"
|
14
|
+
autoload :Linux, "#{ROOT}/vmc/micro/switcher/linux"
|
15
|
+
autoload :Windows, "#{ROOT}/vmc/micro/switcher/windows"
|
16
|
+
end
|
17
|
+
autoload :VMrun, "#{ROOT}/vmc/micro/vmrun"
|
18
|
+
end
|
7
19
|
|
8
20
|
module Cli
|
9
21
|
autoload :Config, "#{ROOT}/cli/config"
|
@@ -13,12 +25,13 @@ module VMC
|
|
13
25
|
autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
|
14
26
|
autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
|
15
27
|
autoload :ManifestHelper, "#{ROOT}/cli/manifest_helper"
|
16
|
-
autoload :ConsoleHelper,
|
28
|
+
autoload :ConsoleHelper, "#{ROOT}/cli/console_helper"
|
17
29
|
|
18
30
|
module Command
|
19
31
|
autoload :Base, "#{ROOT}/cli/commands/base"
|
20
32
|
autoload :Admin, "#{ROOT}/cli/commands/admin"
|
21
33
|
autoload :Apps, "#{ROOT}/cli/commands/apps"
|
34
|
+
autoload :Micro, "#{ROOT}/cli/commands/micro"
|
22
35
|
autoload :Misc, "#{ROOT}/cli/commands/misc"
|
23
36
|
autoload :Services, "#{ROOT}/cli/commands/services"
|
24
37
|
autoload :User, "#{ROOT}/cli/commands/user"
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'interact'
|
2
|
+
|
3
|
+
module VMC::Micro::Switcher
|
4
|
+
class Base
|
5
|
+
include Interactive
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
|
10
|
+
@vmrun = VMC::Micro::VMrun.new(config)
|
11
|
+
unless @vmrun.running?
|
12
|
+
if ask("Micro Cloud Foundry VM is not running. Do you want to start it?", :choices => ['y', 'n']) == 'y'
|
13
|
+
display "Starting Micro Cloud Foundry VM: ", false
|
14
|
+
@vmrun.start
|
15
|
+
say "done".green
|
16
|
+
else
|
17
|
+
err "Micro Cloud Foundry VM needs to be running."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
err "Micro Cloud Foundry VM initial setup needs to be completed before using 'vmc micro'" unless @vmrun.ready?
|
22
|
+
end
|
23
|
+
|
24
|
+
def offline
|
25
|
+
unless @vmrun.offline?
|
26
|
+
# save online connection type so we can restore it later
|
27
|
+
@config['online_connection_type'] = @vmrun.connection_type
|
28
|
+
|
29
|
+
if (@config['online_connection_type'] != 'nat')
|
30
|
+
if ask("Reconfigure Micro Cloud Foundry VM network to nat mode and reboot?", :choices => ['y', 'n']) == 'y'
|
31
|
+
display "Rebooting Micro Cloud Foundry VM: ", false
|
32
|
+
@vmrun.connection_type = 'nat'
|
33
|
+
@vmrun.reset
|
34
|
+
say "done".green
|
35
|
+
else
|
36
|
+
err "Aborted"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
display "Setting Micro Cloud Foundry VM to offline mode: ", false
|
41
|
+
@vmrun.offline!
|
42
|
+
say "done".green
|
43
|
+
display "Setting host DNS server: ", false
|
44
|
+
|
45
|
+
@config['domain'] = @vmrun.domain
|
46
|
+
@config['ip'] = @vmrun.ip
|
47
|
+
set_nameserver(@config['domain'], @config['ip'])
|
48
|
+
say "done".green
|
49
|
+
else
|
50
|
+
say "Micro Cloud Foundry VM already in offline mode".yellow
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def online
|
55
|
+
if @vmrun.offline?
|
56
|
+
current_connection_type = @vmrun.connection_type
|
57
|
+
@config['online_connection_type'] ||= current_connection_type
|
58
|
+
|
59
|
+
if (@config['online_connection_type'] != current_connection_type)
|
60
|
+
# TODO handle missing connection type in saved config
|
61
|
+
question = "Reconfigure Micro Cloud Foundry VM network to #{@config['online_connection_type']} mode and reboot?"
|
62
|
+
if ask(question, :choices => ['y', 'n']) == 'y'
|
63
|
+
display "Rebooting Micro Cloud Foundry VM: ", false
|
64
|
+
@vmrun.connection_type = @config['online_connection_type']
|
65
|
+
@vmrun.reset
|
66
|
+
say "done".green
|
67
|
+
else
|
68
|
+
err "Aborted"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
display "Unsetting host DNS server: ", false
|
73
|
+
# TODO handle missing domain and ip in saved config (look at the VM)
|
74
|
+
@config['domain'] ||= @vmrun.domain
|
75
|
+
@config['ip'] ||= @vmrun.ip
|
76
|
+
unset_nameserver(@config['domain'], @config['ip'])
|
77
|
+
say "done".green
|
78
|
+
|
79
|
+
display "Setting Micro Cloud Foundry VM to online mode: ", false
|
80
|
+
@vmrun.online!
|
81
|
+
say "done".green
|
82
|
+
else
|
83
|
+
say "Micro Cloud Foundry already in online mode".yellow
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def status
|
88
|
+
mode = @vmrun.offline? ? 'offline' : 'online'
|
89
|
+
say "Micro Cloud Foundry VM currently in #{mode.green} mode"
|
90
|
+
# should the VMX path be unescaped?
|
91
|
+
say "VMX Path: #{@vmrun.vmx}"
|
92
|
+
say "Domain: #{@vmrun.domain.green}"
|
93
|
+
say "IP Address: #{@vmrun.ip.green}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module VMC::Micro::Switcher
|
2
|
+
|
3
|
+
class Darwin < Base
|
4
|
+
def adminrun(command)
|
5
|
+
VMC::Micro.run_command("osascript", "-e 'do shell script \"#{command}\" with administrator privileges'")
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_nameserver(domain, ip)
|
9
|
+
File.open("/tmp/#{domain}", 'w') { |file| file.write("nameserver #{ip}") }
|
10
|
+
adminrun("mkdir -p /etc/resolver;mv /tmp/#{domain} /etc/resolver/")
|
11
|
+
end
|
12
|
+
|
13
|
+
def unset_nameserver(domain, ip)
|
14
|
+
err "domain missing" unless domain
|
15
|
+
adminrun("rm -f /etc/resolver/#{domain}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VMC::Micro::Switcher
|
2
|
+
|
3
|
+
class Linux < Base
|
4
|
+
def set_nameserver(domain, ip)
|
5
|
+
VMC::Micro.run_command("sudo", "sed -i'.backup' '1 i nameserver #{ip}' /etc/resolv.conf")
|
6
|
+
# lock resolv.conf so Network Manager doesn't clear out the file when offline
|
7
|
+
VMC::Micro.run_command("sudo", "chattr +i /etc/resolv.conf")
|
8
|
+
end
|
9
|
+
|
10
|
+
def unset_nameserver(domain, ip)
|
11
|
+
VMC::Micro.run_command("sudo", "chattr -i /etc/resolv.conf")
|
12
|
+
VMC::Micro.run_command("sudo", "sed -i'.backup' '/#{ip}/d' /etc/resolv.conf")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VMC::Micro::Switcher
|
2
|
+
|
3
|
+
class Windows < Base
|
4
|
+
def version?
|
5
|
+
VMC::Micro.run_command("cmd", "/c ver").to_s.scan(/\d+\.\d+/).first.to_f
|
6
|
+
end
|
7
|
+
|
8
|
+
def adminrun(command, args=nil)
|
9
|
+
if version? > 5.2
|
10
|
+
require 'win32ole'
|
11
|
+
shell = WIN32OLE.new("Shell.Application")
|
12
|
+
shell.ShellExecute(command, args, nil, "runas", 0)
|
13
|
+
else
|
14
|
+
# on older version this will try to run the command, and if you don't have
|
15
|
+
# admin privilges it will tell you so and exit
|
16
|
+
VMC::Micro.run_command(command, args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO better method to figure out the interface name is to get the NAT ip and find the
|
21
|
+
# interface with the correct subnet
|
22
|
+
def set_nameserver(domain, ip)
|
23
|
+
adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static #{ip}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def unset_nameserver(domain, ip)
|
27
|
+
adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static none")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module VMC::Micro
|
2
|
+
class VMrun
|
3
|
+
attr_reader :vmx, :vmrun
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@platform = config['platform']
|
7
|
+
@user = 'root' # must use root as we muck around with system settings
|
8
|
+
@password = config['password']
|
9
|
+
@vmrun = config['vmrun']
|
10
|
+
@vmx = config['vmx']
|
11
|
+
|
12
|
+
# TODO honor TMPDIR
|
13
|
+
if @platform == :windows
|
14
|
+
@temp_dir = ENV['temp']
|
15
|
+
else
|
16
|
+
@temp_dir = '/tmp'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def connection_type
|
21
|
+
read_variable('ethernet0.connectionType')
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection_type=(type)
|
25
|
+
write_variable("ethernet0.connectionType", type)
|
26
|
+
end
|
27
|
+
|
28
|
+
def nat?
|
29
|
+
connection_type == "nat"
|
30
|
+
end
|
31
|
+
|
32
|
+
def bridged?
|
33
|
+
connection_type == "bridged"
|
34
|
+
end
|
35
|
+
|
36
|
+
def domain
|
37
|
+
# switch to Dir.mktmpdir
|
38
|
+
state_config = VMC::Micro.escape_path(File.join(@temp_dir, 'state.yml'))
|
39
|
+
run('CopyFileFromGuestToHost', "/var/vcap/bosh/state.yml #{state_config}")
|
40
|
+
bosh_config = YAML.load_file(state_config)
|
41
|
+
bosh_config['properties']['domain']
|
42
|
+
end
|
43
|
+
|
44
|
+
def ip
|
45
|
+
# switch to Dir.mktmpdir
|
46
|
+
path = VMC::Micro.escape_path(VMC::Micro.config_file('refresh_ip.rb'))
|
47
|
+
ip_file = VMC::Micro.escape_path(File.join(@temp_dir, 'ip.txt'))
|
48
|
+
run('CopyFileFromHostToGuest', "#{path} /tmp/refresh_ip.rb")
|
49
|
+
run('runProgramInGuest', '/tmp/refresh_ip.rb')
|
50
|
+
run('CopyFileFromGuestToHost', "/tmp/ip.txt #{ip_file}")
|
51
|
+
File.open(ip_file, 'r') { |file| file.read }
|
52
|
+
end
|
53
|
+
|
54
|
+
def list
|
55
|
+
vms = run("list")
|
56
|
+
vms.delete_if { |line| line =~ /^Total/ }
|
57
|
+
vms.map { |line| VMC::Micro.escape_path(File.expand_path(line)) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def offline?
|
61
|
+
command = "-gu #{@user} -gp #{@password} runProgramInGuest"
|
62
|
+
args = '/usr/bin/test -e /var/vcap/micro/offline'
|
63
|
+
# why not use run_command?
|
64
|
+
result = %x{#{@vmrun} #{command} #{@vmx} #{args}}
|
65
|
+
|
66
|
+
if result.include?('Guest program exited with non-zero exit code: 1')
|
67
|
+
return false
|
68
|
+
elsif $?.exitstatus == 0
|
69
|
+
return true
|
70
|
+
else
|
71
|
+
raise "failed to execute vmrun:\n#{result}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def offline!
|
76
|
+
path = VMC::Micro.escape_path(VMC::Micro.config_file('offline.conf'))
|
77
|
+
run('CopyFileFromHostToGuest', "#{path} /etc/dnsmasq.d/offline.conf")
|
78
|
+
run('runProgramInGuest', '/usr/bin/touch /var/vcap/micro/offline')
|
79
|
+
restart_dnsmasq
|
80
|
+
end
|
81
|
+
|
82
|
+
def online!
|
83
|
+
run('runProgramInGuest', '/bin/rm -f /etc/dnsmasq.d/offline.conf')
|
84
|
+
run('runProgramInGuest', '/bin/rm -f /var/vcap/micro/offline')
|
85
|
+
restart_dnsmasq
|
86
|
+
end
|
87
|
+
|
88
|
+
# check to see if the micro cloud has been configured
|
89
|
+
# uses default password to check
|
90
|
+
def ready?
|
91
|
+
command = "-gu root -gp 'ca$hc0w' runProgramInGuest"
|
92
|
+
args = '/usr/bin/test -e /var/vcap/micro/micro.json'
|
93
|
+
result = %x{#{@vmrun} #{command} #{@vmx} #{args}}
|
94
|
+
|
95
|
+
if result.include?('Invalid user name or password for the guest OS') || $?.exitstatus == 0
|
96
|
+
return true
|
97
|
+
elsif $?.exitstatus == 1
|
98
|
+
return false
|
99
|
+
else
|
100
|
+
raise "failed to execute vmrun:\n#{result}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def read_variable(var)
|
105
|
+
# TODO deal with non-ok return
|
106
|
+
run("readVariable", "runtimeConfig #{var}").first
|
107
|
+
end
|
108
|
+
|
109
|
+
def write_variable(var, value)
|
110
|
+
run('writeVariable', "runtimeConfig #{var} #{value}")
|
111
|
+
end
|
112
|
+
|
113
|
+
def reset
|
114
|
+
run('reset', 'soft')
|
115
|
+
end
|
116
|
+
|
117
|
+
def restart_dnsmasq
|
118
|
+
# restart command doesn't always work, start and stop seems to be more reliable
|
119
|
+
run('runProgramInGuest', '/etc/init.d/dnsmasq stop')
|
120
|
+
run('runProgramInGuest', '/etc/init.d/dnsmasq start')
|
121
|
+
end
|
122
|
+
|
123
|
+
def run(command, args=nil)
|
124
|
+
if command.include?('Guest')
|
125
|
+
command = "-gu #{@user} -gp #{@password} #{command}"
|
126
|
+
end
|
127
|
+
VMC::Micro.run_command(@vmrun, "#{command} #{@vmx} #{args}")
|
128
|
+
end
|
129
|
+
|
130
|
+
def running?
|
131
|
+
vms = list
|
132
|
+
if @platform == :windows
|
133
|
+
vms.map! { |x| x.downcase }
|
134
|
+
vms.include?(@vmx.downcase)
|
135
|
+
else
|
136
|
+
vms.include?(@vmx)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def start
|
141
|
+
run('start') unless running?
|
142
|
+
end
|
143
|
+
|
144
|
+
def stop
|
145
|
+
run('stop') if running?
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.locate(platform)
|
149
|
+
paths = YAML.load_file(VMC::Micro.config_file('paths.yml'))
|
150
|
+
vmrun_paths = paths[platform.to_s]['vmrun']
|
151
|
+
vmrun_exe = @platform == :windows ? 'vmrun.exe' : 'vmrun'
|
152
|
+
vmrun = VMC::Micro.locate_file(vmrun_exe, "VMware", vmrun_paths)
|
153
|
+
err "Unable to locate vmrun, please supply --vmrun option" unless vmrun
|
154
|
+
vmrun
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
data/lib/vmc/micro.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module VMC::Micro
|
4
|
+
def config_file(file)
|
5
|
+
File.join(File.dirname(__FILE__), '..', '..', 'config', 'micro', file)
|
6
|
+
end
|
7
|
+
|
8
|
+
def escape_path(path)
|
9
|
+
path = File.expand_path(path)
|
10
|
+
if RUBY_PLATFORM =~ /mingw|mswin32|cygwin/
|
11
|
+
if path.include?(' ')
|
12
|
+
return '"' + path + '"'
|
13
|
+
else
|
14
|
+
return path
|
15
|
+
end
|
16
|
+
else
|
17
|
+
return path.gsub(' ', '\ ')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def locate_file(file, directory, search_paths)
|
22
|
+
search_paths.each do |path|
|
23
|
+
expanded_path = File.expand_path(path)
|
24
|
+
if File.exists?(expanded_path)
|
25
|
+
Find.find(expanded_path) do |current|
|
26
|
+
if File.directory?(current) && current.include?(directory)
|
27
|
+
full_path = File.join(current, file)
|
28
|
+
return self.escape_path(full_path) if File.exists?(full_path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def run_command(command, args=nil)
|
38
|
+
# TODO switch to using posix-spawn instead
|
39
|
+
result = %x{#{command} #{args} 2>&1}
|
40
|
+
unless $?.exitstatus == 0
|
41
|
+
if block_given?
|
42
|
+
yield
|
43
|
+
else
|
44
|
+
raise "failed to execute #{command} #{args}:\n#{result}"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
result.split(/\n/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module_function :config_file
|
52
|
+
module_function :escape_path
|
53
|
+
module_function :locate_file
|
54
|
+
module_function :run_command
|
55
|
+
|
56
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: vmc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 7
|
5
|
-
version: 0.3.16.beta.
|
5
|
+
version: 0.3.16.beta.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- VMware
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-02
|
13
|
+
date: 2012-03-02 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -143,10 +143,14 @@ files:
|
|
143
143
|
- README.md
|
144
144
|
- Rakefile
|
145
145
|
- config/clients.yml
|
146
|
+
- config/micro/offline.conf
|
147
|
+
- config/micro/paths.yml
|
148
|
+
- config/micro/refresh_ip.rb
|
146
149
|
- lib/cli/commands/admin.rb
|
147
150
|
- lib/cli/commands/apps.rb
|
148
151
|
- lib/cli/commands/base.rb
|
149
152
|
- lib/cli/commands/manifest.rb
|
153
|
+
- lib/cli/commands/micro.rb
|
150
154
|
- lib/cli/commands/misc.rb
|
151
155
|
- lib/cli/commands/services.rb
|
152
156
|
- lib/cli/commands/user.rb
|
@@ -165,6 +169,13 @@ files:
|
|
165
169
|
- lib/cli.rb
|
166
170
|
- lib/vmc/client.rb
|
167
171
|
- lib/vmc/const.rb
|
172
|
+
- lib/vmc/micro/switcher/base.rb
|
173
|
+
- lib/vmc/micro/switcher/darwin.rb
|
174
|
+
- lib/vmc/micro/switcher/dummy.rb
|
175
|
+
- lib/vmc/micro/switcher/linux.rb
|
176
|
+
- lib/vmc/micro/switcher/windows.rb
|
177
|
+
- lib/vmc/micro/vmrun.rb
|
178
|
+
- lib/vmc/micro.rb
|
168
179
|
- lib/vmc.rb
|
169
180
|
- caldecott_helper/Gemfile
|
170
181
|
- caldecott_helper/Gemfile.lock
|