vagrant-vmpooler 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +21 -0
  3. data/Gemfile +15 -0
  4. data/LICENSE +15 -0
  5. data/README.md +143 -0
  6. data/Rakefile +22 -0
  7. data/example_box/Vagrantfile +22 -0
  8. data/example_box/dummy.box +0 -0
  9. data/example_box/metadata.json +3 -0
  10. data/example_box/readme.md +8 -0
  11. data/lib/vagrant-vmpooler.rb +53 -0
  12. data/lib/vagrant-vmpooler/action.rb +212 -0
  13. data/lib/vagrant-vmpooler/action/create_server.rb +103 -0
  14. data/lib/vagrant-vmpooler/action/delete_server.rb +50 -0
  15. data/lib/vagrant-vmpooler/action/hard_reboot_server.rb +24 -0
  16. data/lib/vagrant-vmpooler/action/is_created.rb +16 -0
  17. data/lib/vagrant-vmpooler/action/is_paused.rb +16 -0
  18. data/lib/vagrant-vmpooler/action/is_suspended.rb +16 -0
  19. data/lib/vagrant-vmpooler/action/message_already_created.rb +16 -0
  20. data/lib/vagrant-vmpooler/action/message_not_created.rb +16 -0
  21. data/lib/vagrant-vmpooler/action/message_server_running.rb +16 -0
  22. data/lib/vagrant-vmpooler/action/message_will_not_destroy.rb +16 -0
  23. data/lib/vagrant-vmpooler/action/pause_server.rb +24 -0
  24. data/lib/vagrant-vmpooler/action/read_ssh_info.rb +56 -0
  25. data/lib/vagrant-vmpooler/action/read_state.rb +41 -0
  26. data/lib/vagrant-vmpooler/action/reboot_server.rb +24 -0
  27. data/lib/vagrant-vmpooler/action/resume_server.rb +25 -0
  28. data/lib/vagrant-vmpooler/action/setup_rsync.rb +40 -0
  29. data/lib/vagrant-vmpooler/action/suspend_server.rb +24 -0
  30. data/lib/vagrant-vmpooler/action/sync_folders.rb +104 -0
  31. data/lib/vagrant-vmpooler/action/take_snapshot.rb +35 -0
  32. data/lib/vagrant-vmpooler/action/wait_for_state.rb +38 -0
  33. data/lib/vagrant-vmpooler/config.rb +100 -0
  34. data/lib/vagrant-vmpooler/errors.rb +31 -0
  35. data/lib/vagrant-vmpooler/plugin.rb +30 -0
  36. data/lib/vagrant-vmpooler/provider.rb +55 -0
  37. data/lib/vagrant-vmpooler/version.rb +5 -0
  38. data/locales/en.yml +151 -0
  39. data/spec/spec_helper.rb +0 -0
  40. data/spec/vagrant-vmpooler/config_spec.rb +44 -0
  41. data/vagrant-vmpooler.gemspec +23 -0
  42. metadata +45 -3
@@ -0,0 +1,25 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module Vmpooler
5
+ module Action
6
+ # This starts a suspended server, if there is one.
7
+ class ResumeServer
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vmpooler::action::resume_server")
11
+ end
12
+
13
+ def call(env)
14
+ if env[:machine].id
15
+ env[:ui].info(I18n.t("vagrant_vmpooler.resuming_server"))
16
+
17
+ # raise "not implemented"
18
+ end
19
+
20
+ @app.call(env)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module VagrantPlugins
3
+ module Vmpooler
4
+ module Action
5
+ class SetupRsync
6
+ def initialize(app, env)
7
+ @app = app
8
+ @logger = Log4r::Logger.new("vagrant_vmpooler::action::setup_rsync")
9
+ end
10
+
11
+ def determine_packman(os_flavor)
12
+ if os_flavor =~ /centos|fedora|redhat/i
13
+ cmd_install_rsync = "yum install rsync.x86_64 -y"
14
+ elsif os_flavor =~ /debian|ubuntu/i
15
+ cmd_install_rsync = "apt-get install rsync -y"
16
+ else
17
+ cmd_install_rsync = nil
18
+ end
19
+
20
+ cmd_install_rsync
21
+ end
22
+
23
+ def call(env)
24
+ ssh_info = env[:machine].ssh_info
25
+ os_flavor = env[:machine].provider_config.os
26
+ cmd_install_rsync = determine_packman(os_flavor)
27
+
28
+ if cmd_install_rsync
29
+ env[:ui].info(I18n.t("vagrant_vmpooler.install_rsync"))
30
+ env[:machine].communicate.execute(cmd_install_rsync, :error_check => true)
31
+ else
32
+ env[:ui].warn(I18n.t("vagrant_vmpooler.no_install_rsync"))
33
+ end
34
+
35
+ @app.call(env)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module Vmpooler
5
+ module Action
6
+ # This deletes the running server, if there is one.
7
+ class SuspendServer
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vmpooler::action::suspend_server")
11
+ end
12
+
13
+ def call(env)
14
+ if env[:machine].id
15
+ env[:ui].info(I18n.t("vagrant_vmpooler.suspending_server"))
16
+
17
+ end
18
+
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,104 @@
1
+ require "log4r"
2
+
3
+ require "vagrant/util/subprocess"
4
+ require "vagrant/util/which"
5
+
6
+ module VagrantPlugins
7
+ module Vmpooler
8
+ module Action
9
+ # This middleware uses `rsync` to sync the folders over to the
10
+ # remote instance.
11
+ class SyncFolders
12
+ def initialize(app, env)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_vmpooler::action::sync_folders")
15
+ end
16
+
17
+ def call(env)
18
+ @app.call(env)
19
+
20
+ ssh_info = env[:machine].ssh_info
21
+
22
+ env[:machine].config.vm.synced_folders.each do |id, data|
23
+ # ignore disabled shared folders
24
+ if data[:disabled]
25
+ @logger.info "Not syncing disabled folder: #{data[:hostpath]} => #{data[:guestpath]}"
26
+ next
27
+ end
28
+
29
+ unless Vagrant::Util::Which.which('rsync')
30
+ @logger.info "please install rsync locally first"
31
+ break
32
+ end
33
+
34
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
35
+ # rsync interprets paths with colons as remote locations.
36
+ # "cygdrive" path for cygwin on windows.
37
+ if Vagrant::Util::Platform.windows?
38
+ hostpath = Vagrant::Util::Subprocess.execute("cygpath", "-u", "-a", hostpath).stdout.chomp
39
+ end
40
+ guestpath = data[:guestpath]
41
+
42
+ # Make sure there is a trailing slash on the host path to
43
+ # avoid creating an additional directory with rsync
44
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
45
+
46
+ env[:ui].info(I18n.t("vagrant_vmpooler.rsync_folder",
47
+ :hostpath => hostpath,
48
+ :guestpath => guestpath))
49
+
50
+ # Create the guest path
51
+ # Use sudo only when it is necessary
52
+ cmd_mkdir = "mkdir -p '#{guestpath}'"
53
+ cmd_chown = "chown #{ssh_info[:username]} '#{guestpath}'"
54
+ if env[:machine].communicate.execute(cmd_mkdir, :error_check => false) != 0 then
55
+ env[:machine].communicate.sudo(cmd_mkdir)
56
+ end
57
+ if env[:machine].communicate.execute(cmd_chown, :error_check => false) != 0 then
58
+ env[:machine].communicate.sudo(cmd_chown)
59
+ end
60
+
61
+ #collect rsync excludes specified :rsync_excludes=>['path1',...] in synced_folder options
62
+ excludes = ['.vagrant/', 'Vagrantfile', *Array(data[:rsync_excludes])].uniq
63
+
64
+ # Rsync over to the guest path using the SSH info
65
+ if env[:machine].config.ssh.proxy_command
66
+ proxy_cmd = "-o ProxyCommand='#{env[:machine].config.ssh.proxy_command}'"
67
+ else
68
+ proxy_cmd = ''
69
+ end
70
+
71
+ # poor workaround for poor ipv6 handling of rsync
72
+ if ssh_info[:host].include? ':'
73
+ user_at_host = "[#{ssh_info[:username]}@#{ssh_info[:host]}]"
74
+ else
75
+ user_at_host = ssh_info[:username] + "@" + ssh_info[:host]
76
+ end
77
+
78
+ command = [
79
+ 'rsync', '--verbose', '--archive', '-z', '--delete',
80
+ *excludes.map{|e|['--exclude', e]}.flatten,
81
+ '-e', "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no #{proxy_cmd} #{ssh_key_options(ssh_info)}",
82
+ hostpath,
83
+ user_at_host + ":" + guestpath]
84
+
85
+ r = Vagrant::Util::Subprocess.execute(*command)
86
+ if r.exit_code != 0
87
+ raise Errors::RsyncError,
88
+ :guestpath => guestpath,
89
+ :hostpath => hostpath,
90
+ :stderr => r.stderr
91
+ end
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def ssh_key_options(ssh_info)
98
+ # Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
99
+ Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,35 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module Vmpooler
5
+ module Action
6
+ # This reboots a running server, if there is one.
7
+ class TakeSnapshot
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_vmpooler::action::take_snapshot")
11
+ end
12
+
13
+ def call(env)
14
+ if env[:machine].id
15
+ env[:ui].info(I18n.t("vagrant_vmpooler.snapshoting_server"))
16
+ # make api call to snapshot server
17
+ provider_config = env[:machine].provider_config
18
+
19
+ token = provider_config.token
20
+ url = provider_config.url
21
+ verbose = provider_config.verbose
22
+ hostname = env[:machine].id
23
+ response = Pooler.snapshot(verbose, url, hostname, token)
24
+ if response['ok'] == false
25
+ env[:ui].info(I81n.t("vagrant_vmpooler.errors.failed_snapshot"))
26
+ env[:ui].info(response)
27
+ end
28
+ end
29
+
30
+ @app.call(env)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ require 'log4r'
2
+ require 'timeout'
3
+
4
+ module VagrantPlugins
5
+ module Vmpooler
6
+ module Action
7
+ # This action will wait for a machine to reach a specific state or quit by timeout.
8
+ class WaitForState
9
+ def initialize(app, env, state, timeout)
10
+ @app = app
11
+ @logger = Log4r::Logger.new('vagrant_vmpooler::action::wait_for_state')
12
+ @state = Array.new(state).flatten
13
+ @timeout = timeout
14
+ end
15
+
16
+ def call(env)
17
+ env[:result] = true
18
+ state = env[:machine].state.id.to_sym
19
+
20
+ if @state.include?(state)
21
+ @logger.info("Machine already at status #{ state.to_s }")
22
+ else
23
+ @logger.info("Waiting for machine to reach state...")
24
+ begin
25
+ Timeout.timeout(@timeout) do
26
+ sleep 2 until @state.include?(env[:machine].state.id)
27
+ end
28
+ rescue Timeout::Error
29
+ env[:result] = false
30
+ end
31
+
32
+ @app.call(env)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,100 @@
1
+ require 'vagrant'
2
+ require 'yaml'
3
+
4
+ module VagrantPlugins
5
+ module Vmpooler
6
+ class Config < Vagrant.plugin("2", :config)
7
+ # The token used to obtain vms
8
+ #
9
+ # @return [String]
10
+ attr_accessor :token
11
+
12
+ # The url to your vmpooler installation
13
+ #
14
+ # @return [String]
15
+ attr_accessor :url
16
+
17
+ # Whether or not to run vmfloaty
18
+ # commands in verbose mode
19
+ #
20
+ # @return [Boolean]
21
+ attr_accessor :verbose
22
+
23
+ # The type of operatingsystem to
24
+ # get from the pooler
25
+ #
26
+ # @return [String]
27
+ attr_accessor :os
28
+
29
+ # The password to use to log
30
+ # into the vmpooler machine
31
+ #
32
+ # @return [String]
33
+ attr_accessor :password
34
+
35
+ # How long the vm should stay
36
+ # active for
37
+ #
38
+ # @return [Integer]
39
+ attr_accessor :ttl
40
+
41
+ # Increases default disk space by
42
+ # this size
43
+ #
44
+ # @return [Integer]
45
+ attr_accessor :disk
46
+
47
+ #attr_accessor :user
48
+
49
+ # ----------------
50
+ # Internal methods
51
+ # ----------------
52
+
53
+ def read_config
54
+ conf_file = {}
55
+ begin
56
+ conf_file = YAML.load_file("#{Dir.home}/.vmfloaty.yml")
57
+ rescue
58
+ # vagrant debug?
59
+ end
60
+ conf_file
61
+ end
62
+
63
+ def finalize!
64
+ conf_file = read_config
65
+
66
+ if conf_file['token']
67
+ @token = conf_file['token']
68
+ else
69
+ @token = nil
70
+ end
71
+
72
+ if conf_file['url']
73
+ @url = conf_file['url']
74
+ else
75
+ @url = nil
76
+ end
77
+
78
+ @verbose = false if @verbose == UNSET_VALUE
79
+ @os = nil if @os == UNSET_VALUE
80
+ @ttl = nil if @ttl == UNSET_VALUE
81
+ @disk = nil if @disk == UNSET_VALUE
82
+ @password = nil if @password == UNSET_VALUE
83
+ end
84
+
85
+ # ----------------
86
+ # Provider methods
87
+ # ----------------
88
+
89
+ def initialize(verbose=false)
90
+ @token = UNSET_VALUE
91
+ @url = UNSET_VALUE
92
+ @verbose = UNSET_VALUE
93
+ @os = UNSET_VALUE
94
+ @ttl = UNSET_VALUE
95
+ @disk = UNSET_VALUE
96
+ @password = UNSET_VALUE
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,31 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantPlugins
4
+ module Vmpooler
5
+ module Errors
6
+ class VagrantVmpoolerErrors < Vagrant::Errors::VagrantError
7
+ error_namespace("vagrant_vmpooler.errors")
8
+ end
9
+
10
+ class NoURLError < VagrantVmpoolerErrors
11
+ error_key(:vmpooler_url_error)
12
+ end
13
+
14
+ class NoOSError < VagrantVmpoolerErrors
15
+ error_key(:no_os_error)
16
+ end
17
+
18
+ class FailedRequest < VagrantVmpoolerErrors
19
+ error_key(:bad_request)
20
+ end
21
+
22
+ class RsyncError < VagrantVmpoolerErrors
23
+ error_key(:rsync_error)
24
+ end
25
+
26
+ class RsyncError < VagrantVmpoolerErrors
27
+ error_key(:install_rsync_error)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant vmpooler plugin must be run within Vagrant."
5
+ end
6
+
7
+ module VagrantPlugins
8
+ module Vmpooler
9
+ class Plugin < Vagrant.plugin("2")
10
+ name "Vmpooler"
11
+ description <<-DESC
12
+ This plugin installs a provider that allows Vagrant to manage
13
+ machines in vmpooler.
14
+ DESC
15
+
16
+ config(:vmpooler, :provider) do
17
+ require_relative "config"
18
+ Config
19
+ end
20
+
21
+ provider(:vmpooler, parallel:true) do
22
+ Vmpooler.init_i18n
23
+ Vmpooler.init_logging
24
+
25
+ require_relative 'provider'
26
+ Provider
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ require "vagrant"
2
+
3
+ require "vagrant-vmpooler/action"
4
+
5
+ module VagrantPlugins
6
+ module Vmpooler
7
+ class Provider < Vagrant.plugin("2", :provider)
8
+ def initialize(machine)
9
+ @machine = machine
10
+ end
11
+
12
+ def action(name)
13
+ # Attempt to get the action method from the Action class if it
14
+ # exists, otherwise return nil to show that we don't support the
15
+ # given action.
16
+ action_method = "action_#{name}"
17
+ return Action.send(action_method) if Action.respond_to?(action_method)
18
+ nil
19
+ end
20
+
21
+ def ssh_info
22
+ # Run a custom action called "read_ssh_info" which does what it
23
+ # says and puts the resulting SSH info into the `:machine_ssh_info`
24
+ # key in the environment.
25
+ env = @machine.action("read_ssh_info")
26
+ env[:machine_ssh_info]
27
+ end
28
+
29
+ def state
30
+ # Run a custom action we define called "read_state" which does
31
+ # what it says. It puts the state in the `:machine_state_id`
32
+ # key in the environment.
33
+ env = @machine.action("read_state")
34
+
35
+ state_id = env[:machine_state_id]
36
+
37
+ # Get the short and long description
38
+ short = I18n.t("vagrant_vmpooler.states.short_#{state_id}")
39
+ long = I18n.t("vagrant_vmpooler.states.long_#{state_id}")
40
+
41
+ # Return the MachineState object
42
+ Vagrant::MachineState.new(state_id, short, long)
43
+ end
44
+
45
+ def to_s
46
+ id = "new"
47
+ if !@machine.id.nil?
48
+ id = @machine.id
49
+ end
50
+
51
+ "Vmpooler (#{id})"
52
+ end
53
+ end
54
+ end
55
+ end