diff --git a/README.md b/README.md index bbe6a291..f5d9eed9 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,9 @@ resources out yourself. * fs_type (Parameter) - The file system type. eg. ext3. * mkfs_cmd (Parameter) - Command to use to create the file system. Defaults to `mkswap` for `fs_type=swap`, otherwise `mkfs.{fs_type}` * options (Parameter) - Params for the mkfs command. eg. `-l internal,agcount=x` +* force (Parameter) Default value: `false` - Force the creation even if the FS exists and mounted. + - `true` + - `false` ### logical_volume diff --git a/lib/puppet/provider/filesystem/lvm.rb b/lib/puppet/provider/filesystem/lvm.rb index a5422f56..0e40a53d 100644 --- a/lib/puppet/provider/filesystem/lvm.rb +++ b/lib/puppet/provider/filesystem/lvm.rb @@ -3,27 +3,33 @@ confine kernel: :linux - commands blkid: 'blkid' + commands blkid: 'blkid', findmnt: 'findmnt', umount: 'umount' def create - mkfs(@resource[:fs_type], @resource[:name]) + mkfs(@resource[:fs_type], @resource[:name], @resource[:force]) end def exists? - fstype == @resource[:fs_type] + fstype(@resource[:name]) == @resource[:fs_type] end def destroy # no-op end - def fstype - %r{\bTYPE=\"(\S+)\"}.match(blkid(@resource[:name]))[1] + def fstype(name) + %r{\bTYPE=\"(\S+)\"}.match(blkid(name))[1] rescue Puppet::ExecutionFailure nil end - def mkfs(fs_type, name) + def mounted(name) + findmnt('-rno', 'SOURCE', name) + rescue Puppet::ExecutionFailure + false + end + + def mkfs(fs_type, name, force) mkfs_params = { 'reiserfs' => '-q', 'xfs' => '-f' } mkfs_cmd = !@resource[:mkfs_cmd].nil? ? @@ -46,6 +52,16 @@ def mkfs(fs_type, name) mkfs_cmd << mkfs_options end + current_fs_type = fstype(name) + unless current_fs_type.nil? + if [:true, true, 'true'].include?(force) + umount(name) if mounted(name) + info("#{name} will be umount and FS will be changed to #{fs_type} (currently #{current_fs_type})") + else + raise(Puppet::Error, "Changing FS type is destructive operation and it requires manual intervention (from #{current_fs_type} to #{fs_type}) or set force argument.") + end + end + execute mkfs_cmd if fs_type == 'swap' swap_cmd = ['swapon'] diff --git a/lib/puppet/type/filesystem.rb b/lib/puppet/type/filesystem.rb index df7ee245..917261ef 100644 --- a/lib/puppet/type/filesystem.rb +++ b/lib/puppet/type/filesystem.rb @@ -148,4 +148,10 @@ @parameters[:name].value end end + + newparam(:force) do + desc 'Force the FS type even if the FS is mounted.' + defaultto :false + newvalues(:true, :false) + end end diff --git a/spec/unit/puppet/provider/filesystem/lvm_spec.rb b/spec/unit/puppet/provider/filesystem/lvm_spec.rb index 323b080b..df32dacb 100644 --- a/spec/unit/puppet/provider/filesystem/lvm_spec.rb +++ b/spec/unit/puppet/provider/filesystem/lvm_spec.rb @@ -13,6 +13,7 @@ @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') @resource.expects(:[]).with(:fs_type).returns('ext4') @resource.expects(:[]).with(:options) + @resource.expects(:[]).with(:force).returns(:false) @provider.expects(:execute).with(['mkfs.ext4', '/dev/myvg/mylv']) @resource.expects(:[]).with(:mkfs_cmd) @provider.create @@ -21,6 +22,7 @@ @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') @resource.expects(:[]).with(:fs_type).returns('ext4') @resource.expects(:[]).with(:options).returns('-b 4096 -E stride=32,stripe-width=64').twice + @resource.expects(:[]).with(:force).returns(:false) @provider.expects(:execute).with(['mkfs.ext4', '/dev/myvg/mylv', ['-b', '4096', '-E', 'stride=32,stripe-width=64']]) @resource.expects(:[]).with(:mkfs_cmd) @provider.create @@ -29,14 +31,25 @@ @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') @resource.expects(:[]).with(:fs_type).returns('reiserfs') @resource.expects(:[]).with(:options).returns('-b 4096 -E stride=32,stripe-width=64').twice + @resource.expects(:[]).with(:force).returns(:false) @provider.expects(:execute).with(['mkfs.reiserfs', '/dev/myvg/mylv', '-q', ['-b', '4096', '-E', 'stride=32,stripe-width=64']]) @resource.expects(:[]).with(:mkfs_cmd) @provider.create end + it 'includes -f for xfs' do + @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') + @resource.expects(:[]).with(:fs_type).returns('xfs') + @resource.expects(:[]).with(:options).returns('-b 4096 -E stride=32,stripe-width=64').twice + @resource.expects(:[]).with(:force).returns(:false) + @provider.expects(:execute).with(['mkfs.xfs', '/dev/myvg/mylv', '-f', ['-b', '4096', '-E', 'stride=32,stripe-width=64']]) + @resource.expects(:[]).with(:mkfs_cmd) + @provider.create + end it 'calls mkswap for filesystem type swap' do @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') @resource.expects(:[]).with(:fs_type).returns('swap') @resource.expects(:[]).with(:options) + @resource.expects(:[]).with(:force).returns(:false) @provider.expects(:execute).with(['mkswap', '/dev/myvg/mylv']) @resource.expects(:[]).with(:mkfs_cmd) @provider.expects(:execute).with(['swapon', '/dev/myvg/mylv']) @@ -46,9 +59,22 @@ @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') @resource.expects(:[]).with(:fs_type).returns('jbd') @resource.expects(:[]).with(:options).returns('-O journal_dev').twice + @resource.expects(:[]).with(:force).returns(:false) @provider.expects(:execute).with(['mkfs.ext4', '/dev/myvg/mylv', ['-O', 'journal_dev']]) @resource.expects(:[]).with(:mkfs_cmd).returns('mkfs.ext4').twice @provider.create end end + + describe 'when creating with force' do + it "executes the 'mkfs.xfs' with force option" do + @resource.expects(:[]).with(:name).returns('/dev/myvg/mylv') + @resource.expects(:[]).with(:fs_type).returns('xfs') + @resource.expects(:[]).with(:force).returns(:true) + @resource.expects(:[]).with(:options) + @provider.expects(:execute).with(['mkfs.xfs', '/dev/myvg/mylv', '-f']) + @resource.expects(:[]).with(:mkfs_cmd) + @provider.create + end + end end