vagrant-extended-storage 0.0.1

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.
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: []