vagrant-vmpooler 0.1.1 → 0.1.2

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 (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