vagrant-extended-storage 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 681ccb63fa3b124b6f761a8f90ce00beb26a7409
4
+ data.tar.gz: 0184ec50eb4b4ec905dce58046a5a2f8e937fadc
5
+ SHA512:
6
+ metadata.gz: e0279cb84ed45b3704194823826e8110e46843fc670839e546e28609da2b85267d098178c8118659ab6c155a49b22ea1490008b2cc5c7327c59164ad0cfeb821
7
+ data.tar.gz: 4bc9135fe7c0b11e3d47fbb92ae4ad8b0f06cf111b272d7db36f7c1f8514034a3ca3ccaba9571ca1af614f315338a141b4efbd47dbbbbf775a326f307503e10a
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-persistent-storage.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sebastian Kusnier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Vagrant::Extended-storage
2
+
3
+ A Vagrant plugin that extends the root storage by attaching a second volume and using lvmextend.
4
+
5
+ Requires lvm partitions.
6
+
7
+ ## Installation
8
+
9
+ $ vagrant plugin install vagrant-extended-storage
10
+
11
+ ## Usage
12
+
13
+ After installing you can set the location and size of the extended storage.
14
+
15
+ The following options will create a extend storage with 5000 MB, named mysql,
16
+ mounted on /var/lib/mysql, in a volume group called 'vagrant'
17
+ ```ruby
18
+ config.extended_storage.enabled = true
19
+ config.extended_storage.location = "~/development/sourcehdd.vdi"
20
+ config.extended_storage.size = 5000
21
+ config.extended_storage.filesystem = 'ext4'
22
+ config.extended_storage.volgroupname = 'vg_os'
23
+ ```
24
+
25
+ With `config.extended_storage.mountoptions` you can change the mount options (default: defaults).
26
+ A example which sets `prjquota` option with xfs.
27
+ ```ruby
28
+ config.extended_storage.mountname = 'root'
29
+ ```
30
+
31
+ Device defaults to `/dev/sdb`. For boxes with multiple disks, make sure you increment the drive:
32
+ ```
33
+ config.extended_storage.diskdevice = '/dev/sdc'
34
+ ```
35
+
36
+ Every `vagrant up` will attach this file as hard disk to the guest machine.
37
+ An `vagrant destroy` will detach the storage to avoid deletion of the storage by vagrant.
38
+ A `vagrant destroy` generally destroys all attached drives. See [VBoxMange unregistervm --delete option][vboxmanage_delete].
39
+
40
+ The disk is initialized and added to the volume group specfied in the config;
41
+
42
+
43
+ ## Windows Guests
44
+
45
+ NOT TESTED or SUPPORTED. Get a Mac/Linux ffs.
46
+
47
+ ## Troubleshooting
48
+
49
+ If your box are not using LVM you must set `config.extended_storage.use_lvm = false`. (currently we only support LVM)
50
+
51
+ ## Supported Providers
52
+
53
+ * Only the VirtualBox provider is supported.
54
+
55
+ ## Contributors
56
+
57
+ * [madAndroid](https://github.com/madAndroid)
58
+ * [Jeremiah Snapp](https://github.com/jeremiahsnapp)
59
+ * [Hiroya Ito](https://github.com/hiboma)
60
+ * [joshuata](https://github.com/joshuata)
61
+ * [Ciprian Zaharie](https://github.com/bucatzel)
62
+ * [aishahalim](https://github.com/aishahalim)
63
+ * [Dick Tang](https://github.com/dictcp)
64
+ * [dsmaher](https://github.com/dsmaher)
65
+ * [Marsup](https://github.com/Marsup)
66
+ * [k2s](https://github.com/k2s)
67
+ * [vvavrychuk](https://github.com/vvavrychuk)
68
+ * [Lars Hupfeldt Nielsen](https://github.com/lhupfeldt)
69
+ * [Chen Yu Pao](https://github.com/windperson)
70
+ * [Kris Reese](https://github.com/ktreese)
71
+ * [Henry N.](https://github.com/HenryNe)
72
+
73
+ ## TODO
74
+
75
+ * There's Always Something to Do
76
+ * Add more options (controller, port, etc.)
77
+
78
+
79
+ [vboxmanage_delete]: http://www.virtualbox.org/manual/ch08.html#vboxmanage-registervm "VBoxManage registervm / unregistervm"
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ Bundler::GemHelper.install_tasks
4
+
@@ -0,0 +1,13 @@
1
+ require 'vagrant-extended-storage/plugin'
2
+ require 'vagrant-extended-storage/version'
3
+
4
+ module VagrantPlugins
5
+ module ExtendedStorage
6
+ def self.source_root
7
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
8
+ end
9
+
10
+ I18n.load_path << File.expand_path('locales/en.yml', source_root)
11
+ I18n.reload!
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ require "vagrant/action/builder"
2
+ require "vagrant-persistent-storage/action"
3
+ require "vagrant-persistent-storage/action/manage_storage"
4
+
5
+ module VagrantPlugins
6
+ module ExtendedStorage
7
+ module Action
8
+ include Vagrant::Action::Builtin
9
+
10
+ autoload :CreateAdapter, File.expand_path("../action/create_adapter.rb", __FILE__)
11
+ autoload :CreateStorage, File.expand_path("../action/create_storage.rb", __FILE__)
12
+ autoload :AttachStorage, File.expand_path("../action/attach_storage.rb", __FILE__)
13
+ autoload :DetachStorage, File.expand_path("../action/detach_storage.rb", __FILE__)
14
+ autoload :ManageStorage, File.expand_path("../action/manage_storage.rb", __FILE__)
15
+
16
+ def self.create_adapter
17
+ Vagrant::Action::Builder.new.tap do |builder|
18
+ builder.use ConfigValidate
19
+ builder.use CreateAdapter
20
+ end
21
+ end
22
+
23
+ def self.create_storage
24
+ Vagrant::Action::Builder.new.tap do |builder|
25
+ builder.use ConfigValidate
26
+ builder.use CreateStorage
27
+ end
28
+ end
29
+
30
+ def self.attach_storage
31
+ Vagrant::Action::Builder.new.tap do |builder|
32
+ builder.use ConfigValidate
33
+ builder.use AttachStorage
34
+ end
35
+ end
36
+
37
+ def self.detach_storage
38
+ Vagrant::Action::Builder.new.tap do |builder|
39
+ builder.use ConfigValidate
40
+ builder.use DetachStorage
41
+ end
42
+ end
43
+
44
+ def self.manage_storage
45
+ Vagrant::Action::Builder.new.tap do |builder|
46
+ builder.use ConfigValidate
47
+ builder.use ManageAll
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ module Action
6
+ class AttachStorage
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @machine = env[:machine]
11
+ @global_env = @machine.env
12
+ @provider = env[:provider]
13
+ @logger = Log4r::Logger.new('vagrant::ExtendedStorage::action::attachstorage')
14
+ end
15
+
16
+ def call(env)
17
+ # skip if machine is not running and the action is destroy, halt or suspend
18
+ return @app.call(env) if @machine.state.id != :running && [:destroy, :halt, :suspend].include?(env[:machine_action])
19
+ # skip if machine is saved
20
+ return @app.call(env) if @machine.state.id == :saved
21
+
22
+ return @app.call(env) unless env[:machine].config.extended_storage.enabled?
23
+ @logger.info '** Attaching Extended Storage **'
24
+
25
+ env[:ui].info I18n.t("vagrant_extended_storage.action.attach_storage")
26
+ location = env[:machine].config.extended_storage.location
27
+ env[:machine].provider.driver.attach_storage(location)
28
+
29
+ @app.call(env)
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ module Action
6
+ class CreateAdapter
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @machine = env[:machine]
11
+ @global_env = @machine.env
12
+ @provider = env[:provider]
13
+ @logger = Log4r::Logger.new('vagrant::extended_storage::action::create_adapter')
14
+ end
15
+
16
+ def call(env)
17
+ # skip if machine is not running and the action is destroy, halt or suspend
18
+ return @app.call(env) if @machine.state.id != :running && [:destroy, :halt, :suspend].include?(env[:machine_action])
19
+ # skip if machine is not saved and the action is resume
20
+ return @app.call(env) if @machine.state.id != :saved && env[:machine_action] == :resume
21
+ # skip if machine is powered off and the action is resume or up
22
+ return @app.call(env) if @machine.state.id == :poweroff && [:resume, :up].include?(env[:machine_action])
23
+ # skip if machine is saved
24
+ return @app.call(env) if @machine.state.id == :saved
25
+
26
+ return @app.call(env) unless env[:machine].config.extended_storage.enabled?
27
+ @logger.info '** Creating Extended Storage Adapter **'
28
+
29
+ env[:ui].info I18n.t("vagrant_extended_storage.action.create_adapter")
30
+ env[:machine].provider.driver.create_adapter
31
+
32
+ @app.call(env)
33
+
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,50 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ module Action
6
+ class CreateStorage
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @machine = env[:machine]
11
+ @global_env = @machine.env
12
+ @provider = env[:provider]
13
+ @logger = Log4r::Logger.new('vagrant::extended_storage::action::create_storage')
14
+ end
15
+
16
+ def call(env)
17
+ # skip if machine is not running and the action is destroy, halt or suspend
18
+ return @app.call(env) if @machine.state.id != :running && [:destroy, :halt, :suspend].include?(env[:machine_action])
19
+ # skip if machine is not saved and the action is resume
20
+ return @app.call(env) if @machine.state.id != :saved && env[:machine_action] == :resume
21
+ # skip if machine is powered off and the action is resume
22
+ return @app.call(env) if @machine.state.id == :poweroff && env[:machine_action] == :resume
23
+ # skip if machine is saved
24
+ return @app.call(env) if @machine.state.id == :saved
25
+
26
+ return @app.call(env) unless env[:machine].config.extended_storage.enabled?
27
+
28
+ # check config to see if the disk should be created
29
+ return @app.call(env) unless env[:machine].config.extended_storage.create?
30
+
31
+ if File.exists?(File.expand_path(env[:machine].config.extended_storage.location))
32
+ @logger.info '** Extended Storage Volume exists, not creating **'
33
+ env[:ui].info I18n.t("vagrant_extended_storage.action.not_creating")
34
+ @app.call(env)
35
+
36
+ else
37
+ @logger.info '** Creating Extended Storage **'
38
+ env[:ui].info I18n.t("vagrant_extended_storage.action.create_storage")
39
+ location = env[:machine].config.extended_storage.location
40
+ size = env[:machine].config.extended_storage.size
41
+ env[:machine].provider.driver.create_storage(location, size)
42
+ @app.call(env)
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,34 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ module Action
6
+ class DetachStorage
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @machine = env[:machine]
11
+ @global_env = @machine.env
12
+ @provider = env[:provider]
13
+ @logger = Log4r::Logger.new('vagrant::extended_storage::action::detach_adapter')
14
+ end
15
+
16
+ def call(env)
17
+ # skip if machine is not saved and the action is resume
18
+ return @app.call(env) if @machine.state.id != :saved && env[:machine_action] == :resume
19
+
20
+ return @app.call(env) unless env[:machine].config.extended_storage.enabled?
21
+ @logger.info '** Detaching Extended Storage **'
22
+
23
+ env[:ui].info I18n.t("vagrant_extended_storage.action.detach_storage")
24
+ location = env[:machine].config.extended_storage.location
25
+ env[:machine].provider.driver.detach_storage(location)
26
+
27
+ @app.call(env)
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ require "log4r"
2
+ require 'vagrant-persistent-storage/manage_storage'
3
+
4
+ module VagrantPlugins
5
+ module ExtendedStorage
6
+ module Action
7
+ class ManageAll
8
+
9
+ include ManageStorage
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @machine = env[:machine]
14
+ @global_env = @machine.env
15
+ @provider = @machine.provider_name
16
+ @logger = Log4r::Logger.new('vagrant::extended_storage::action::manage_storage')
17
+ end
18
+
19
+ def call(env)
20
+ # skip if machine is not running and the action is destroy, halt or suspend
21
+ return @app.call(env) if @machine.state.id != :running && [:destroy, :halt, :suspend].include?(env[:machine_action])
22
+ # skip if machine is not saved and the action is resume
23
+ return @app.call(env) if @machine.state.id != :saved && env[:machine_action] == :resume
24
+ # skip if machine is powered off and the action is resume
25
+ return @app.call(env) if @machine.state.id == :poweroff && env[:machine_action] == :resume
26
+ # skip if machine is powered off and the action is resume
27
+ return @app.call(env) if @machine.state.id == :saved && env[:machine_action] == :resume
28
+
29
+ return @app.call(env) unless env[:machine].config.extended_storage.enabled?
30
+ return @app.call(env) unless env[:machine].config.extended_storage.manage?
31
+ @logger.info '** Managing Extended Storage **'
32
+
33
+ env[:ui].info I18n.t('vagrant_extended_storage.action.manage_storage')
34
+ machine = env[:machine]
35
+ manage_volumes(machine)
36
+
37
+ @app.call(env)
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,152 @@
1
+ require 'pathname'
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ class Config < Vagrant.plugin('2', :config)
6
+
7
+ attr_accessor :size
8
+ attr_accessor :create
9
+ attr_accessor :mount
10
+ attr_accessor :manage
11
+ attr_accessor :format
12
+ attr_accessor :enabled
13
+ attr_accessor :use_lvm
14
+ attr_accessor :location
15
+ attr_accessor :mountname
16
+ attr_accessor :mountpoint
17
+ attr_accessor :mountoptions
18
+ attr_accessor :diskdevice
19
+ attr_accessor :filesystem
20
+ attr_accessor :volgroupname
21
+ attr_accessor :drive_letter
22
+
23
+ alias_method :create?, :create
24
+ alias_method :mount?, :mount
25
+ alias_method :manage?, :manage
26
+ alias_method :format?, :format
27
+ alias_method :use_lvm?, :use_lvm
28
+ alias_method :enabled?, :enabled
29
+
30
+ def initialize
31
+ @size = UNSET_VALUE
32
+ @create = true
33
+ @mount = true
34
+ @manage = true
35
+ @format = true
36
+ @use_lvm = true
37
+ @enabled = false
38
+ @location = UNSET_VALUE
39
+ @mountname = UNSET_VALUE
40
+ @mountpoint = UNSET_VALUE
41
+ @mountoptions = UNSET_VALUE
42
+ @diskdevice = UNSET_VALUE
43
+ @filesystem = UNSET_VALUE
44
+ @volgroupname = UNSET_VALUE
45
+ @drive_letter = UNSET_VALUE
46
+ end
47
+
48
+ def finalize!
49
+ @size = 0 if @size == UNSET_VALUE
50
+ @create = true if @create == UNSET_VALUE
51
+ @mount = true if @mount == UNSET_VALUE
52
+ @manage = true if @manage == UNSET_VALUE
53
+ @format = true if @format == UNSET_VALUE
54
+ @use_lvm = true if @use_lvm == UNSET_VALUE
55
+ @enabled = false if @enabled == UNSET_VALUE
56
+ @location = 0 if @location == UNSET_VALUE
57
+ @mountname = 0 if @mountname == UNSET_VALUE
58
+ @mountpoint = 0 if @mountpoint == UNSET_VALUE
59
+ @mountoptions = 0 if @mountoptions == UNSET_VALUE
60
+ @diskdevice = 0 if @diskdevice == UNSET_VALUE
61
+ @filesystem = 0 if @filesystem == UNSET_VALUE
62
+ @volgroupname = 0 if @volgroupname == UNSET_VALUE
63
+ @drive_letter = 0 if @drive_letter == UNSET_VALUE
64
+ end
65
+
66
+ def validate(machine)
67
+ errors = []
68
+
69
+ errors << validate_bool('extended_storage.create', @create)
70
+ errors << validate_bool('extended_storage.mount', @mount)
71
+ errors << validate_bool('extended_storage.mount', @manage)
72
+ errors << validate_bool('extended_storage.mount', @format)
73
+ errors << validate_bool('extended_storage.mount', @use_lvm)
74
+ errors << validate_bool('extended_storage.mount', @enabled)
75
+ errors.compact!
76
+
77
+ if !machine.config.extended_storage.size.kind_of?(String)
78
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
79
+ :config_key => 'extended_storage.size',
80
+ :is_class => size.class.to_s,
81
+ })
82
+ end
83
+ if !machine.config.extended_storage.location.kind_of?(String)
84
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
85
+ :config_key => 'extended_storage.location',
86
+ :is_class => location.class.to_s,
87
+ })
88
+ end
89
+ if !machine.config.extended_storage.mountname.kind_of?(String)
90
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
91
+ :config_key => 'extended_storage.mountname',
92
+ :is_class => mountname.class.to_s,
93
+ })
94
+ end
95
+ if !machine.config.extended_storage.mountpoint.kind_of?(String)
96
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
97
+ :config_key => 'extended_storage.mountpoint',
98
+ :is_class => mountpoint.class.to_s,
99
+ })
100
+ end
101
+ if !machine.config.extended_storage.diskdevice.kind_of?(String)
102
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
103
+ :config_key => 'extended_storage.diskdevice',
104
+ :is_class => diskdevice.class.to_s,
105
+ })
106
+ end
107
+ if !machine.config.extended_storage.filesystem.kind_of?(String)
108
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
109
+ :config_key => 'extended_storage.filesystem',
110
+ :is_class => filesystem.class.to_s,
111
+ })
112
+ end
113
+ if !machine.config.extended_storage.volgroupname.kind_of?(String)
114
+ errors << I18n.t('vagrant_extended_storage.config.not_a_string', {
115
+ :config_key => 'extended_storage.volgroupname',
116
+ :is_class => volgroupname.class.to_s,
117
+ })
118
+ end
119
+
120
+ mount_point_path = Pathname.new("#{machine.config.extended_storage.location}")
121
+ if ! mount_point_path.absolute?
122
+ errors << I18n.t('vagrant_extended_storage.config.not_a_path', {
123
+ :config_key => 'extended_storage.location',
124
+ :is_path => location.class.to_s,
125
+ })
126
+ end
127
+
128
+ { 'Persistent Storage configuration' => errors }
129
+
130
+ if ! File.exists?@location.to_s and ! @create == "true"
131
+ return { "location" => ["file doesn't exist, and create set to false"] }
132
+ end
133
+ {}
134
+ end
135
+
136
+ private
137
+
138
+ def validate_bool(key, value)
139
+ if ![TrueClass, FalseClass].include?(value.class) &&
140
+ value != UNSET_VALUE
141
+ I18n.t('vagrant_extended_storage.config.not_a_bool', {
142
+ :config_key => key,
143
+ :value => value.class.to_s
144
+ })
145
+ else
146
+ nil
147
+ end
148
+ end
149
+
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,131 @@
1
+ require 'tempfile'
2
+ require 'fileutils'
3
+ require 'erb'
4
+
5
+ module VagrantPlugins
6
+ module ExtendedStorage
7
+ module ManageStorage
8
+ def populate_template(m)
9
+ mnt_name = m.config.extended_storage.mountname
10
+ mnt_point = m.config.extended_storage.mountpoint
11
+ mnt_options = m.config.extended_storage.mountoptions
12
+ vg_name = m.config.extended_storage.volgroupname
13
+ disk_dev = m.config.extended_storage.diskdevice
14
+ fs_type = m.config.extended_storage.filesystem
15
+ manage = m.config.extended_storage.manage
16
+ use_lvm = m.config.extended_storage.use_lvm
17
+ mount = m.config.extended_storage.mount
18
+ format = m.config.extended_storage.format
19
+
20
+ ## windows filesystem options
21
+ drive_letter = m.config.extended_storage.drive_letter
22
+
23
+ if m.config.vm.communicator == :winrm
24
+ os = "windows"
25
+ else
26
+ os = "linux"
27
+ end
28
+
29
+ vg_name = 'vps' unless vg_name != 0
30
+ disk_dev = '/dev/sdb' unless disk_dev != 0
31
+ mnt_name = 'vps' unless mnt_name != 0
32
+ mnt_options = ['defaults'] unless mnt_options != 0
33
+ fs_type = 'ext3' unless fs_type != 0
34
+ if use_lvm
35
+ device = "/dev/#{vg_name}/#{mnt_name}"
36
+ else
37
+ device = "#{disk_dev}1"
38
+ end
39
+ if drive_letter == 0
40
+ drive_letter = ""
41
+ else
42
+ drive_letter = "letter=#{drive_letter}"
43
+ end
44
+
45
+ if os == "windows"
46
+ ## shell script for windows to create NTFS partition and assign drive letter
47
+ disk_operations_template = ERB.new <<-EOF
48
+ <% if format == true %>
49
+ foreach ($disk in get-wmiobject Win32_DiskDrive -Filter "Partitions = 0"){
50
+ $disk.DeviceID
51
+ $disk.Index
52
+ "select disk "+$disk.Index+"`r clean`r create partition primary`r format fs=ntfs unit=65536 quick`r active`r assign #{drive_letter}" | diskpart >> disk_operation_log.txt
53
+ }
54
+ <% end %>
55
+ EOF
56
+ else
57
+ ## shell script to format disk, create/manage LVM, mount disk
58
+ disk_operations_template = ERB.new <<-EOF
59
+ #!/bin/bash
60
+ # fdisk the disk if it's not a block device already:
61
+ re='[0-9][.][0-9.]*[0-9.]*'; [[ $(sfdisk --version) =~ $re ]] && version="${BASH_REMATCH}"
62
+ if ! awk -v ver="$version" 'BEGIN { if (ver < 2.26 ) exit 1; }'; then
63
+ [ -b #{disk_dev}1 ] || echo 0,,8e | sfdisk #{disk_dev}
64
+ else
65
+ [ -b #{disk_dev}1 ] || echo ,,8e | sfdisk #{disk_dev}
66
+ fi
67
+ echo "fdisk returned: $?" >> disk_operation_log.txt
68
+
69
+ <% if use_lvm == true %>
70
+ # Create the physical volume if it doesn't already exist:
71
+ [[ `pvs #{disk_dev}1` ]] || pvcreate #{disk_dev}1
72
+ echo "pvcreate returned: $?" >> disk_operation_log.txt
73
+ # Extend the volume group :
74
+ vgextend #{vg_name} #{disk_dev}1
75
+ echo "vgextend returned: $?" >> disk_operation_log.txt
76
+ # Extend LVM:
77
+ lvextend #{device} #{disk_dev}1
78
+ echo "lvextend returned: $?" >> disk_operation_log.txt
79
+ # Resize on the fly
80
+ resize2fs #{device}
81
+ echo "resize2fs #{device} returned: $?" >> disk_operation_log.txt
82
+ # reserver 5%
83
+ tune2fs -m 5 /dev/mapper/#{vg_name}-#{mnt_name}
84
+ <% end %>
85
+
86
+ exit $?
87
+ EOF
88
+ end
89
+
90
+ buffer = disk_operations_template.result(binding)
91
+ tmp_script = Tempfile.new("disk_operations_#{mnt_name}.sh")
92
+
93
+ if os == 'windows'
94
+ target_script = "disk_operations_#{mnt_name}.ps1"
95
+ else
96
+ target_script = "/tmp/disk_operations_#{mnt_name}.sh"
97
+ end
98
+
99
+ File.open("#{tmp_script.path}", 'wb') do |f|
100
+ f.write buffer
101
+ end
102
+ m.communicate.upload(tmp_script.path, target_script)
103
+ unless os == 'windows'
104
+ m.communicate.sudo("chmod 755 #{target_script}")
105
+ end
106
+ end
107
+
108
+ def run_disk_operations(m)
109
+ return unless m.communicate.ready?
110
+ mnt_name = m.config.extended_storage.mountname
111
+ mnt_name = 'vps' unless mnt_name != 0
112
+ if m.config.vm.communicator == :winrm
113
+ target_script = "disk_operations_#{mnt_name}.ps1"
114
+ m.communicate.sudo("powershell -executionpolicy bypass -file #{target_script}")
115
+ else
116
+ target_script = "/tmp/disk_operations_#{mnt_name}.sh"
117
+ m.communicate.sudo("#{target_script}")
118
+ end
119
+
120
+ end
121
+
122
+ def manage_volumes(m)
123
+ populate_template(m)
124
+ if m.config.extended_storage.manage?
125
+ run_disk_operations(m)
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,62 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantPlugins
4
+ module ExtendedStorage
5
+ class Plugin < Vagrant.plugin('2')
6
+
7
+ include Vagrant::Action::Builtin
8
+
9
+ require_relative "action"
10
+ require_relative "providers/virtualbox/driver/base"
11
+ require_relative "providers/virtualbox/driver/meta"
12
+
13
+ name "extended_storage"
14
+ description <<-DESC
15
+ This plugin provides config to extend the root storage
16
+ DESC
17
+
18
+ config "extended_storage" do
19
+ require_relative "config"
20
+ Config
21
+ end
22
+
23
+ ## NB Currently only works with Virtualbox provider, due to hooks being used
24
+ action_hook(:extended_storage, :machine_action_up) do |hook|
25
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::SaneDefaults,
26
+ VagrantPlugins::ExtendedStorage::Action.create_adapter
27
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
28
+ VagrantPlugins::ExtendedStorage::Action.create_storage
29
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
30
+ VagrantPlugins::ExtendedStorage::Action.attach_storage
31
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::CheckGuestAdditions,
32
+ VagrantPlugins::ExtendedStorage::Action.manage_storage
33
+ hook.after VagrantPlugins::ExtendedStorage::Action.attach_storage,
34
+ VagrantPlugins::ExtendedStorage::Action.manage_storage
35
+ end
36
+
37
+ action_hook(:extended_storage, :machine_action_destroy) do |hook|
38
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::action_halt,
39
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
40
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Destroy,
41
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
42
+ end
43
+
44
+ action_hook(:extended_storage, :machine_action_halt) do |hook|
45
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::GracefulHalt,
46
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
47
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::ForcedHalt,
48
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
49
+ end
50
+
51
+ action_hook(:extended_storage, :machine_action_reload) do |hook|
52
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::GracefulHalt,
53
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
54
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::ForcedHalt,
55
+ VagrantPlugins::ExtendedStorage::Action.detach_storage
56
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
57
+ VagrantPlugins::ExtendedStorage::Action.attach_storage
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,104 @@
1
+ require "log4r"
2
+ require 'pathname'
3
+
4
+ module VagrantPlugins
5
+ module ProviderVirtualBox
6
+ module Driver
7
+ class Base
8
+
9
+ def create_adapter
10
+ controller_name = get_controller_name
11
+ if controller_name.nil?
12
+ controller_name = "SATA Controller"
13
+ execute("storagectl", @uuid, "--name", controller_name, "--" + ((@version.start_with?("4.3") || @version.start_with?("5.")) ? "" : "sata") + "portcount", "2", "--add", "sata")
14
+ else
15
+ execute("storagectl", @uuid, "--name", controller_name, "--" + ((@version.start_with?("4.3") || @version.start_with?("5.")) ? "" : "sata") + "portcount", "2")
16
+ end
17
+ end
18
+
19
+ def create_storage(location, size)
20
+ execute("createhd", "--filename", File.expand_path(location), "--size", "#{size}")
21
+ end
22
+
23
+ def attach_storage(location)
24
+ controller_name = get_controller_name
25
+ if controller_name.nil?
26
+ controller_name = "SATA Controller"
27
+ end
28
+
29
+ location_realpath = File.expand_path(location)
30
+
31
+ if controller_name.start_with?("IDE")
32
+ execute("storageattach", @uuid, "--storagectl", get_controller_name, "--port", "1", "--device", "0", "--type", "hdd", "--medium", "#{location_realpath}")
33
+ elsif controller_name.start_with?("SCSI")
34
+ execute("storageattach", @uuid, "--storagectl", get_controller_name, "--port", "15", "--device", "0", "--type", "hdd", "--medium", "#{location_realpath}")
35
+ else
36
+ execute("storageattach", @uuid, "--storagectl", get_controller_name, "--port", "4", "--device", "0", "--type", "hdd", "--medium", "#{location_realpath}", "--hotpluggable", "on")
37
+ end
38
+
39
+
40
+ end
41
+
42
+ def detach_storage(location)
43
+ location_realpath = File.expand_path(location)
44
+ extended_storage_data = read_extended_storage(location_realpath)
45
+ if location and extended_storage_data and identical_files(extended_storage_data.location, location_realpath)
46
+ execute("storageattach", @uuid, "--storagectl", extended_storage_data.controller, "--port", extended_storage_data.port, "--device", "0", "--type", "hdd", "--medium", "none")
47
+ end
48
+ end
49
+
50
+ def read_extended_storage(location)
51
+ ## Ensure previous operations are complete - bad practise yes, not sure how to avoid this:
52
+ sleep 3
53
+ storage_data = nil
54
+ controller_name = get_controller_name
55
+ info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
56
+ info.split("\n").each do |line|
57
+ tmp_storage_data = nil
58
+ tmp_storage_data = ExtendedStorageData.new(controller_name, $1, $3) if line =~ /^"#{controller_name}-(\d+)-(\d+)"="(.*)"/
59
+
60
+ if !tmp_storage_data.nil? and tmp_storage_data.location != 'none' and identical_files(File.expand_path(location), tmp_storage_data.location)
61
+ storage_data = tmp_storage_data
62
+ end
63
+ end
64
+ return storage_data
65
+ end
66
+
67
+ def identical_files(file1, file2)
68
+ return (File.exist?(file1) and File.exist?(file2) and File.identical?(Pathname.new(file1).realpath, Pathname.new(file2).realpath))
69
+ end
70
+
71
+ def get_controller_name
72
+ controller_number = nil
73
+ controllers = Hash.new
74
+ info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
75
+ info.split("\n").each do |line|
76
+ controllers[$1] = $2 if line =~ /^storagecontrollername(\d+)="(.*)"/
77
+ controller_number = $1 if line =~ /^storagecontrollertype(\d+)="(IntelAhci|PIIX4|LsiLogic)"/
78
+ end
79
+
80
+ if controller_number.nil?
81
+ return nil
82
+ end
83
+
84
+ return controllers[controller_number]
85
+ end
86
+
87
+ class ExtendedStorageData
88
+
89
+ attr_accessor :controller
90
+ attr_accessor :port
91
+ attr_accessor :location
92
+
93
+ def initialize(controller,port,location)
94
+ @controller = controller
95
+ @port = port
96
+ @location = location
97
+ end
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Driver
4
+ class Meta
5
+
6
+ def_delegators :@driver,
7
+ :create_storage,
8
+ :attach_storage,
9
+ :detach_storage,
10
+ :read_extended_storage
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module ExtendedStorage
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,12 @@
1
+ en:
2
+ vagrant_extended_storage:
3
+ action:
4
+ create_adapter: "** Creating adapter for extended storage **"
5
+ create_storage: "** Creating extendeded storage **"
6
+ not_creating: "** Extended Storage Volume exists, not creating **"
7
+ attach_storage: "** Attaching extended storage **"
8
+ detach_storage: "** Detaching extended storage **"
9
+ manage_storage: "** Managing extended storage **"
10
+ config:
11
+ not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'"
12
+ not_an_array_or_string: "A value for %{config_key} must be an Array or String, not type '%{is_class}'"
@@ -0,0 +1 @@
1
+ .vagrant
@@ -0,0 +1,26 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "precise32"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = "http://files.vagrantup.com/precise32.box"
15
+
16
+ # configure a Extended storage for mysql data
17
+ config.extended_storage.enabled = true
18
+ config.extended_storage.location = "virtualdrive.vdi"
19
+ config.extended_storage.size = 5000
20
+ config.extended_storage.mountname = 'mysql'
21
+ config.extended_storage.filesystem = 'ext4'
22
+ config.extended_storage.mountpoint = '/var/lib/mysql'
23
+ config.extended_storage.volgroupname = 'vg_os'
24
+ config.extended_storage.mountname = 'root'
25
+
26
+ end
@@ -0,0 +1,22 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "myWindowsBox"
11
+
12
+ # These are required for Windows machines running under vagrant
13
+ config.vm.communicator = "winrm"
14
+ config.winrm.username = "Administrator"
15
+ config.winrm.password = "Password!"
16
+
17
+ # configure a Extended storage for mysql data
18
+ config.extended_storage.enabled = true
19
+ config.extended_storage.location = "virtualdrive.vdi"
20
+ config.extended_storage.size = 5000
21
+
22
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-extended-storage/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "vagrant-extended-storage"
8
+ gem.version = VagrantPlugins::ExtendedStorage::VERSION
9
+ gem.authors = ["Nayeem Syed"]
10
+ gem.email = ["developerinlondon@gmail.com"]
11
+ gem.description = "A Vagrant plugin that extends the root storage by attaching a new volume and adding it to lvm"
12
+ gem.summary = "Vagrant Extended Storage Plugin"
13
+ gem.homepage = "https://github.com/developerinlondon/vagrant-extended-storage"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'rspec'
23
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-extended-storage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nayeem Syed
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A Vagrant plugin that extends the root storage by attaching a new volume
42
+ and adding it to lvm
43
+ email:
44
+ - developerinlondon@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - lib/vagrant-extended-storage.rb
54
+ - lib/vagrant-extended-storage/action.rb
55
+ - lib/vagrant-extended-storage/action/attach_storage.rb
56
+ - lib/vagrant-extended-storage/action/create_adapter.rb
57
+ - lib/vagrant-extended-storage/action/create_storage.rb
58
+ - lib/vagrant-extended-storage/action/detach_storage.rb
59
+ - lib/vagrant-extended-storage/action/manage_storage.rb
60
+ - lib/vagrant-extended-storage/config.rb
61
+ - lib/vagrant-extended-storage/manage_storage.rb
62
+ - lib/vagrant-extended-storage/plugin.rb
63
+ - lib/vagrant-extended-storage/providers/virtualbox/driver/base.rb
64
+ - lib/vagrant-extended-storage/providers/virtualbox/driver/meta.rb
65
+ - lib/vagrant-extended-storage/version.rb
66
+ - locales/en.yml
67
+ - sample-vm/.gitignore
68
+ - sample-vm/Vagrantfile
69
+ - sample-win-vm/Vagrantfile
70
+ - vagrant-extended-storage.gemspec
71
+ homepage: https://github.com/developerinlondon/vagrant-extended-storage
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.4.8
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Vagrant Extended Storage Plugin
95
+ test_files: []