cf 4.0.1.rc2 → 4.1.0rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3f7db873a3433f6a41a5b6b2373560e6638651e2
4
+ data.tar.gz: ee5511a3f2188b76047fe98e7d5b40de804e36da
5
+ SHA512:
6
+ metadata.gz: e587cae8a1feef4fc85c5ab0f691449d692376c5c16ebe587a75afa3cdd4deed45227cdda180947d7103d431dd35eb068ac8e3ceaa4891d3e5222be6cac61a56
7
+ data.tar.gz: 1f6e73117e955a892551126c3c52069a9856e8d5aa2ce2e122fc061d6cc66d6f2bd65d253956671f6780cb898c347e2ca1a90289021df2453b59805130ccd60f
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "rake"
2
2
  require "rspec/core/rake_task"
3
+ Dir.glob("lib/tasks/**/*").sort.each { |ext| load(ext) }
3
4
 
4
5
  specfile, _ = Dir["*.gemspec"]
5
6
  SPEC = Gem::Specification.load(specfile)
data/lib/cf.rb CHANGED
@@ -11,3 +11,4 @@ require "admin/plugin"
11
11
  require "console/plugin"
12
12
  require "tunnel/plugin"
13
13
  require "manifests/plugin"
14
+ require "micro/plugin"
@@ -14,6 +14,7 @@ require "cf/spacing"
14
14
 
15
15
  require "cf/cli/help"
16
16
  require "cf/cli/interactive"
17
+ require "cf/cli/login_requirements"
17
18
 
18
19
 
19
20
  $cf_asked_auth = false
@@ -72,6 +73,7 @@ module CF
72
73
  end
73
74
 
74
75
  def check_logged_in
76
+ check_target
75
77
  unless client.logged_in?
76
78
  if force?
77
79
  fail "Please log in with 'cf login'."
@@ -84,17 +86,42 @@ module CF
84
86
  end
85
87
  end
86
88
 
87
- def precondition
88
- check_target
89
- check_logged_in
89
+ desc "Help!"
90
+ input :command, :argument => :optional
91
+ input :all, :type => :boolean
92
+ def help
93
+ if name = input[:command]
94
+ if cmd = @@commands[name.gsub("-", "_").to_sym]
95
+ Mothership::Help.command_help(cmd)
96
+ else
97
+ unknown_command(name)
98
+ end
99
+ elsif Help.has_groups?
100
+ unless input[:all]
101
+ puts "#{help_header}"
102
+ end
90
103
 
91
- unless client.current_organization
92
- fail "Please select an organization with 'cf target --organization ORGANIZATION_NAME'. (Get organization names from 'cf orgs'.)"
104
+ Mothership::Help.print_help_groups(@@global, input[:all])
105
+ else
106
+ Mothership::Help.basic_help(@@commands, @@global)
93
107
  end
108
+ end
94
109
 
95
- unless client.current_space
96
- fail "Please select a space with 'cf target --space SPACE_NAME'. (Get space names from 'cf spaces'.)"
97
- end
110
+ def help_header
111
+ <<EOS
112
+ Cloud Foundry Command Line Interface, version [#{CF::VERSION}]
113
+ Showing basic commands. Use 'cf help --all' to list all commands, or
114
+ 'cf help [command]' for help detailed help on a command.
115
+
116
+ For docs and support visit http://support.cloudfoundry.com
117
+
118
+ USAGE EXAMPLES
119
+ $ cf target api.run.pivotal.io <-- sets target API endpoint (the CF instance where you want to push apps) to 'api.run.pivotal.io'
120
+ $ cf login <-- logs into currently targeted CF instance, will also prompt for target org and app space
121
+ $ cf push <-- deploys app to current target
122
+ $ cf target -s staging <-- changes currently targeted app space to 'staging'
123
+
124
+ EOS
98
125
  end
99
126
 
100
127
  def wrap_errors
@@ -160,7 +187,7 @@ module CF
160
187
  else
161
188
  wrap_errors do
162
189
  @command = cmd
163
- precondition
190
+ precondition if respond_to? :precondition
164
191
 
165
192
  save_token_if_it_changes do
166
193
  super
@@ -3,6 +3,8 @@ require "cf/cli"
3
3
  module CF
4
4
  module App
5
5
  class Base < CLI
6
+ include LoginRequirements
7
+
6
8
  # choose the right color for app/instance state
7
9
  def state_color(s)
8
10
  case s
@@ -3,6 +3,7 @@ require "cf/cli"
3
3
  module CF
4
4
  module Domain
5
5
  class Base < CLI
6
+ include LoginRequirements
6
7
  end
7
8
  end
8
9
  end
@@ -0,0 +1,13 @@
1
+ module LoginRequirements
2
+ def precondition
3
+ check_logged_in
4
+
5
+ unless client.current_organization
6
+ fail "Please select an organization with 'cf target --organization ORGANIZATION_NAME'. (Get organization names from 'cf orgs'.)"
7
+ end
8
+
9
+ unless client.current_space
10
+ fail "Please select a space with 'cf target --space SPACE_NAME'. (Get space names from 'cf spaces'.)"
11
+ end
12
+ end
13
+ end
@@ -3,6 +3,8 @@ require "cf/cli"
3
3
  module CF
4
4
  module Populators
5
5
  class Base < CF::CLI
6
+ include LoginRequirements
7
+
6
8
  attr_reader :input, :info
7
9
 
8
10
  def initialize(input)
@@ -3,6 +3,7 @@ require "cf/cli"
3
3
  module CF
4
4
  module Route
5
5
  class Base < CLI
6
+ include LoginRequirements
6
7
  end
7
8
  end
8
9
  end
@@ -2,8 +2,6 @@ require "cf/cli/route/base"
2
2
 
3
3
  module CF::Route
4
4
  class Map < Base
5
- def precondition; end
6
-
7
5
  desc "Add a URL mapping"
8
6
  group :apps, :info, :hidden => true
9
7
  input :app, :desc => "Application to add the URL to",
@@ -3,6 +3,7 @@ require "cf/cli"
3
3
  module CF
4
4
  module Service
5
5
  class Base < CLI
6
+ include LoginRequirements
6
7
  end
7
8
  end
8
9
  end
@@ -3,6 +3,7 @@ require "cf/cli"
3
3
  module CF
4
4
  module Start
5
5
  class Base < CLI
6
+
6
7
  # Make sure we only show the target once
7
8
  @@displayed_target = false
8
9
 
@@ -10,11 +11,6 @@ module CF
10
11
  @@displayed_target
11
12
  end
12
13
 
13
-
14
- # These commands don't require authentication.
15
- def precondition;
16
- end
17
-
18
14
  private
19
15
 
20
16
  def show_context
@@ -1,3 +1,3 @@
1
1
  module CF
2
- VERSION = "4.0.1.rc2".freeze
2
+ VERSION = "4.1.0rc1".freeze
3
3
  end
@@ -7,32 +7,21 @@ module CFManifests
7
7
  MANIFEST_FILE = "manifest.yml"
8
8
 
9
9
  @@showed_manifest_usage = false
10
-
11
- class BadManifestError < StandardError
12
-
13
- def initialize(attr)
14
- @attr = attr
15
- end
16
-
17
- def to_s
18
- "#{@attr} is not a valid attribute, please visit the Manifest " +
19
- "Documentation for a list of valid attributes."
20
- end
21
- end
10
+ @@manifest = nil
22
11
 
23
12
  def manifest
24
- return @manifest if @manifest
13
+ return @@manifest if @@manifest
25
14
 
26
15
  if manifest_file && File.exists?(manifest_file)
27
- @manifest = load_manifest(manifest_file)
16
+ @@manifest = load_manifest(manifest_file)
28
17
  end
29
18
  end
30
19
 
31
20
  def save_manifest(save_to = manifest_file)
32
- fail "No manifest to save!" unless @manifest
21
+ fail "No manifest to save!" unless @@manifest
33
22
 
34
23
  File.open(save_to, "w") do |io|
35
- YAML.dump(@manifest, io)
24
+ YAML.dump(@@manifest, io)
36
25
  end
37
26
  end
38
27
 
@@ -64,22 +53,27 @@ module CFManifests
64
53
  def load_manifest(file)
65
54
  check_manifest! Loader.new(file, self).manifest
66
55
  end
67
-
68
- def check_manifest!(manifest_hash)
69
- manifest_hash[:applications].each{|app| check_attributes! app}
56
+
57
+ def check_manifest!(manifest_hash, output = $stdout)
58
+ manifest_hash[:applications].each{ |app| check_attributes!(app, output) }
70
59
  manifest_hash
71
60
  end
72
-
73
- def check_attributes!(app)
61
+
62
+ def check_attributes!(app, output = $stdout)
74
63
  app.each do |k, v|
75
- raise BadManifestError.new(k) unless known_manifest_attributes.include? k
76
- end
64
+ output.puts error_message_for_attribute(k) unless known_manifest_attributes.include? k
65
+ end
66
+ end
67
+
68
+ def error_message_for_attribute(attribute)
69
+ "\e[31mWarning: #{attribute} is not a valid manifest attribute. Please " +
70
+ "remove this attribute from your manifest to get rid of this warning\e[0m"
77
71
  end
78
72
 
79
73
  def known_manifest_attributes
80
- [:path, :name, :memory, :instances, :host, :domain,
81
- :command, :buildpack, :services, :env, :properties,
82
- :inherit, :mem, :disk, :runtime, :applications]
74
+ [:applications, :buildpack, :command, :disk, :domain, :env,
75
+ :host, :inherit, :instances, :mem, :memory, :name,
76
+ :path, :properties, :runtime, :services, :stack]
83
77
  end
84
78
 
85
79
  # dynamic symbol resolution
@@ -0,0 +1,25 @@
1
+ [![Build Status](https://travis-ci.org/cloudfoundry/micro-cf-plugin.png)](https://travis-ci.org/cloudfoundry/micro-cf-plugin)
2
+ [![Gem Version](https://badge.fury.io/rb/micro-cf-plugin.png)](http://badge.fury.io/rb/micro-cf-plugin)
3
+
4
+ ## Micro Cloud Foundry
5
+ ### Info
6
+ This plugin allows you to manage your Micro Cloud Foundry VM.
7
+
8
+ ### Installation
9
+
10
+ If you have installed CF via gem install, use:
11
+ ```
12
+ gem install micro-cf-plugin
13
+ ```
14
+
15
+ If you have installed CF through bundler and the Gemfile, add the following to your Gemfile:
16
+ ```
17
+ gem "micro-cf-plugin"
18
+ ```
19
+
20
+ ### Usage
21
+ ```
22
+ micro-status VMX [PASSWORD] Display Micro Cloud Foundry VM status
23
+ micro-offline VMX [PASSWORD] Micro Cloud Foundry offline mode
24
+ micro-online VMX [PASSWORD] Micro Cloud Foundry online mode
25
+ ```
@@ -0,0 +1,4 @@
1
+ module CFMicro
2
+ class MCFError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,56 @@
1
+ require 'find'
2
+ require "micro/errors"
3
+
4
+ module CFMicro
5
+ def config_file(file)
6
+ File.expand_path("../../../../config/#{file}", __FILE__)
7
+ end
8
+
9
+ def escape_path(path)
10
+ path = File.expand_path(path)
11
+ if RUBY_PLATFORM =~ /mingw|mswin32|cygwin/
12
+ if path.include?(' ')
13
+ '"' + path + '"'
14
+ else
15
+ path
16
+ end
17
+ else
18
+ path.gsub(' ', '\ ')
19
+ end
20
+ end
21
+
22
+ def locate_file(file, directory, search_paths)
23
+ search_paths.each do |path|
24
+ expanded_path = File.expand_path(path)
25
+ next unless File.exists?(expanded_path)
26
+ Find.find(expanded_path) do |current|
27
+ if File.directory?(current) && current.include?(directory)
28
+ full_path = File.join(current, file)
29
+ return escape_path(full_path) if File.exists?(full_path)
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
+ if $?.exitstatus == 0
41
+ result.split(/\n/)
42
+ else
43
+ if block_given?
44
+ yield
45
+ else
46
+ raise CFMicro::MCFError, "failed to execute #{command} #{args}:\n#{result}"
47
+ end
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
@@ -0,0 +1,197 @@
1
+ require "yaml"
2
+ require "multi_json"
3
+ require "cf/cli"
4
+ require "micro/micro"
5
+ require "micro/vmrun"
6
+ require "micro/switcher/base"
7
+ require "micro/switcher/darwin"
8
+ require "micro/switcher/linux"
9
+ require "micro/switcher/windows"
10
+
11
+ module CFMicro
12
+ class McfCommand < CF::CLI
13
+ MICRO_FILE = '~/.cf/micro.yml'
14
+
15
+ desc "Display Micro Cloud Foundry VM status"
16
+ input :vmx, :argument => :required,
17
+ :desc => "Path to micro.vmx"
18
+ input :password, :argument => :optional,
19
+ :desc => "Cleartext password for guest VM vcap user"
20
+ def micro_status
21
+ mode = runner.offline? ? 'offline' : 'online'
22
+
23
+ line "Micro Cloud Foundry VM currently in #{b(mode)} mode"
24
+ line "VMX Path: #{c(runner.vmx, :good)}"
25
+ line "Domain: #{c(runner.domain, :good)}"
26
+ line "IP Address: #{c(runner.ip, :good)}"
27
+ end
28
+
29
+ desc "Micro Cloud Foundry offline mode"
30
+ input :vmx, :argument => :required,
31
+ :desc => "Path to micro.vmx"
32
+ input :password, :argument => :optional,
33
+ :desc => "Cleartext password for guest VM vcap user"
34
+ def micro_offline
35
+ if !runner.nat?
36
+ if ask("Reconfigure MCF VM network to nat mode and reboot?", :default => true)
37
+ with_progress("Rebooting MCF VM") do
38
+ runner.reset_to_nat!
39
+ end
40
+ else
41
+ fail "Aborted"
42
+ end
43
+ end
44
+
45
+ with_progress("Setting MCF VM to offline mode") do
46
+ runner.offline!
47
+ end
48
+
49
+ with_progress("Setting host DNS server") do
50
+ runner.set_host_dns!
51
+ end
52
+ end
53
+
54
+ desc "Micro Cloud Foundry online mode"
55
+ input :vmx, :argument => :required,
56
+ :desc => "Path to micro.vmx"
57
+ input :password, :argument => :optional,
58
+ :desc => "Cleartext password for guest VM vcap user"
59
+ def micro_online
60
+ runner
61
+ with_progress("Unsetting host DNS server") do
62
+ runner.unset_host_dns!
63
+ end
64
+
65
+ with_progress("Setting MCF VM to online mode") do
66
+ runner.online!
67
+ end
68
+ end
69
+
70
+ def runner
71
+ return @runner if @runner
72
+
73
+ config = build_config
74
+ @runner = switcher(config)
75
+ check_vm_running
76
+ store_config(config)
77
+
78
+ @runner
79
+ end
80
+
81
+ def check_vm_running
82
+ unless runner.running?
83
+ if ask("MCF VM is not running. Do you want to start it?", :default => true)
84
+ with_progress("Starting MCF VM") do
85
+ runner.start!
86
+ end
87
+ else
88
+ fail "MCF VM needs to be running."
89
+ end
90
+ end
91
+
92
+ unless runner.ready?
93
+ fail "MCF VM initial setup needs to be completed before using 'cf micro'"
94
+ end
95
+ end
96
+
97
+ def switcher(config)
98
+ case McfCommand.platform
99
+ when :darwin
100
+ CFMicro::Switcher::Darwin.new(config)
101
+ when :linux
102
+ CFMicro::Switcher::Linux.new(config)
103
+ when :windows
104
+ CFMicro::Switcher::Windows.new(config)
105
+ when :dummy # for testing only
106
+ CFMicro::Switcher::Dummy.new(config)
107
+ else
108
+ fail "unsupported platform: #{McfCommand.platform}"
109
+ end
110
+ end
111
+
112
+ # Returns the configuration needed to run the micro related subcommands.
113
+ # First loads saved config from file (if there is any), then overrides
114
+ # loaded values with command line arguments, and finally tries to guess
115
+ # in case neither was used:
116
+ # vmx location of micro.vmx file
117
+ # vmrun location of vmrun command
118
+ # password password for vcap user (in the guest vm)
119
+ # platform current platform
120
+ def build_config
121
+ conf = micro # returns {} if there isn't a saved config
122
+
123
+ override(conf, :vmx, true) do
124
+ locate_vmx(McfCommand.platform)
125
+ end
126
+
127
+ override(conf, :vmrun, true) do
128
+ CFMicro::VMrun.locate(McfCommand.platform)
129
+ end
130
+
131
+ override(conf, :password) do
132
+ ask("Please enter your MCF VM password (vcap user) password", :echo => "*")
133
+ end
134
+
135
+ conf[:platform] = McfCommand.platform
136
+
137
+ conf
138
+ end
139
+
140
+ # Save the cleartext password if --save is supplied.
141
+ # Note: it is due to vix we have to use a cleartext password :(
142
+ # Only if --password is used and not --save is the password deleted from the
143
+ # config file before it is stored to disk.
144
+ def store_config(config)
145
+ if input[:save]
146
+ warn("cleartext password saved in: #{MICRO_FILE}")
147
+ end
148
+
149
+ store_micro(config)
150
+ end
151
+
152
+ # override with command line arguments and yield the block in case the option isn't set
153
+ def override(config, option, escape=false, &blk)
154
+ # override if given on the command line
155
+ if opt = input[option]
156
+ opt = CFMicro.escape_path(opt) if escape
157
+ config[option] = opt
158
+ end
159
+ config[option] = yield unless config[option]
160
+ end
161
+
162
+ def locate_vmx(platform)
163
+ paths = YAML.load_file(CFMicro.config_file('paths.yml'))
164
+ vmx_paths = paths[platform.to_s]['vmx']
165
+ vmx = CFMicro.locate_file('micro.vmx', 'micro', vmx_paths)
166
+ fail "Unable to locate micro.vmx, please supply --vmx option" unless vmx
167
+ vmx
168
+ end
169
+
170
+ def self.platform
171
+ case RUBY_PLATFORM
172
+ when /darwin/ # x86_64-darwin11.2.0
173
+ :darwin
174
+ when /linux/ # x86_64-linux
175
+ :linux
176
+ when /mingw|mswin32|cygwin/ # i386-mingw32
177
+ :windows
178
+ else
179
+ RUBY_PLATFORM
180
+ end
181
+ end
182
+
183
+ def micro
184
+ micro_file = File.expand_path(MICRO_FILE)
185
+ return {} unless File.exists? micro_file
186
+ contents = File.read(micro_file).strip
187
+ MultiJson.load(contents)
188
+ end
189
+
190
+ def store_micro(micro)
191
+ micro_file = File.expand_path(MICRO_FILE)
192
+ File.open(micro_file, 'w') do |file|
193
+ file.write(MultiJson.dump(micro))
194
+ end
195
+ end
196
+ end
197
+ end