vagrant-hp 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,60 @@
1
+ # Compiled source #
2
+ ###################
3
+ *.com
4
+ *.class
5
+ *.dll
6
+ *.exe
7
+ *.o
8
+ *.so
9
+
10
+ # Packages #
11
+ ############
12
+ # it's better to unpack these files and commit the raw source
13
+ # git has its own built in compression methods
14
+ *.7z
15
+ *.dmg
16
+ *.gz
17
+ *.iso
18
+ *.jar
19
+ *.rar
20
+ *.tar
21
+ *.zip
22
+
23
+ # Logs and databases #
24
+ ######################
25
+ *.log
26
+ *.sql
27
+ *.sqlite
28
+
29
+ # OS generated files #
30
+ ######################
31
+ .DS_Store
32
+ .DS_Store?
33
+ ._*
34
+ .Spotlight-V100
35
+ .Trashes
36
+ Icon?
37
+ ehthumbs.db
38
+ Thumbs.db
39
+
40
+ # Ruby file #
41
+ #############
42
+ Gemfile.lock
43
+ *.gem
44
+ *.rbc
45
+ .bundle
46
+ .config
47
+ coverage
48
+ InstalledFiles
49
+ lib/bundler/man
50
+ pkg
51
+ rdoc
52
+ spec/reports
53
+ test/tmp
54
+ test/version_tmp
55
+ tmp
56
+
57
+ # YARD artifacts
58
+ .yardoc
59
+ _yardoc
60
+ doc/
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 0.0.1 (March 31, 2013)
2
+ * Vagrant-Hp
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ # We depend on Vagrant for development, but we don't add it as a
7
+ # gem dependency because we expect to be installed within the
8
+ # Vagrant environment itself using `vagrant plugin`.
9
+ gem "vagrant", :git => "git://github.com/mohitsethi/vagrant.git"
10
+ end
data/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # Vagrant HP Provider
2
+
3
+ This is a [Vagrant](http://www.vagrantup.com) 1.1+ plugin that adds an [HP](http://www.hpcloud.com)
4
+ provider to Vagrant, allowing Vagrant to control and provision machines on HP Cloud.
5
+
6
+ **NOTE:** This plugin requires Vagrant 1.1+,
7
+
8
+ ## Features
9
+
10
+ * Boot Servers on HP Cloud
11
+ * SSH into the instances.
12
+ * Provision the instances with any built-in Vagrant provisioner.
13
+ * Minimal synced folder support via `rsync`.
14
+
15
+ ## Usage
16
+
17
+ Install using standard Vagrant 1.1+ plugin installation methods. After
18
+ installing, `vagrant up` and specify the `hp` provider. An example is
19
+ shown below.
20
+
21
+ ```
22
+ $ vagrant plugin install vagrant-hp
23
+ ...
24
+ $ vagrant up --provider=hp
25
+ ...
26
+ ```
27
+
28
+ Of course prior to doing this, you'll need to obtain an HP-compatible
29
+ box file for Vagrant.
30
+
31
+ ## Quick Start
32
+
33
+ After installing the plugin (instructions above), the quickest way to get
34
+ started is to actually use a dummy HP box and specify all the details
35
+ manually within a `config.vm.provider` block. So first, add the dummy
36
+ box using any name you want:
37
+
38
+ ```
39
+ $ vagrant box add dummy https://github.com/mohitsethi/vagrant-hp/raw/master/dummy_hp.box
40
+ ...
41
+ ```
42
+
43
+ And then make a Vagrantfile that looks like the following, filling in
44
+ your information where necessary.
45
+
46
+ ```
47
+ Vagrant.configure("2") do |config|
48
+ config.vm.box = "dummy"
49
+
50
+ config.vm.provider :hp do |rs|
51
+ rs.access_key = "<hp_access_key>"
52
+ rs.secret_key = "<hp_secret_key>"
53
+ rs.flavor = "standard.xsmall"
54
+ rs.tenant_id = "<hp_tenant_id>"
55
+ rs.server_name = "<server_name>"
56
+ rs.image = "Ubuntu Precise 12.04 LTS Server 64-bit 20121026 (b)"
57
+ rs.keypair_name = "<your_key_pair_name_on_hpcloud>"
58
+ rs.ssh_private_key_path = "<private_key_location>"
59
+ rs.ssh_username = "<ssh_username>"
60
+ rs.availability_zone = "az1"
61
+ end
62
+ end
63
+ ```
64
+
65
+ And then run `vagrant up --provider=hp`.
66
+
67
+ This will start an Ubuntu 12.04 instance in the az1 availability zone within
68
+ your HP Cloud account. And assuming your SSH information was filled in properly
69
+ within your Vagrantfile, SSH and provisioning will work as well.
70
+
71
+ Note that normally a lot of this boilerplate is encoded within the box
72
+ file, but the box file used for the quick start, the "dummy" box, has
73
+ no preconfigured defaults.
74
+
75
+ ## Box Format
76
+
77
+ Every provider in Vagrant must introduce a custom box format. This
78
+ provider introduces `hp` boxes. You can view an example box in
79
+ the [example_box/ directory](https://github.com/mohitsethi/vagrant-hp/tree/master/example_box).
80
+ That directory also contains instructions on how to build a box.
81
+
82
+ The box format is basically just the required `metadata.json` file
83
+ along with a `Vagrantfile` that does default settings for the
84
+ provider-specific configuration for this provider.
85
+
86
+ ## Configuration
87
+
88
+ This provider exposes quite a few provider-specific configuration options:
89
+
90
+ * `access_key` - The access key for accessing HP Cloud
91
+ * `image` - The Image-id or Image-Name to boot, such as
92
+ "Ubuntu Precise 12.04 LTS Server 64-bit 20121026 (b)"
93
+ * `availability_zone` - The availability zone to launch the server.
94
+ If nil, it will use 'az1'.
95
+ * `flavor` - The type of flavor, such as "standard.xsmall"
96
+ * `keypair_name` - The name of the keypair to use to bootstrap image
97
+ which support it.
98
+ * `secret_key` - The secret access key for accessing HP Cloud.
99
+ * `ssh_private_key_path` - The path to the SSH private key. This overrides
100
+ `config.ssh.private_key_path`.
101
+ * `ssh_username` - The SSH username, which overrides `config.ssh.username`.
102
+ * `server_name` - The name of the server provisioned on HP Cloud.
103
+ * `tenant_id` - The tenant_id to launch the server.
104
+
105
+ These can be set like typical provider-specific configuration:
106
+
107
+
108
+ ```ruby
109
+ Vagrant.configure("2") do |config|
110
+ # ... other stuff
111
+
112
+ config.vm.provider :hp do |rs|
113
+ rs.access_key = "<hp_access_key>"
114
+ rs.secret_key = "<hp_secret_key>"
115
+ rs.flavor = "standard.xsmall"
116
+ rs.tenant_id = "<hp_tenant_id>"
117
+ rs.server_name = "<server_name>"
118
+ rs.image = "Ubuntu Precise 12.04 LTS Server 64-bit 20121026 (b)"
119
+ rs.keypair_name = "<your_key_pair_name_on_hpcloud>"
120
+ rs.ssh_private_key_path = "<private_key_location>"
121
+ rs.ssh_username = "<ssh_username>"
122
+ rs.availability_zone = "az1"
123
+ end
124
+
125
+ end
126
+ ```
127
+
128
+ ## Networks
129
+
130
+ Networking features in the form of `config.vm.network` are not
131
+ supported with `vagrant-hp`, currently. If any of these are
132
+ specified, Vagrant will emit a warning, but will otherwise boot
133
+ the HP machine.
134
+
135
+ ## Synced Folders
136
+
137
+ There is minimal support for synced folders. Upon `vagrant up`,
138
+ `vagrant reload`, and `vagrant provision`, the HP provider will use
139
+ `rsync` (if available) to uni-directionally sync the folder to
140
+ the remote machine over SSH.
141
+
142
+ This is good enough for all built-in Vagrant provisioners (shell,
143
+ chef, and puppet) to work!
144
+
145
+ ## Development
146
+
147
+ To work on the `vagrant-hp` plugin, clone this repository out, and use
148
+ [Bundler](http://gembundler.com) to get the dependencies:
149
+
150
+ ```
151
+ $ bundle
152
+ ```
153
+
154
+ Once you have the dependencies, verify the unit tests pass with `rake`:
155
+
156
+ ```
157
+ $ bundle exec rake
158
+ ```
159
+
160
+ If those pass, you're ready to start developing the plugin. You can test
161
+ the plugin without installing it into your Vagrant environment by just
162
+ creating a `Vagrantfile` in the top level of this directory (it is gitignored)
163
+ that uses it, and uses bundler to execute Vagrant:
164
+
165
+ ```
166
+ $ bundle exec vagrant up --provider=hp
167
+ ```
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core/rake_task'
4
+
5
+ # Immediately sync all stdout so that tools like buildbot can
6
+ # immediately load in the output.
7
+ $stdout.sync = true
8
+ $stderr.sync = true
9
+
10
+ # Change to the directory of this file.
11
+ Dir.chdir(File.expand_path("../", __FILE__))
12
+
13
+ # This installs the tasks that help with gem creation and
14
+ # publishing.
15
+ Bundler::GemHelper.install_tasks
16
+
17
+ # Install the `spec` task so that we can run tests.
18
+ RSpec::Core::RakeTask.new
19
+
20
+ # Default task is to run the unit tests
21
+ task :default => "spec"
data/dummy_hp.box ADDED
Binary file
@@ -0,0 +1,13 @@
1
+ # Vagrant HP Example Box
2
+
3
+ Vagrant providers each require a custom provider-specific box format.
4
+ This folder shows the example contents of a box for the `hp` provider.
5
+ To turn this into a box:
6
+
7
+ ```
8
+ $ tar cvzf hp.box ./metadata.json ./Vagrantfile
9
+ ```
10
+
11
+ This box works by using Vagrant's built-in Vagrantfile merging to setup
12
+ defaults for HP. These defaults can easily be overwritten by higher-level
13
+ Vagrantfiles (such as project root Vagrantfiles).
@@ -0,0 +1,7 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ config.vm.provider :hp do |rs|
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ {
2
+ "provider": "hp"
3
+ }
data/lib/vagrant-hp.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "pathname"
2
+
3
+ require "vagrant-hp/plugin"
4
+
5
+ module VagrantPlugins
6
+ module HP
7
+ lib_path = Pathname.new(File.expand_path("../vagrant-hp", __FILE__))
8
+ autoload :Action, lib_path.join("action")
9
+ autoload :Errors, lib_path.join("errors")
10
+
11
+ # This returns the path to the source of this plugin.
12
+ #
13
+ # @return [Pathname]
14
+ def self.source_root
15
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,110 @@
1
+ #
2
+ # Author:: Mohit Sethi (<mohit@sethis.in>)
3
+ # Copyright:: Copyright (c) 2013 Mohit Sethi.
4
+ #
5
+
6
+ require "pathname"
7
+ require "vagrant/action/builder"
8
+
9
+ module VagrantPlugins
10
+ module HP
11
+ module Action
12
+ # Include the built-in modules so we can use them as top-level things.
13
+ include Vagrant::Action::Builtin
14
+
15
+ # This action is called to terminate the remote machine.
16
+ def self.action_destroy
17
+ Vagrant::Action::Builder.new.tap do |b|
18
+ b.use ConfigValidate
19
+ b.use ConnectHP
20
+ b.use DeleteServer
21
+ end
22
+ end
23
+
24
+ # This action is called when `vagrant provision` is called.
25
+ def self.action_provision
26
+ Vagrant::Action::Builder.new.tap do |b|
27
+ b.use ConfigValidate
28
+ b.use Call, IsCreated do |env, b2|
29
+ if !env[:result]
30
+ b2.use MessageNotCreated
31
+ next
32
+ end
33
+ b2.use SyncFolders
34
+ b2.use Provision
35
+ end
36
+ end
37
+ end
38
+
39
+ # This action is called to read the SSH info of the machine. The
40
+ # resulting state is expected to be put into the `:machine_ssh_info`
41
+ # key.
42
+ def self.action_read_ssh_info
43
+ Vagrant::Action::Builder.new.tap do |b|
44
+ b.use ConfigValidate
45
+ b.use ConnectHP
46
+ b.use ReadSSHInfo
47
+ end
48
+ end
49
+
50
+ # This action is called to read the state of the machine. The
51
+ # resulting state is expected to be put into the `:machine_state_id`
52
+ # key.
53
+ def self.action_read_state
54
+ Vagrant::Action::Builder.new.tap do |b|
55
+ b.use ConfigValidate
56
+ b.use ConnectHP
57
+ b.use ReadState
58
+ end
59
+ end
60
+
61
+ # This action is called to SSH into the machine.
62
+ def self.action_ssh
63
+ Vagrant::Action::Builder.new.tap do |b|
64
+ b.use ConfigValidate
65
+ b.use Call, IsCreated do |env, b2|
66
+ if !env[:result]
67
+ b2.use MessageNotCreated
68
+ next
69
+ end
70
+
71
+ b2.use SSHExec
72
+ end
73
+ end
74
+ end
75
+
76
+ def self.action_up
77
+ Vagrant::Action::Builder.new.tap do |b|
78
+ b.use ConfigValidate
79
+ b.use Call, IsCreated do |env, b2|
80
+ if env[:result]
81
+ b2.use MessageAlreadyCreated
82
+ next
83
+ end
84
+
85
+ b2.use ConnectHP
86
+ b2.use Provision
87
+ b2.use SyncFolders
88
+ b2.use WarnNetworks
89
+ b2.use CreateServer
90
+ end
91
+ end
92
+ end
93
+
94
+ # The autoload farm
95
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
96
+ autoload :ConnectHP, action_root.join("connect_hp")
97
+ autoload :IsCreated, action_root.join("is_created")
98
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
99
+ autoload :MessageNotCreated, action_root.join("message_not_created")
100
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
101
+ autoload :ReadState, action_root.join("read_state")
102
+ autoload :RunInstance, action_root.join("run_instance")
103
+ autoload :SyncFolders, action_root.join("sync_folders")
104
+ autoload :TimedProvision, action_root.join("timed_provision")
105
+ autoload :WarnNetworks, action_root.join("warn_networks")
106
+ autoload :CreateServer, action_root.join("create_server")
107
+ autoload :DeleteServer, action_root.join("delete_server")
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,54 @@
1
+ #
2
+ # Author:: Mohit Sethi (<mohit@sethis.in>)
3
+ # Copyright:: Copyright (c) 2013 Mohit Sethi.
4
+ #
5
+
6
+ require "fog"
7
+ require "log4r"
8
+
9
+ module VagrantPlugins
10
+ module HP
11
+ module Action
12
+ # This action connects to HP, verifies credentials work, and
13
+ # puts the HP connection object into the `:hp_compute` key
14
+ # in the environment.
15
+ class ConnectHP
16
+ def initialize(app, env)
17
+ @app = app
18
+ @logger = Log4r::Logger.new("vagrant_hp::action::connect_hp")
19
+ end
20
+
21
+ def call(env)
22
+ # Get the configs
23
+ config = env[:machine].provider_config
24
+ access_key = config.access_key
25
+ secret_key = config.secret_key
26
+ tenant_id = config.tenant_id
27
+ availability_zone = availability_zone(config.availability_zone)
28
+
29
+ @logger.info("Connecting to HP...")
30
+ env[:hp_compute] = Fog::Compute.new({
31
+ :provider => :hp,
32
+ :hp_access_key => access_key,
33
+ :hp_secret_key => secret_key,
34
+ :hp_tenant_id => tenant_id,
35
+ :hp_avl_zone => availability_zone,
36
+ })
37
+
38
+ @app.call(env)
39
+ end
40
+
41
+ def availability_zone(availability_zone)
42
+ case availability_zone
43
+ when 'az3'
44
+ return 'az-3.region-a.geo-1'
45
+ when 'az2'
46
+ return 'az-2.region-a.geo-1'
47
+ else
48
+ return 'az-1.region-a.geo-1'
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end