Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 9 commits
  • 26 files changed
  • 0 commit comments
  • 5 contributors
Commits on Feb 08, 2012
@vito vito find log files dynamically rather than guessing
Change-Id: I7dd07da7246d9872eb44c17c8d6ed2232be6b94c
235c773
Commits on Feb 23, 2012
@pmenglund pmenglund merge micro cloud helper into vmc
- limited number of tests
  as real testing require a running micro cloud and multiple OSes

Change-Id: I0dd150e8d9f00cdbc349a052f72d954a1f216d15
37a8839
Commits on Feb 24, 2012
Patrick Bozeman fix config dir entry in vmc gemspec
Change-Id: I27e5c83187cc2d31c9592dad0c49c13b07826842
85c5922
Commits on Feb 29, 2012
Jennifer Hickey Add Rack framework detection
Change-Id: I1039c8450640747b8f5edc7ba127d1bc2c65161d
be09fa3
@pmenglund pmenglund updated micro helper with linux support
Change-Id: Ib0d448ff135a834b5f943d13bd784fcf99117e8a
2052a7f
Commits on Mar 01, 2012
@pmenglund pmenglund Merge "updated micro helper with linux support" 475a479
Commits on Mar 02, 2012
Patrick Bozeman bump version to 0.3.16.beta.5
Change-Id: Ia76fd796d2a8ce8372ed4c24061dc1cfa7b2d8bb
b627c98
Patrick Bozeman Merge remote-tracking branch 'local-staging/master' 246e4c7
Commits on Apr 02, 2012
@stefanschneider Merge remote-tracking branch 'vmware/master'
Conflicts:
	lib/cli/frameworks.rb
	lib/cli/version.rb
6053c84
View
9 README.md
@@ -75,6 +75,15 @@ MIT license, please see the LICENSE file. All rights reserved._
runtimes Display the supported runtimes of the target system
frameworks Display the recognized frameworks of the target system
+ Micro Cloud Foundry
+ micro status Display Micro Cloud Foundry VM status
+ mciro offline Configure Micro Cloud Foundry VM for offline mode
+ micro online Configure Micro Cloud Foundry VM for online mode
+ [--vmx file] Path to micro.vmx
+ [--vmrun executable] Path to vmrun executable
+ [--password cleartext] Cleartext password for guest VM vcap user
+ [--save] Save cleartext password in ~/.vmc_micro
+
Misc
aliases List aliases
alias <alias[=]command> Create an alias for a command
View
2 config/micro/offline.conf
@@ -0,0 +1,2 @@
+no-resolv
+log-queries
View
22 config/micro/paths.yml
@@ -0,0 +1,22 @@
+darwin:
+ vmrun:
+ - "/Applications/VMware Fusion.app/Contents/Library/"
+ - "/Applications/Fusion.app/Contents/Library/"
+ vmx:
+ - "~/Documents/Virtual Machines.localized/"
+ - "~/Documents/Virtual Machines/"
+ - "~/Desktop/"
+
+linux:
+ vmrun:
+ - "/usr/bin/"
+ vmx:
+ - "~/"
+
+windows:
+ vmrun:
+ - "c:\\Program Files (x86)\\"
+ - "c:\\Program Files\\"
+ vmx:
+ - "~\\Documents\\"
+ - "~\\Desktop\\"
View
20 config/micro/refresh_ip.rb
@@ -0,0 +1,20 @@
+#!/var/vcap/bosh/bin/ruby
+require 'socket'
+
+A_ROOT_SERVER = '198.41.0.4'
+
+begin
+retries ||= 0
+route ||= A_ROOT_SERVER
+orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
+ip_address = UDPSocket.open {|s| s.connect(route, 1); s.addr.last }
+rescue Errno::ENETUNREACH
+ # happens on boot when dhcp hasn't completed when we get here
+ sleep 3
+ retries += 1
+ retry if retries < 10
+ensure
+ Socket.do_not_reverse_lookup = orig
+end
+
+File.open("/tmp/ip.txt", 'w') { |file| file.write(ip_address) }
View
15 lib/cli.rb
@@ -4,6 +4,18 @@
module VMC
autoload :Client, "#{ROOT}/vmc/client"
+ autoload :Micro, "#{ROOT}/vmc/micro"
+
+ module Micro
+ module Switcher
+ autoload :Base, "#{ROOT}/vmc/micro/switcher/base"
+ autoload :Darwin, "#{ROOT}/vmc/micro/switcher/darwin"
+ autoload :Dummy, "#{ROOT}/vmc/micro/switcher/dummy"
+ autoload :Linux, "#{ROOT}/vmc/micro/switcher/linux"
+ autoload :Windows, "#{ROOT}/vmc/micro/switcher/windows"
+ end
+ autoload :VMrun, "#{ROOT}/vmc/micro/vmrun"
+ end
module Cli
autoload :Config, "#{ROOT}/cli/config"
@@ -13,12 +25,13 @@ module Cli
autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
autoload :ManifestHelper, "#{ROOT}/cli/manifest_helper"
- autoload :ConsoleHelper, "#{ROOT}/cli/console_helper"
+ autoload :ConsoleHelper, "#{ROOT}/cli/console_helper"
module Command
autoload :Base, "#{ROOT}/cli/commands/base"
autoload :Admin, "#{ROOT}/cli/commands/admin"
autoload :Apps, "#{ROOT}/cli/commands/apps"
+ autoload :Micro, "#{ROOT}/cli/commands/micro"
autoload :Misc, "#{ROOT}/cli/commands/misc"
autoload :Services, "#{ROOT}/cli/commands/services"
autoload :User, "#{ROOT}/cli/commands/user"
View
37 lib/cli/commands/apps.rb
@@ -193,7 +193,7 @@ def files(appname, path='/')
instance = @options[:instance] || '0'
content = client.app_files(appname, path, instance)
display content
- rescue VMC::Client::TargetError
+ rescue VMC::Client::NotFound, VMC::Client::TargetError
err 'No such file or directory'
end
@@ -675,10 +675,6 @@ def display_logfile(path, content, instance='0', banner=nil)
end
end
- def log_file_paths
- %w[logs/stderr.log logs/stdout.log logs/startup.log]
- end
-
def grab_all_logs(appname)
instances_info_envelope = client.app_instances(appname)
return if instances_info_envelope.is_a?(Array)
@@ -689,15 +685,23 @@ def grab_all_logs(appname)
end
def grab_logs(appname, instance)
- log_file_paths.each do |path|
+ files_under(appname, instance, "/logs").each do |path|
begin
content = client.app_files(appname, path, instance)
display_logfile(path, content, instance)
- rescue VMC::Client::TargetError
+ rescue VMC::Client::NotFound, VMC::Client::TargetError
end
end
end
+ def files_under(appname, instance, path)
+ client.app_files(appname, path, instance).split("\n").collect do |l|
+ "#{path}/#{l.split[0]}"
+ end
+ rescue VMC::Client::NotFound, VMC::Client::TargetError
+ []
+ end
+
def grab_crash_logs(appname, instance, was_staged=false)
# stage crash info
crashes(appname, false) unless was_staged
@@ -706,16 +710,11 @@ def grab_crash_logs(appname, instance, was_staged=false)
map = VMC::Cli::Config.instances
instance = map[instance] if map[instance]
- %w{
- /logs/err.log /logs/staging.log /logs/migration.log
- /app/logs/stderr.log /app/logs/stdout.log /app/logs/startup.log
- /app/logs/migration.log
- }.each do |path|
- begin
- content = client.app_files(appname, path, instance)
- display_logfile(path, content, instance)
- rescue VMC::Client::TargetError
- end
+ (files_under(appname, instance, "/logs") +
+ files_under(appname, instance, "/app/logs") +
+ files_under(appname, instance, "/app/log")).each do |path|
+ content = client.app_files(appname, path, instance)
+ display_logfile(path, content, instance)
end
end
@@ -732,7 +731,7 @@ def grab_startup_tail(appname, since = 0)
display tail.join("\n") if new_lines > 0
end
since + new_lines
- rescue VMC::Client::TargetError
+ rescue VMC::Client::NotFound, VMC::Client::TargetError
0
end
@@ -1064,7 +1063,7 @@ def all_files(appname, path)
entry[:index],
"====> [#{entry[:index]}: #{path}] <====\n".bold
)
- rescue VMC::Client::TargetError
+ rescue VMC::Client::NotFound, VMC::Client::TargetError
end
end
end
View
115 lib/cli/commands/micro.rb
@@ -0,0 +1,115 @@
+module VMC::Cli::Command
+ class Micro < Base
+
+ def initialize(args)
+ super(args)
+ end
+
+ def offline(mode)
+ command('offline')
+ end
+
+ def online(mode)
+ command('online')
+ end
+
+ def status(mode)
+ command('status')
+ end
+
+ def command(cmd)
+ config = build_config
+ switcher(config).send(cmd)
+ store_config(config)
+ end
+
+ def switcher(config)
+ case Micro.platform
+ when :darwin
+ switcher = VMC::Micro::Switcher::Darwin.new(config)
+ when :linux
+ switcher = VMC::Micro::Switcher::Linux.new(config)
+ when :windows
+ switcher = VMC::Micro::Switcher::Windows.new(config)
+ when :dummy # for testing only
+ switcher = VMC::Micro::Switcher::Dummy.new(config)
+ else
+ err "unsupported platform: #{Micro.platform}"
+ end
+ end
+
+ # Returns the configuration needed to run the micro related subcommands.
+ # First loads saved config from file (if there is any), then overrides
+ # loaded values with command line arguments, and finally tries to guess
+ # in case neither was used:
+ # vmx location of micro.vmx file
+ # vmrun location of vmrun command
+ # password password for vcap user (in the guest vm)
+ # platform current platform
+ def build_config
+ conf = VMC::Cli::Config.micro # returns {} if there isn't a saved config
+
+ override(conf, 'vmx', true) do
+ locate_vmx(Micro.platform)
+ end
+
+ override(conf, 'vmrun', true) do
+ VMC::Micro::VMrun.locate(Micro.platform)
+ end
+
+ override(conf, 'password') do
+ @password = ask("Please enter your Micro Cloud Foundry VM password (vcap user) password", :echo => "*")
+ end
+
+ conf['platform'] = Micro.platform
+
+ conf
+ end
+
+ # Save the cleartext password if --save is supplied.
+ # Note: it is due to vix we have to use a cleartext password :(
+ # Only if --password is used and not --save is the password deleted from the
+ # config file before it is stored to disk.
+ def store_config(config)
+ if @options[:save]
+ warn("cleartext password saved in: #{VMC::Cli::Config::MICRO_FILE}")
+ elsif @options[:password] || @password
+ config.delete('password')
+ end
+
+ VMC::Cli::Config.store_micro(config)
+ end
+
+ # override with command line arguments and yield the block in case the option isn't set
+ def override(config, option, escape=false, &blk)
+ # override if given on the command line
+ if opt = @options[option.to_sym]
+ opt = VMC::Micro.escape_path(opt) if escape
+ config[option] = opt
+ end
+ config[option] = yield unless config[option]
+ end
+
+ def locate_vmx(platform)
+ paths = YAML.load_file(VMC::Micro.config_file('paths.yml'))
+ vmx_paths = paths[platform.to_s]['vmx']
+ vmx = VMC::Micro.locate_file('micro.vmx', 'micro', vmx_paths)
+ err "Unable to locate micro.vmx, please supply --vmx option" unless vmx
+ vmx
+ end
+
+ def self.platform
+ case RUBY_PLATFORM
+ when /darwin/ # x86_64-darwin11.2.0
+ :darwin
+ when /linux/ # x86_64-linux
+ :linux
+ when /mingw|mswin32|cygwin/ # i386-mingw32
+ :windows
+ else
+ RUBY_PLATFORM
+ end
+ end
+
+ end
+end
View
13 lib/cli/config.rb
@@ -14,6 +14,7 @@ class Config
INSTANCES_FILE = '~/.vmc_instances'
ALIASES_FILE = '~/.vmc_aliases'
CLIENTS_FILE = '~/.vmc_clients'
+ MICRO_FILE = '~/.vmc_micro'
STOCK_CLIENTS = File.expand_path("../../../config/clients.yml", __FILE__)
@@ -102,6 +103,18 @@ def store_aliases(aliases)
File.open(aliases_file, 'wb') {|f| f.write(aliases.to_yaml)}
end
+ def micro
+ micro_file = File.expand_path(MICRO_FILE)
+ return {} unless File.exists? micro_file
+ contents = lock_and_read(micro_file).strip
+ JSON.parse(contents)
+ end
+
+ def store_micro(micro)
+ micro_file = File.expand_path(MICRO_FILE)
+ lock_and_write(micro_file, micro.to_json)
+ end
+
def deep_merge(a, b)
merge = proc do |_, old, new|
if new.is_a?(Hash) and old.is_a?(Hash)
View
8 lib/cli/frameworks.rb
@@ -18,6 +18,7 @@ class Framework
'WSGI' => ['wsgi', { :mem => '64M', :description => 'Python WSGI Application'}],
'Django' => ['django', { :mem => '128M', :description => 'Python Django Application'}],
'dotNet' => ['dotNet', { :mem => '128M', :description => '.Net Web Application'}],
+ 'Rack' => ['rack', { :mem => '128M', :description => 'Rack Application'}]
}
class << self
@@ -36,13 +37,16 @@ def lookup_by_framework(name)
end
end
- def detect(path)
+ def detect(path, available_frameworks)
Dir.chdir(path) do
-
# Rails
if File.exist?('config/environment.rb')
return Framework.lookup('Rails')
+ # Rack
+ elsif File.exist?('config.ru') && available_frameworks.include?(["rack"])
+ return Framework.lookup('Rack')
+
# Java
elsif Dir.glob('*.war').first || File.exist?('WEB-INF/web.xml')
war_file = Dir.glob('*.war').first
View
2 lib/cli/manifest_helper.rb
@@ -165,7 +165,7 @@ def set(what, *where)
# Detect the appropriate framework.
def detect_framework(prompt_ok = true)
- framework = VMC::Cli::Framework.detect(@application)
+ framework = VMC::Cli::Framework.detect(@application, frameworks_info)
framework_correct = ask("Detected a #{framework}, is this correct?", :default => true) if prompt_ok && framework
if prompt_ok && (framework.nil? || !framework_correct)
display "#{"[WARNING]".yellow} Can't determine the Application Type." unless framework
View
11 lib/cli/runner.rb
@@ -59,6 +59,11 @@ def parse_options!
opts.on('-q', '--quiet') { @options[:quiet] = true }
+ # micro cloud options
+ opts.on('--vmx FILE') { |file| @options[:vmx] = file }
+ opts.on('--vmrun FILE') { |file| @options[:vmrun] = file }
+ opts.on('--save') { @options[:save] = true }
+
# Don't use builtin zip
opts.on('--no-zip') { @options[:nozip] = true }
opts.on('--nozip') { @options[:nozip] = true }
@@ -380,6 +385,12 @@ def parse_command!
usage('vmc rails-console <appname>')
set_cmd(:apps, :console, 1)
+ when 'micro'
+ usage('vmc micro <online|offline|status> [--password password] [--save] [--vmx file] [--vmrun executable]')
+ if %w[online offline status].include?(@args[0])
+ set_cmd(:micro, @args[0].to_sym, 1)
+ end
+
when 'help'
display_help if @args.size == 0
@help_only = true
View
9 lib/cli/usage.rb
@@ -91,6 +91,15 @@ def command_usage
runtimes Display the supported runtimes of the target system
frameworks Display the recognized frameworks of the target system
+ Micro Cloud Foundry
+ micro status Display Micro Cloud Foundry VM status
+ micro offline Configure Micro Cloud Foundry VM for offline mode
+ micro online Configure Micro Cloud Foundry VM for online mode
+ [--vmx file] Path to micro.vmx
+ [--vmrun executable] Path to vmrun executable
+ [--password cleartext] Cleartext password for guest VM vcap user
+ [--save] Save cleartext password in ~/.vmc_micro
+
Misc
aliases List aliases
alias <alias[=]command> Create an alias for a command
View
2 lib/cli/version.rb
@@ -2,6 +2,6 @@ module VMC
module Cli
# This version number is used as the RubyGem release version.
# The internal VMC version number is VMC::VERSION.
- VERSION = '0.3.15.1'
+ VERSION = '0.3.16.beta.5'
end
end
View
56 lib/vmc/micro.rb
@@ -0,0 +1,56 @@
+require 'find'
+
+module VMC::Micro
+ def config_file(file)
+ File.join(File.dirname(__FILE__), '..', '..', 'config', 'micro', file)
+ end
+
+ def escape_path(path)
+ path = File.expand_path(path)
+ if RUBY_PLATFORM =~ /mingw|mswin32|cygwin/
+ if path.include?(' ')
+ return '"' + path + '"'
+ else
+ return path
+ end
+ else
+ return path.gsub(' ', '\ ')
+ end
+ end
+
+ def locate_file(file, directory, search_paths)
+ search_paths.each do |path|
+ expanded_path = File.expand_path(path)
+ if File.exists?(expanded_path)
+ Find.find(expanded_path) do |current|
+ if File.directory?(current) && current.include?(directory)
+ full_path = File.join(current, file)
+ return self.escape_path(full_path) if File.exists?(full_path)
+ end
+ end
+ end
+ end
+
+ false
+ end
+
+ def run_command(command, args=nil)
+ # TODO switch to using posix-spawn instead
+ result = %x{#{command} #{args} 2>&1}
+ unless $?.exitstatus == 0
+ if block_given?
+ yield
+ else
+ raise "failed to execute #{command} #{args}:\n#{result}"
+ end
+ else
+ result.split(/\n/)
+ end
+ end
+
+ module_function :config_file
+ module_function :escape_path
+ module_function :locate_file
+ module_function :run_command
+
+end
View
97 lib/vmc/micro/switcher/base.rb
@@ -0,0 +1,97 @@
+require 'interact'
+
+module VMC::Micro::Switcher
+ class Base
+ include Interactive
+
+ def initialize(config)
+ @config = config
+
+ @vmrun = VMC::Micro::VMrun.new(config)
+ unless @vmrun.running?
+ if ask("Micro Cloud Foundry VM is not running. Do you want to start it?", :choices => ['y', 'n']) == 'y'
+ display "Starting Micro Cloud Foundry VM: ", false
+ @vmrun.start
+ say "done".green
+ else
+ err "Micro Cloud Foundry VM needs to be running."
+ end
+ end
+
+ err "Micro Cloud Foundry VM initial setup needs to be completed before using 'vmc micro'" unless @vmrun.ready?
+ end
+
+ def offline
+ unless @vmrun.offline?
+ # save online connection type so we can restore it later
+ @config['online_connection_type'] = @vmrun.connection_type
+
+ if (@config['online_connection_type'] != 'nat')
+ if ask("Reconfigure Micro Cloud Foundry VM network to nat mode and reboot?", :choices => ['y', 'n']) == 'y'
+ display "Rebooting Micro Cloud Foundry VM: ", false
+ @vmrun.connection_type = 'nat'
+ @vmrun.reset
+ say "done".green
+ else
+ err "Aborted"
+ end
+ end
+
+ display "Setting Micro Cloud Foundry VM to offline mode: ", false
+ @vmrun.offline!
+ say "done".green
+ display "Setting host DNS server: ", false
+
+ @config['domain'] = @vmrun.domain
+ @config['ip'] = @vmrun.ip
+ set_nameserver(@config['domain'], @config['ip'])
+ say "done".green
+ else
+ say "Micro Cloud Foundry VM already in offline mode".yellow
+ end
+ end
+
+ def online
+ if @vmrun.offline?
+ current_connection_type = @vmrun.connection_type
+ @config['online_connection_type'] ||= current_connection_type
+
+ if (@config['online_connection_type'] != current_connection_type)
+ # TODO handle missing connection type in saved config
+ question = "Reconfigure Micro Cloud Foundry VM network to #{@config['online_connection_type']} mode and reboot?"
+ if ask(question, :choices => ['y', 'n']) == 'y'
+ display "Rebooting Micro Cloud Foundry VM: ", false
+ @vmrun.connection_type = @config['online_connection_type']
+ @vmrun.reset
+ say "done".green
+ else
+ err "Aborted"
+ end
+ end
+
+ display "Unsetting host DNS server: ", false
+ # TODO handle missing domain and ip in saved config (look at the VM)
+ @config['domain'] ||= @vmrun.domain
+ @config['ip'] ||= @vmrun.ip
+ unset_nameserver(@config['domain'], @config['ip'])
+ say "done".green
+
+ display "Setting Micro Cloud Foundry VM to online mode: ", false
+ @vmrun.online!
+ say "done".green
+ else
+ say "Micro Cloud Foundry already in online mode".yellow
+ end
+ end
+
+ def status
+ mode = @vmrun.offline? ? 'offline' : 'online'
+ say "Micro Cloud Foundry VM currently in #{mode.green} mode"
+ # should the VMX path be unescaped?
+ say "VMX Path: #{@vmrun.vmx}"
+ say "Domain: #{@vmrun.domain.green}"
+ say "IP Address: #{@vmrun.ip.green}"
+ end
+ end
+
+end
View
19 lib/vmc/micro/switcher/darwin.rb
@@ -0,0 +1,19 @@
+module VMC::Micro::Switcher
+
+ class Darwin < Base
+ def adminrun(command)
+ VMC::Micro.run_command("osascript", "-e 'do shell script \"#{command}\" with administrator privileges'")
+ end
+
+ def set_nameserver(domain, ip)
+ File.open("/tmp/#{domain}", 'w') { |file| file.write("nameserver #{ip}") }
+ adminrun("mkdir -p /etc/resolver;mv /tmp/#{domain} /etc/resolver/")
+ end
+
+ def unset_nameserver(domain, ip)
+ err "domain missing" unless domain
+ adminrun("rm -f /etc/resolver/#{domain}")
+ end
+ end
+
+end
View
15 lib/vmc/micro/switcher/dummy.rb
@@ -0,0 +1,15 @@
+# only used for testing
+module VMC::Micro::Switcher
+
+ class Dummy < Base
+ def adminrun(command)
+ end
+
+ def set_nameserver(domain, ip)
+ end
+
+ def unset_nameserver(domain, ip)
+ end
+ end
+
+end
View
16 lib/vmc/micro/switcher/linux.rb
@@ -0,0 +1,16 @@
+module VMC::Micro::Switcher
+
+ class Linux < Base
+ def set_nameserver(domain, ip)
+ VMC::Micro.run_command("sudo", "sed -i'.backup' '1 i nameserver #{ip}' /etc/resolv.conf")
+ # lock resolv.conf so Network Manager doesn't clear out the file when offline
+ VMC::Micro.run_command("sudo", "chattr +i /etc/resolv.conf")
+ end
+
+ def unset_nameserver(domain, ip)
+ VMC::Micro.run_command("sudo", "chattr -i /etc/resolv.conf")
+ VMC::Micro.run_command("sudo", "sed -i'.backup' '/#{ip}/d' /etc/resolv.conf")
+ end
+ end
+
+end
View
31 lib/vmc/micro/switcher/windows.rb
@@ -0,0 +1,31 @@
+module VMC::Micro::Switcher
+
+ class Windows < Base
+ def version?
+ VMC::Micro.run_command("cmd", "/c ver").to_s.scan(/\d+\.\d+/).first.to_f
+ end
+
+ def adminrun(command, args=nil)
+ if version? > 5.2
+ require 'win32ole'
+ shell = WIN32OLE.new("Shell.Application")
+ shell.ShellExecute(command, args, nil, "runas", 0)
+ else
+ # on older version this will try to run the command, and if you don't have
+ # admin privilges it will tell you so and exit
+ VMC::Micro.run_command(command, args)
+ end
+ end
+
+ # TODO better method to figure out the interface name is to get the NAT ip and find the
+ # interface with the correct subnet
+ def set_nameserver(domain, ip)
+ adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static #{ip}")
+ end
+
+ def unset_nameserver(domain, ip)
+ adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static none")
+ end
+ end
+
+end
View
158 lib/vmc/micro/vmrun.rb
@@ -0,0 +1,158 @@
+module VMC::Micro
+ class VMrun
+ attr_reader :vmx, :vmrun
+
+ def initialize(config)
+ @platform = config['platform']
+ @user = 'root' # must use root as we muck around with system settings
+ @password = config['password']
+ @vmrun = config['vmrun']
+ @vmx = config['vmx']
+
+ # TODO honor TMPDIR
+ if @platform == :windows
+ @temp_dir = ENV['temp']
+ else
+ @temp_dir = '/tmp'
+ end
+ end
+
+ def connection_type
+ read_variable('ethernet0.connectionType')
+ end
+
+ def connection_type=(type)
+ write_variable("ethernet0.connectionType", type)
+ end
+
+ def nat?
+ connection_type == "nat"
+ end
+
+ def bridged?
+ connection_type == "bridged"
+ end
+
+ def domain
+ # switch to Dir.mktmpdir
+ state_config = VMC::Micro.escape_path(File.join(@temp_dir, 'state.yml'))
+ run('CopyFileFromGuestToHost', "/var/vcap/bosh/state.yml #{state_config}")
+ bosh_config = YAML.load_file(state_config)
+ bosh_config['properties']['domain']
+ end
+
+ def ip
+ # switch to Dir.mktmpdir
+ path = VMC::Micro.escape_path(VMC::Micro.config_file('refresh_ip.rb'))
+ ip_file = VMC::Micro.escape_path(File.join(@temp_dir, 'ip.txt'))
+ run('CopyFileFromHostToGuest', "#{path} /tmp/refresh_ip.rb")
+ run('runProgramInGuest', '/tmp/refresh_ip.rb')
+ run('CopyFileFromGuestToHost', "/tmp/ip.txt #{ip_file}")
+ File.open(ip_file, 'r') { |file| file.read }
+ end
+
+ def list
+ vms = run("list")
+ vms.delete_if { |line| line =~ /^Total/ }
+ vms.map { |line| VMC::Micro.escape_path(File.expand_path(line)) }
+ end
+
+ def offline?
+ command = "-gu #{@user} -gp #{@password} runProgramInGuest"
+ args = '/usr/bin/test -e /var/vcap/micro/offline'
+ # why not use run_command?
+ result = %x{#{@vmrun} #{command} #{@vmx} #{args}}
+
+ if result.include?('Guest program exited with non-zero exit code: 1')
+ return false
+ elsif $?.exitstatus == 0
+ return true
+ else
+ raise "failed to execute vmrun:\n#{result}"
+ end
+ end
+
+ def offline!
+ path = VMC::Micro.escape_path(VMC::Micro.config_file('offline.conf'))
+ run('CopyFileFromHostToGuest', "#{path} /etc/dnsmasq.d/offline.conf")
+ run('runProgramInGuest', '/usr/bin/touch /var/vcap/micro/offline')
+ restart_dnsmasq
+ end
+
+ def online!
+ run('runProgramInGuest', '/bin/rm -f /etc/dnsmasq.d/offline.conf')
+ run('runProgramInGuest', '/bin/rm -f /var/vcap/micro/offline')
+ restart_dnsmasq
+ end
+
+ # check to see if the micro cloud has been configured
+ # uses default password to check
+ def ready?
+ command = "-gu root -gp 'ca$hc0w' runProgramInGuest"
+ args = '/usr/bin/test -e /var/vcap/micro/micro.json'
+ result = %x{#{@vmrun} #{command} #{@vmx} #{args}}
+
+ if result.include?('Invalid user name or password for the guest OS') || $?.exitstatus == 0
+ return true
+ elsif $?.exitstatus == 1
+ return false
+ else
+ raise "failed to execute vmrun:\n#{result}"
+ end
+ end
+
+ def read_variable(var)
+ # TODO deal with non-ok return
+ run("readVariable", "runtimeConfig #{var}").first
+ end
+
+ def write_variable(var, value)
+ run('writeVariable', "runtimeConfig #{var} #{value}")
+ end
+
+ def reset
+ run('reset', 'soft')
+ end
+
+ def restart_dnsmasq
+ # restart command doesn't always work, start and stop seems to be more reliable
+ run('runProgramInGuest', '/etc/init.d/dnsmasq stop')
+ run('runProgramInGuest', '/etc/init.d/dnsmasq start')
+ end
+
+ def run(command, args=nil)
+ if command.include?('Guest')
+ command = "-gu #{@user} -gp #{@password} #{command}"
+ end
+ VMC::Micro.run_command(@vmrun, "#{command} #{@vmx} #{args}")
+ end
+
+ def running?
+ vms = list
+ if @platform == :windows
+ vms.map! { |x| x.downcase }
+ vms.include?(@vmx.downcase)
+ else
+ vms.include?(@vmx)
+ end
+ end
+
+ def start
+ run('start') unless running?
+ end
+
+ def stop
+ run('stop') if running?
+ end
+
+ def self.locate(platform)
+ paths = YAML.load_file(VMC::Micro.config_file('paths.yml'))
+ vmrun_paths = paths[platform.to_s]['vmrun']
+ vmrun_exe = @platform == :windows ? 'vmrun.exe' : 'vmrun'
+ vmrun = VMC::Micro.locate_file(vmrun_exe, "VMware", vmrun_paths)
+ err "Unable to locate vmrun, please supply --vmrun option" unless vmrun
+ vmrun
+ end
+ end
+
+end
2 spec/assets/tests
@@ -1 +1 @@
-Subproject commit 44d962ba028e5c76eeb2bd4bd8ee6311241a194a
+Subproject commit 6a32f9c4faa99385a32d7b5d3529a0ac446100a6
View
16 spec/unit/frameworks_spec.rb
@@ -71,19 +71,29 @@
framework(app).should =~ /Sinatra/
end
+ it 'should be able to detect a Rack app' do
+ app = spec_asset('tests/rack/app_rack_service')
+ framework(app,false,[["rack"]]).should =~ /Rack/
+ end
+
+ it 'should fall back to Sinatra detection if Rack framework not supported' do
+ app = spec_asset('tests/rack/app_rack_service')
+ framework(app,false).should =~ /Sinatra/
+ end
+
it 'should be able to detect a Node.js app' do
app = spec_asset('tests/node/hello_vcap')
framework(app).should=~ /Node.js/
end
- def framework app, explode=false
+ def framework app, explode=false, available_frameworks=[]
unless explode == true
- return VMC::Cli::Framework.detect(app).to_s
+ return VMC::Cli::Framework.detect(app, available_frameworks).to_s
end
Dir.mktmpdir {|dir|
exploded_dir = File.join(dir, "exploded")
VMC::Cli::ZipUtil.unpack(app, exploded_dir)
- VMC::Cli::Framework.detect(exploded_dir).to_s
+ VMC::Cli::Framework.detect(exploded_dir, available_frameworks).to_s
}
end
View
34 spec/unit/micro_cmd_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe VMC::Cli::Command::Micro do
+ VMRUN = "/path/to/vmrun"
+ VMX = "/path/to/micro.vmx"
+ PASSWORD = "password"
+
+ describe "#build_config" do
+ it "should ask for info when the config is empty" do
+ VMC::Cli::Config.should_receive(:micro).and_return({})
+ cmd = VMC::Cli::Command::Micro.new({})
+
+ cmd.should_receive(:locate_vmx).and_return(VMX)
+ VMC::Micro::VMrun.should_receive(:locate).and_return(VMRUN)
+ cmd.should_receive(:ask).and_return(PASSWORD)
+
+ config = cmd.build_config
+ config['vmx'].should == VMX
+ config['vmrun'].should == VMRUN
+ config['password'].should == PASSWORD
+ end
+
+ it "should override stored config with command line arguments" do
+ VMC::Cli::Config.should_receive(:micro).and_return({})
+ options = {:password => PASSWORD, :vmx => VMX, :vmrun => VMRUN}
+ cmd = VMC::Cli::Command::Micro.new(options)
+
+ config = cmd.build_config
+ config['vmx'].should == VMX
+ config['vmrun'].should == VMRUN
+ config['password'].should == PASSWORD
+ end
+ end
+end
View
22 spec/unit/switcher_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe VMC::Micro::Switcher::Base do
+ it "should go online" do
+ vmrun = double(VMC::Micro::VMrun)
+ vmrun.should_receive(:running?).and_return(true)
+ vmrun.should_receive(:ready?).and_return(true)
+ vmrun.should_receive(:offline?).and_return(false)
+ VMC::Micro::VMrun.should_receive(:new).and_return(vmrun)
+ switcher = VMC::Micro::Switcher::Dummy.new({})
+ switcher.online
+ end
+ it "should go offline" do
+ vmrun = double(VMC::Micro::VMrun)
+ vmrun.should_receive(:running?).and_return(true)
+ vmrun.should_receive(:ready?).and_return(true)
+ vmrun.should_receive(:offline?).and_return(true)
+ VMC::Micro::VMrun.should_receive(:new).and_return(vmrun)
+ switcher = VMC::Micro::Switcher::Dummy.new({})
+ switcher.offline
+ end
+end
View
23 spec/unit/vmrun_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe VMC::Micro::VMrun do
+
+ before(:all) do
+ platform = VMC::Cli::Command::Micro.platform
+ @config = {'platform' => platform, 'password' => 'pass', 'vmrun' => 'vmrun', 'vmx' => 'vmx'}
+ end
+
+ it "should list all VMs running" do
+ v = VMC::Micro::VMrun.new(@config)
+ v.should_receive(:run).and_return(["Total ...", "/foo.vmx", "/bar.vmx"])
+ v.list.should == ["/foo.vmx", "/bar.vmx"]
+ end
+
+ describe "connection type" do
+ it "should list the connection type" do
+ vmrun = VMC::Micro::VMrun.new(@config)
+ vmrun.should_receive(:run).and_return(["bridged"])
+ vmrun.connection_type == "bridged"
+ end
+ end
+end
View
2 vmc.gemspec
@@ -29,5 +29,5 @@ spec = Gem::Specification.new do |s|
s.bindir = "bin"
s.require_path = 'lib'
- s.files = %w(LICENSE README.md Rakefile config/clients.yml) + Dir.glob("{lib,caldecott_helper}/**/*")
+ s.files = %w(LICENSE README.md Rakefile) + Dir.glob("{config,lib,caldecott_helper}/**/*")
end

No commit comments for this range

Something went wrong with that request. Please try again.