Add package_manifest resource.
authorDan Prince <dprince@redhat.com>
Mon, 20 Jul 2015 20:18:52 +0000 (16:18 -0400)
committerMartin Mágr <mmagr@redhat.com>
Thu, 3 Sep 2015 09:35:25 +0000 (11:35 +0200)
This patch converts the write_package_names function into
a proper resource. Using the write_package_names only works
if the function comes last in the puppet manifest. By
making the same functionality a custom resource we allow
for it to exist anywhere in the manifest and provide the
same functionality.

 The new syntax would be:

 package_manifest{'/tmp/foo': ensure => present}

Co-Authored-By: Martin Mágr <mmagr@redhat.com>
Change-Id: If3e03b1983fed47082fac8ce63f975557dbc503c

lib/puppet/parser/functions/write_package_names.rb [deleted file]
lib/puppet/provider/package_manifest/flat_file.rb [new file with mode: 0644]
lib/puppet/type/package_manifest.rb [new file with mode: 0644]
spec/unit/type/package_manifest_spec.rb [new file with mode: 0644]

diff --git a/lib/puppet/parser/functions/write_package_names.rb b/lib/puppet/parser/functions/write_package_names.rb
deleted file mode 100644 (file)
index 8f99674..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'fileutils'
-
-module Puppet::Parser::Functions
-  newfunction(:write_package_names, :doc => "Write package names which are managed via this puppet run to a file.") do |arg|
-    if arg[0].class == String
-      begin
-        output_file = arg[0]
-        packages = catalog.resources.collect { |r| r.title if r.type == 'Package' }.compact
-        FileUtils.mkdir_p(File.dirname(output_file))
-        File.open(output_file, 'w') do |f|
-            packages.each do |pkg_name|
-                f.write(pkg_name + "\n")
-            end
-        end
-      rescue JSON::ParserError
-        raise Puppet::ParseError, "Syntax error: #{arg[0]} is invalid"
-      end
-    else
-      raise Puppet::ParseError, "Syntax error: #{arg[0]} is not a String"
-    end
-  end
-end
diff --git a/lib/puppet/provider/package_manifest/flat_file.rb b/lib/puppet/provider/package_manifest/flat_file.rb
new file mode 100644 (file)
index 0000000..96e033b
--- /dev/null
@@ -0,0 +1,39 @@
+
+require 'set'
+
+
+Puppet::Type.type(:package_manifest).provide(:flat_file) do
+
+  desc "Write package manifest to a flat file"
+
+  def exists?
+    # exists? is always run before create, so we can create package list here
+    @packages = resource.catalog.resources.collect { |r|
+        r.name if r.type == :package
+    }.compact.sort
+
+    exists = File.exist?(resource[:path])
+    if exists
+      new_content = Set.new @packages
+      old_content = Set.new(
+        File.open(resource[:path], 'r').each_line.collect{ |pkg| pkg.strip() }
+      )
+      exists = new_content == old_content
+    end
+    exists
+  end
+
+  def create
+    FileUtils.mkdir_p(File.dirname(resource[:path]))
+    File.open(resource[:path], 'w') do |f|
+      @packages.each do |pkg_name|
+        f.puts(pkg_name)
+      end
+    end
+  end
+
+  def destroy
+    File.delete(resource[:path])
+  end
+
+end
diff --git a/lib/puppet/type/package_manifest.rb b/lib/puppet/type/package_manifest.rb
new file mode 100644 (file)
index 0000000..9ee3270
--- /dev/null
@@ -0,0 +1,8 @@
+Puppet::Type.newtype(:package_manifest) do
+
+  ensurable
+  newparam(:path, :namevar => true) do
+    newvalues(/\S+\/\S+/)
+  end
+
+end
diff --git a/spec/unit/type/package_manifest_spec.rb b/spec/unit/type/package_manifest_spec.rb
new file mode 100644 (file)
index 0000000..096564c
--- /dev/null
@@ -0,0 +1,37 @@
+
+require 'puppet'
+require 'puppet/type/package_manifest'
+
+describe 'Puppet::Type.type(:package_manifest)' do
+  before :each do
+    @manifest = Puppet::Type.type(:package_manifest).new(
+        :path => '/tmp/test_package_manifest.txt', :ensure => 'present'
+    )
+  end
+
+  it 'should require a path' do
+    expect {
+      Puppet::Type.type(:package_manifest).new({})
+  }.to raise_error Puppet::Error
+  end
+
+  it 'should not require a value when ensure is absent' do
+    Puppet::Type.type(:package_manifest).new(
+        :path => '/tmp/test_package_manifest.txt', :ensure => :absent
+    )
+  end
+
+  it 'should accept valid ensure values' do
+    @manifest[:ensure] = :present
+    expect(@manifest[:ensure]).to eq(:present)
+    @manifest[:ensure] = :absent
+    expect(@manifest[:ensure]).to eq(:absent)
+  end
+
+  it 'should not accept invalid ensure values' do
+    expect {
+      @manifest[:ensure] = :latest
+    }.to raise_error(Puppet::Error, /Invalid value/)
+  end
+
+end