Skip to content

Commit

Permalink
add class udev::rule to manage device rule files
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Hoblitt committed Sep 19, 2013
1 parent 112ebab commit 8e79572
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 1 deletion.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,16 @@ Usage
include udev
```

### Manually trigging a udev rules reload
### Manage a `udev` rule

```puppet
udev::rule { '60-raw.rules':
ensure => present,
content => 'ACTION=="add", KERNEL=="sda", RUN+="/bin/raw /dev/raw/raw1 %N"',
}
```

### Manually trigging a `udev` device rules reload

```puppet
file { '/etc/etc/udev/rules.d/99-myfrobnicator.rules':
Expand Down
89 changes: 89 additions & 0 deletions manifests/rule.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# == Define: udev::rule
#
# Manage a udev rules file and trigger udev to reload it's device rules upon
# modification.
#
# === Parameters
#
# Note that either *content* or *source* must be specified unless *ensure* is
# 'absent'.
#
# [*ensure*]
#
# String. Possible values: 'present', 'absent'
#
# Controls the state of the udev rule file.
#
# Default: 'present'
#
# [*content*]
#
# String.
#
# A literal string of the content that is to appear in udev rule file. This
# parameter is mutually exclusive with *source*.
#
# Default: undef
#
# [*source*]
#
# String.
#
# The URI to pull the udev rule file content from. This parameter is mutually
# exclusive with *content*. Eg. 'puppet:///modules/mysite/myrule.rules'.
#
# Default: undef
#
#
# === Example
#
define udev::rule(
$ensure = present,
$content = undef,
$source = undef,
) {
validate_re($ensure, '^present$|^absent$')

include udev

# only $source or $content are allowed
if $source {
validate_string($source)

if $content {
fail("${title}: parameters \$source and \$content are mutually exclusive")
}

$safe_source = { source => $source }
} elsif $content {
validate_string($content)

if $source {
fail("${title}: parameters \$source and \$content are mutually exclusive")
}

$safe_content = { content => $content }
} else {
# one of $source or $content is required unless we're removing the file,
if $ensure != 'absent' {
fail("${title}: parameter \$source or \$content is required")
}
}

$config = {
ensure => $ensure,
owner => 'root',
group => 'root',
mode => '0644',
notify => Class['udev::udevadm'],
}

$safe_config = merge(
$config,
$safe_source,
$safe_content
)

create_resources( 'file', { "/etc/udev/rules.d/${title}" => $safe_config } )

}
152 changes: 152 additions & 0 deletions spec/defines/rule_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
require 'spec_helper'

describe 'udev::rule', :type => :define do

shared_examples 'generic_rule' do |title, state, params|
let(:title) { title }
let(:params) { params }

it do
should include_class('udev')
should contain_file("/etc/udev/rules.d/#{title}").with({
:ensure => state,
:owner => 'root',
:group => 'root',
:mode => '0644',
:source => params[:source],
:content => params[:content],
# XXX figure out how to properly test metaparams...
#:notify => 'Class[Udev::Udevadm]{:name=>"Udev::Udevadm"}',
})
end
end


describe 'for osfamily RedHat' do
let(:facts) {{ :osfamily => 'RedHat' }}

describe 'content => foo' do
it_behaves_like(
'generic_rule',
'99-foo.rules',
'present',
{ :content => 'foo' }
)
end

describe 'ensure => present, content => foo' do
it_behaves_like(
'generic_rule',
'99-foo.rules',
'present',
{ :ensure => 'present', :content => 'foo' }
)
end

describe 'source => foo' do
it_behaves_like(
'generic_rule',
'99-foo.rules',
'present',
{ :source => 'foo' }
)
end

describe 'ensure => present, source => foo' do
it_behaves_like(
'generic_rule',
'99-foo.rules',
'present',
{ :ensure => 'present', :source => 'foo' }
)
end

describe 'ensure => absent' do
it_behaves_like(
'generic_rule',
'99-foo.rules',
'absent',
{
:ensure => 'absent',
}
)
end

describe 'no params' do
let(:title) { '99-foo.rules' }

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /parameter \$source or \$content is required/)
end
end

describe 'content => foo, source => foo' do
let(:title) { '99-foo.rules' }
let :params do
{
:content => 'foo',
:source => 'foo',
}
end

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /parameters \$source and \$content are mutually exclusive/)
end
end

describe 'ensure => absent, content => foo, source => foo' do
let(:title) { '99-foo.rules' }
let :params do
{
:ensure => 'absent',
:content => 'foo',
:source => 'foo',
}
end

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /parameters \$source and \$content are mutually exclusive/)
end
end

describe 'ensure => invalid' do
let(:title) { '99-foo.rules' }
let(:params) {{ :ensure => 'invalid' }}

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /does not match/)
end
end

describe 'content => true' do
let(:title) { '99-foo.rules' }
let(:params) {{ :content => true }}

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /is not a string/)
end
end

describe 'source => true' do
let(:title) { '99-foo.rules' }
let(:params) {{ :source => true }}

it 'should fail' do
expect {
should include_class('udev')
}.to raise_error(Puppet::Error, /is not a string/)
end
end

end
end

0 comments on commit 8e79572

Please sign in to comment.