cjscp-vagrant-persistent-storage 0.0.27

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 345c86f292ea94b18c956ab28c5c1395e1480660
4
+ data.tar.gz: 5ffa2334fa1e443182b970fd4743f50dbad0b944
5
+ SHA512:
6
+ metadata.gz: 9cdcd702ae04f959032f4179a89a9bd5c1cba39397f6a591fd81d94cd37c822260ac482adf2e58b06d8d70c7f2e2b97fee4683196bf18f18df6e87a6ca13d577
7
+ data.tar.gz: 397da654e0091fa52babae060ddcb1e59044c7a839140dc0442e8a98a477f7a625b16a67fe38268290f4b8db8d4d931bc50ac210941f98c29aaa4261f86998c1
@@ -0,0 +1 @@
1
+ *.gem
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.
@@ -0,0 +1,92 @@
1
+ # Vagrant::Persistent-Storage
2
+
3
+ A Vagrant plugin that creates a persistent storage and attaches it to guest machine.
4
+
5
+ Requires Virtualbox 5
6
+
7
+ ## Installation
8
+
9
+ $ vagrant plugin install vagrant-persistent-storage
10
+
11
+ ## Usage
12
+
13
+ After installing you can set the location and size of the persistent storage.
14
+
15
+ The following options will create a persistent storage with 5000 MB, named mysql,
16
+ mounted on /var/lib/mysql, in a volume group called 'vagrant'
17
+ ```ruby
18
+ config.persistent_storage.enabled = true
19
+ config.persistent_storage.location = "~/development/sourcehdd.vdi"
20
+ config.persistent_storage.size = 5000
21
+ config.persistent_storage.mountname = 'mysql'
22
+ config.persistent_storage.filesystem = 'ext4'
23
+ config.persistent_storage.mountpoint = '/var/lib/mysql'
24
+ config.persistent_storage.volgroupname = 'myvolgroup'
25
+ ```
26
+
27
+ With `config.persistent_storage.mountoptions` you can change the mount options (default: defaults).
28
+ A example which sets `prjquota` option with xfs.
29
+ ```ruby
30
+ config.persistent_storage.mountname = 'xfs'
31
+ config.persistent_storage.filesystem = 'xfs'
32
+ config.persistent_storage.mountpoint = '/mnt/xfs'
33
+ config.persistent_storage.mountoptions = ['defaults', 'prjquota']
34
+ ```
35
+
36
+ Device defaults to `/dev/sdb`. For boxes with multiple disks, make sure you increment the drive:
37
+ ```
38
+ config.persistent_storage.diskdevice = '/dev/sdc'
39
+ ```
40
+
41
+ Every `vagrant up` will attach this file as hard disk to the guest machine.
42
+ An `vagrant destroy` will detach the storage to avoid deletion of the storage by vagrant.
43
+ A `vagrant destroy` generally destroys all attached drives. See [VBoxMange unregistervm --delete option][vboxmanage_delete].
44
+
45
+ The disk is initialized and added to it's own volume group as specfied in the config;
46
+ this defaults to 'vagrant'. An ext4 filesystem is created and the disk mounted appropriately,
47
+ with entries added to fstab ... subsequent runs will mount this disk with the options specified
48
+
49
+ ## Windows Guests
50
+
51
+ Windows Guests must use the WinRM communicator by setting `vm.communicator = 'winrm'`. An additional option is provided to
52
+ allow you to set the drive letter using:
53
+
54
+ ```
55
+ config.persistent_storage.drive_letter = 'Z'
56
+ ```
57
+
58
+ Options that are irrelevent to Windows are ignored, such as `mountname`, `filesystem`, `mountpoint` and `volgroupname`.
59
+
60
+ ## Troubleshooting
61
+
62
+ If your box are not using LVM you must set `config.persistent_storage.use_lvm = false`.
63
+
64
+ ## Supported Providers
65
+
66
+ * Only the VirtualBox provider is supported.
67
+
68
+ ## Contributors
69
+
70
+ * [madAndroid](https://github.com/madAndroid)
71
+ * [Jeremiah Snapp](https://github.com/jeremiahsnapp)
72
+ * [Hiroya Ito](https://github.com/hiboma)
73
+ * [joshuata](https://github.com/joshuata)
74
+ * [Ciprian Zaharie](https://github.com/bucatzel)
75
+ * [aishahalim](https://github.com/aishahalim)
76
+ * [Dick Tang](https://github.com/dictcp)
77
+ * [dsmaher](https://github.com/dsmaher)
78
+ * [Marsup](https://github.com/Marsup)
79
+ * [k2s](https://github.com/k2s)
80
+ * [vvavrychuk](https://github.com/vvavrychuk)
81
+ * [Lars Hupfeldt Nielsen](https://github.com/lhupfeldt)
82
+ * [Chen Yu Pao](https://github.com/windperson)
83
+ * [Kris Reese](https://github.com/ktreese)
84
+ * [Henry N.](https://github.com/HenryNe)
85
+
86
+ ## TODO
87
+
88
+ * There's Always Something to Do
89
+ * Add more options (controller, port, etc.)
90
+
91
+
92
+ [vboxmanage_delete]: http://www.virtualbox.org/manual/ch08.html#vboxmanage-registervm "VBoxManage registervm / unregistervm"
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ Bundler::GemHelper.install_tasks
4
+
@@ -0,0 +1,13 @@
1
+ require 'vagrant-persistent-storage/plugin'
2
+ require 'vagrant-persistent-storage/version'
3
+
4
+ module VagrantPlugins
5
+ module PersistentStorage
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 PersistentStorage
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 PersistentStorage
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::persistentstorage::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.persistent_storage.enabled?
23
+ @logger.info '** Attaching Persistent Storage **'
24
+
25
+ env[:ui].info I18n.t("vagrant_persistent_storage.action.attach_storage")
26
+ location = env[:machine].config.persistent_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 PersistentStorage
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::persistent_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.persistent_storage.enabled?
27
+ @logger.info '** Creating Persistent Storage Adapter **'
28
+
29
+ env[:ui].info I18n.t("vagrant_persistent_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 PersistentStorage
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::persistent_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.persistent_storage.enabled?
27
+
28
+ # check config to see if the disk should be created
29
+ return @app.call(env) unless env[:machine].config.persistent_storage.create?
30
+
31
+ if File.exists?(File.expand_path(env[:machine].config.persistent_storage.location))
32
+ @logger.info '** Persistent Storage Volume exists, not creating **'
33
+ env[:ui].info I18n.t("vagrant_persistent_storage.action.not_creating")
34
+ @app.call(env)
35
+
36
+ else
37
+ @logger.info '** Creating Persistent Storage **'
38
+ env[:ui].info I18n.t("vagrant_persistent_storage.action.create_storage")
39
+ location = env[:machine].config.persistent_storage.location
40
+ size = env[:machine].config.persistent_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 PersistentStorage
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::persistent_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.persistent_storage.enabled?
21
+ @logger.info '** Detaching Persistent Storage **'
22
+
23
+ env[:ui].info I18n.t("vagrant_persistent_storage.action.detach_storage")
24
+ location = env[:machine].config.persistent_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 PersistentStorage
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::persistent_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.persistent_storage.enabled?
30
+ return @app.call(env) unless env[:machine].config.persistent_storage.manage?
31
+ @logger.info '** Managing Persistent Storage **'
32
+
33
+ env[:ui].info I18n.t('vagrant_persistent_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 PersistentStorage
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('persistent_storage.create', @create)
70
+ errors << validate_bool('persistent_storage.mount', @mount)
71
+ errors << validate_bool('persistent_storage.mount', @manage)
72
+ errors << validate_bool('persistent_storage.mount', @format)
73
+ errors << validate_bool('persistent_storage.mount', @use_lvm)
74
+ errors << validate_bool('persistent_storage.mount', @enabled)
75
+ errors.compact!
76
+
77
+ if !machine.config.persistent_storage.size.kind_of?(String)
78
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
79
+ :config_key => 'persistent_storage.size',
80
+ :is_class => size.class.to_s,
81
+ })
82
+ end
83
+ if !machine.config.persistent_storage.location.kind_of?(String)
84
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
85
+ :config_key => 'persistent_storage.location',
86
+ :is_class => location.class.to_s,
87
+ })
88
+ end
89
+ if !machine.config.persistent_storage.mountname.kind_of?(String)
90
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
91
+ :config_key => 'persistent_storage.mountname',
92
+ :is_class => mountname.class.to_s,
93
+ })
94
+ end
95
+ if !machine.config.persistent_storage.mountpoint.kind_of?(String)
96
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
97
+ :config_key => 'persistent_storage.mountpoint',
98
+ :is_class => mountpoint.class.to_s,
99
+ })
100
+ end
101
+ if !machine.config.persistent_storage.diskdevice.kind_of?(String)
102
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
103
+ :config_key => 'persistent_storage.diskdevice',
104
+ :is_class => diskdevice.class.to_s,
105
+ })
106
+ end
107
+ if !machine.config.persistent_storage.filesystem.kind_of?(String)
108
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
109
+ :config_key => 'persistent_storage.filesystem',
110
+ :is_class => filesystem.class.to_s,
111
+ })
112
+ end
113
+ if !machine.config.persistent_storage.volgroupname.kind_of?(String)
114
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_string', {
115
+ :config_key => 'persistent_storage.volgroupname',
116
+ :is_class => volgroupname.class.to_s,
117
+ })
118
+ end
119
+
120
+ mount_point_path = Pathname.new("#{machine.config.persistent_storage.location}")
121
+ if ! mount_point_path.absolute?
122
+ errors << I18n.t('vagrant_persistent_storage.config.not_a_path', {
123
+ :config_key => 'persistent_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_persistent_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,149 @@
1
+ require 'tempfile'
2
+ require 'fileutils'
3
+ require 'erb'
4
+
5
+ module VagrantPlugins
6
+ module PersistentStorage
7
+ module ManageStorage
8
+ def populate_template(m)
9
+ mnt_name = m.config.persistent_storage.mountname
10
+ mnt_point = m.config.persistent_storage.mountpoint
11
+ mnt_options = m.config.persistent_storage.mountoptions
12
+ vg_name = m.config.persistent_storage.volgroupname
13
+ disk_dev = m.config.persistent_storage.diskdevice
14
+ fs_type = m.config.persistent_storage.filesystem
15
+ manage = m.config.persistent_storage.manage
16
+ use_lvm = m.config.persistent_storage.use_lvm
17
+ mount = m.config.persistent_storage.mount
18
+ format = m.config.persistent_storage.format
19
+
20
+ ## windows filesystem options
21
+ drive_letter = m.config.persistent_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
+ # Create the volume group if it doesn't already exist:
74
+ [[ `vgs #{vg_name}` ]] || vgcreate #{vg_name} #{disk_dev}1
75
+ echo "vgcreate returned: $?" >> disk_operation_log.txt
76
+ # Create the logical volume if it doesn't already exist:
77
+ [[ `lvs #{vg_name} | grep #{mnt_name}` ]] || lvcreate -l 100%FREE -n #{mnt_name} #{vg_name}
78
+ echo "lvcreate returned: $?" >> disk_operation_log.txt
79
+ # Activate the volume group if it's inactive:
80
+ [[ `lvs #{vg_name} --noheadings --nameprefixes | grep LVM2_LV_ATTR | grep "wi\-a"` ]] || vgchange #{vg_name} -a y
81
+ echo "vg activation returned: $?" >> disk_operation_log.txt
82
+ <% end %>
83
+
84
+ <% if format == true %>
85
+ # Create the filesytem if it doesn't already exist
86
+ MNT_NAME=#{mnt_name}
87
+ [[ `blkid | grep ${MNT_NAME:0:16} | grep #{fs_type}` ]] || mkfs.#{fs_type} -L #{mnt_name} #{device}
88
+ echo "#{fs_type} creation return: $?" >> disk_operation_log.txt
89
+ <% if mount == true %>
90
+ # if directory already exists, then copy over the contents into the new directory
91
+ [ -d #{mnt_point} ] && mv #{mnt_point} #{mnt_point}_orig
92
+ # Create mountpoint #{mnt_point}
93
+ [ -d #{mnt_point} ] || mkdir -p #{mnt_point}
94
+ # Update fstab with new mountpoint name
95
+ [[ `grep -i #{device} /etc/fstab` ]] || echo #{device} #{mnt_point} #{fs_type} #{mnt_options.join(',')} 0 0 >> /etc/fstab
96
+ echo "fstab update returned: $?" >> disk_operation_log.txt
97
+ # Finally, mount the partition
98
+ [[ `mount | grep #{mnt_point}` ]] || mount #{mnt_point}
99
+ echo "#{mnt_point} mounting returned: $?" >> disk_operation_log.txt
100
+ # if we copied over the orig directory then copy its contents back
101
+ [ -d #{mnt_point}_orig ] && cp -frp #{mnt_point}_orig/* #{mnt_point}/ && rm -fr #{mnt_point}_orig
102
+ <% end %>
103
+ <% end %>
104
+ exit $?
105
+ EOF
106
+ end
107
+
108
+ buffer = disk_operations_template.result(binding)
109
+ tmp_script = Tempfile.new("disk_operations_#{mnt_name}.sh")
110
+
111
+ if os == 'windows'
112
+ target_script = "disk_operations_#{mnt_name}.ps1"
113
+ else
114
+ target_script = "/tmp/disk_operations_#{mnt_name}.sh"
115
+ end
116
+
117
+ File.open("#{tmp_script.path}", 'wb') do |f|
118
+ f.write buffer
119
+ end
120
+ m.communicate.upload(tmp_script.path, target_script)
121
+ unless os == 'windows'
122
+ m.communicate.sudo("chmod 755 #{target_script}")
123
+ end
124
+ end
125
+
126
+ def run_disk_operations(m)
127
+ return unless m.communicate.ready?
128
+ mnt_name = m.config.persistent_storage.mountname
129
+ mnt_name = 'vps' unless mnt_name != 0
130
+ if m.config.vm.communicator == :winrm
131
+ target_script = "disk_operations_#{mnt_name}.ps1"
132
+ m.communicate.sudo("powershell -executionpolicy bypass -file #{target_script}")
133
+ else
134
+ target_script = "/tmp/disk_operations_#{mnt_name}.sh"
135
+ m.communicate.sudo("#{target_script}")
136
+ end
137
+
138
+ end
139
+
140
+ def manage_volumes(m)
141
+ populate_template(m)
142
+ if m.config.persistent_storage.manage?
143
+ run_disk_operations(m)
144
+ end
145
+ end
146
+
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,62 @@
1
+ require 'vagrant'
2
+
3
+ module VagrantPlugins
4
+ module PersistentStorage
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 "persistent_storage"
14
+ description <<-DESC
15
+ This plugin provides config to attach persistent storage
16
+ DESC
17
+
18
+ config "persistent_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(:persistent_storage, :machine_action_up) do |hook|
25
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::SaneDefaults,
26
+ VagrantPlugins::PersistentStorage::Action.create_adapter
27
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
28
+ VagrantPlugins::PersistentStorage::Action.create_storage
29
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
30
+ VagrantPlugins::PersistentStorage::Action.attach_storage
31
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::CheckGuestAdditions,
32
+ VagrantPlugins::PersistentStorage::Action.manage_storage
33
+ hook.after VagrantPlugins::PersistentStorage::Action.attach_storage,
34
+ VagrantPlugins::PersistentStorage::Action.manage_storage
35
+ end
36
+
37
+ action_hook(:persistent_storage, :machine_action_destroy) do |hook|
38
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::action_halt,
39
+ VagrantPlugins::PersistentStorage::Action.detach_storage
40
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Destroy,
41
+ VagrantPlugins::PersistentStorage::Action.detach_storage
42
+ end
43
+
44
+ action_hook(:persistent_storage, :machine_action_halt) do |hook|
45
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::GracefulHalt,
46
+ VagrantPlugins::PersistentStorage::Action.detach_storage
47
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::ForcedHalt,
48
+ VagrantPlugins::PersistentStorage::Action.detach_storage
49
+ end
50
+
51
+ action_hook(:persistent_storage, :machine_action_reload) do |hook|
52
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::GracefulHalt,
53
+ VagrantPlugins::PersistentStorage::Action.detach_storage
54
+ hook.after VagrantPlugins::ProviderVirtualBox::Action::ForcedHalt,
55
+ VagrantPlugins::PersistentStorage::Action.detach_storage
56
+ hook.before VagrantPlugins::ProviderVirtualBox::Action::Boot,
57
+ VagrantPlugins::PersistentStorage::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
+ persistent_storage_data = read_persistent_storage(location_realpath)
45
+ if location and persistent_storage_data and identical_files(persistent_storage_data.location, location_realpath)
46
+ execute("storageattach", @uuid, "--storagectl", persistent_storage_data.controller, "--port", persistent_storage_data.port, "--device", "0", "--type", "hdd", "--medium", "none")
47
+ end
48
+ end
49
+
50
+ def read_persistent_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 = PersistentStorageData.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 PersistentStorageData
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_persistent_storage
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module PersistentStorage
3
+ VERSION = "0.0.27"
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ en:
2
+ vagrant_persistent_storage:
3
+ action:
4
+ create_adapter: "** Creating adapter for persistent storage **"
5
+ create_storage: "** Creating persistent storage **"
6
+ not_creating: "** Persistent Storage Volume exists, not creating **"
7
+ attach_storage: "** Attaching persistent storage **"
8
+ detach_storage: "** Detaching persistent storage **"
9
+ manage_storage: "** Managing persistent 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,25 @@
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 persistent storage for mysql data
17
+ config.persistent_storage.enabled = true
18
+ config.persistent_storage.location = "virtualdrive.vdi"
19
+ config.persistent_storage.size = 5000
20
+ config.persistent_storage.mountname = 'mysql'
21
+ config.persistent_storage.filesystem = 'ext4'
22
+ config.persistent_storage.mountpoint = '/var/lib/mysql'
23
+ config.persistent_storage.volgroupname = 'myvolgroup'
24
+
25
+ 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 persistent storage for mysql data
18
+ config.persistent_storage.enabled = true
19
+ config.persistent_storage.location = "virtualdrive.vdi"
20
+ config.persistent_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-persistent-storage/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cjscp-vagrant-persistent-storage"
8
+ gem.version = VagrantPlugins::PersistentStorage::VERSION
9
+ gem.authors = ["Sebastian Kusnier","Nayeem Syed"]
10
+ gem.email = ["sebastian@kusnier.net","developerinlondon@gmail.com"]
11
+ gem.description = "A Vagrant plugin that creates a persistent storage and attaches it to guest machine. (cjscp version)"
12
+ gem.summary = gem.description
13
+ gem.homepage = "https://github.com/CJSCommonPlatform/vagrant-persistent-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,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cjscp-vagrant-persistent-storage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.27
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Kusnier
8
+ - Nayeem Syed
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-05-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description: A Vagrant plugin that creates a persistent storage and attaches it to
43
+ guest machine. (cjscp version)
44
+ email:
45
+ - sebastian@kusnier.net
46
+ - developerinlondon@gmail.com
47
+ executables: []
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".gitignore"
52
+ - Gemfile
53
+ - LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - lib/vagrant-persistent-storage.rb
57
+ - lib/vagrant-persistent-storage/action.rb
58
+ - lib/vagrant-persistent-storage/action/attach_storage.rb
59
+ - lib/vagrant-persistent-storage/action/create_adapter.rb
60
+ - lib/vagrant-persistent-storage/action/create_storage.rb
61
+ - lib/vagrant-persistent-storage/action/detach_storage.rb
62
+ - lib/vagrant-persistent-storage/action/manage_storage.rb
63
+ - lib/vagrant-persistent-storage/config.rb
64
+ - lib/vagrant-persistent-storage/manage_storage.rb
65
+ - lib/vagrant-persistent-storage/plugin.rb
66
+ - lib/vagrant-persistent-storage/providers/virtualbox/driver/base.rb
67
+ - lib/vagrant-persistent-storage/providers/virtualbox/driver/meta.rb
68
+ - lib/vagrant-persistent-storage/version.rb
69
+ - locales/en.yml
70
+ - sample-vm/.gitignore
71
+ - sample-vm/Vagrantfile
72
+ - sample-win-vm/Vagrantfile
73
+ - vagrant-persistent-storage.gemspec
74
+ homepage: https://github.com/CJSCommonPlatform/vagrant-persistent-storage
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.4.8
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: A Vagrant plugin that creates a persistent storage and attaches it to guest
98
+ machine. (cjscp version)
99
+ test_files: []