puppet-library 0.13.0 → 0.14.0

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 CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- data.tar.gz: 52a2fcf7cb4121ce34d56a978c220b0608654351
4
- metadata.gz: afdccfcce7d2c23cae0cb1c429f687c3cf6b0ba8
5
- SHA512:
6
- data.tar.gz: dacbade142357d35f0cd154a8a401a52c855fc0df5f2c0f5ed8d450b89e026475e3f5bfdf6e0a074e820d1c8fa702d8e586c84906b0b0a05f7096a71acdd0a34
7
- metadata.gz: e268f15fe38c6c8c8d41877dd70cf3d5b38092cffd6adc0f5b2592bfcbdd82b4eb46dcc034d4c8955f273a18ca41747d73637aa36f752625247bb14f334e4a49
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce0573aac08832b970f50871291d13f4487e8495
4
+ data.tar.gz: d5f1fd926455ca4fbb87c7570797b002b0cf4bca
5
+ SHA512:
6
+ metadata.gz: 123f603ff5ec60ec88f41bb7120e338e83e349e4d566dd11a1be46be406ae5f170577203d7c21a46eb7ed426da02ef25f71304d843cfb3589d84465a6d038961
7
+ data.tar.gz: 948cc9e9a048709d05ec1d53a9b2c0d90225d9b0026383fa48afc5f3ee442f1ebc08bcf62deaee591e7c50ca5e6218e0295007da0e57e140cce67c377590ba48
data/.gitignore CHANGED
@@ -4,7 +4,6 @@
4
4
  .bundle
5
5
  .config
6
6
  .yardoc
7
- Gemfile.lock
8
7
  InstalledFiles
9
8
  _yardoc
10
9
  coverage
@@ -17,3 +16,4 @@ test/tmp
17
16
  test/version_tmp
18
17
  tmp
19
18
  .rake_t_cache
19
+ /Gemfile.lock
data/CHANGELOG.yml CHANGED
@@ -91,3 +91,9 @@
91
91
  - tag: v0.13.0
92
92
  changes:
93
93
  - Fixed "Invalid gemspec" error (#5)
94
+ - tag: v0.14.0
95
+ changes:
96
+ - Use `metadata.json` in place of `Modulefile` if it exists (and `Modulefile` doesn't exist)
97
+ - Ignore corrupt module files on disk
98
+ - Added logging for when module files can't be read from disk
99
+ - Recurse into module directories when serving modules from disk
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  A private Puppet Forge. Compatible with [librarian-puppet](http://librarian-puppet.com).
4
4
 
5
- [![Build Status](https://travis-ci.org/drrb/puppet-library.png?branch=master)](https://travis-ci.org/drrb/puppet-library)
6
- [![Coverage Status](https://coveralls.io/repos/drrb/puppet-library/badge.png)](https://coveralls.io/r/drrb/puppet-library)
7
- [![Code Climate](https://codeclimate.com/github/drrb/puppet-library.png)](https://codeclimate.com/github/drrb/puppet-library)
5
+ [![Build Status](https://api.travis-ci.org/drrb/puppet-library.svg)](https://travis-ci.org/drrb/puppet-library)
6
+ [![Coverage Status](https://img.shields.io/coveralls/drrb/puppet-library.svg)](https://coveralls.io/r/drrb/puppet-library)
7
+ [![Code Climate](https://img.shields.io/codeclimate/github/drrb/puppet-library.svg)](https://codeclimate.com/github/drrb/puppet-library)
8
8
 
9
- [![Gem Version](https://badge.fury.io/rb/puppet-library.png)](http://badge.fury.io/rb/puppet-library)
10
- [![Dependency Status](https://gemnasium.com/drrb/puppet-library.png)](https://gemnasium.com/drrb/puppet-library)
9
+ [![Gem Version](https://badge.fury.io/rb/puppet-library.svg)](http://badge.fury.io/rb/puppet-library)
10
+ [![Dependency Status](https://gemnasium.com/drrb/puppet-library.svg)](https://gemnasium.com/drrb/puppet-library)
11
11
 
12
12
  Puppet Library serves Puppet modules in the same format as [the Puppet Forge](http://forge.puppetlabs.com). This allows you to create a private Puppet Forge and manage all the modules you use completely within your infrastructure.
13
13
 
@@ -18,6 +18,10 @@ Plugins can be created to serve modules from arbitrary sources. Puppet Library c
18
18
  - serving modules from source on disk
19
19
  - serving modules from Git repositories using tags as version numbers!
20
20
 
21
+ ## Demo
22
+
23
+ Puppet Library has a web UI to browse the modules. A demo is available [here](http://puppet-library.herokuapp.com).
24
+
21
25
  ## Installation
22
26
 
23
27
  Install the server as a Gem:
@@ -96,18 +100,30 @@ Puppet Library contains built-in support for:
96
100
 
97
101
  ## Compatibility with other tools
98
102
 
103
+ ### Dependency Resolution/Installation
104
+
99
105
  Puppet Library currently supports:
100
106
  - search with Puppet (`puppet module search apache`)
101
107
  - dependency resolution and installation with Puppet (`puppet module install puppetlabs/apache`)
102
108
  - dependency resolution and installation with [librarian-puppet](http://librarian-puppet.com)
103
109
  - installation with [r10k](https://github.com/adrienthebo/r10k)
104
110
 
111
+ ### Ruby
112
+
105
113
  Puppet Library is tested against Ruby versions:
106
114
  - 1.8.7
107
115
  - 1.9.3
108
116
  - 2.0.0
109
117
  - 2.1.0
110
118
 
119
+ ### Puppet
120
+
121
+ Puppet Library implements version 1 of the Forge API, and supports reading
122
+ module metadata from modules' Modulefiles. This means that Puppet Library
123
+ can currently only work with Puppet < 3.6, which uses the new Forge API (v3)
124
+ and has switched to using `metadata.json` instead of `Modulefile`. Progress
125
+ can be tracked [here](https://github.com/drrb/puppet-library/issues?milestone=1).
126
+
111
127
  ## Config file (EXPERIMENTAL)
112
128
 
113
129
  Instead of specifying command-line options, you can configure Puppet Library with a configuration file.
data/TODO.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  features:
2
+ - Support Forge API v3
2
3
  - Git repo forge:
3
4
  - make it more flexible:
4
5
  - fail gracefully if we can't contact the remote repo
@@ -18,9 +19,6 @@ features:
18
19
  - Config APIs:
19
20
  - documentation
20
21
 
21
- bugs:
22
- - Using directory forge and Puppet Forge proxy doesn't list Puppet Forge modules on the index page unless you search
23
-
24
22
  dubious_features:
25
23
  - Proxy modules' source in a directory (supported individually for now: should we just leave it that way?)
26
24
  - Make proxy cache TTL configurable
data/config.ru CHANGED
@@ -19,10 +19,10 @@ require 'rubygems'
19
19
  require 'puppet_library'
20
20
 
21
21
  server = PuppetLibrary::Server.configure do
22
- # My custom modules
23
- forge :directory do
24
- path "/var/puppet/modules"
25
- end
22
+ ## My custom modules
23
+ #forge :directory do
24
+ # path "/var/puppet/modules"
25
+ #end
26
26
 
27
27
  # Unreleased versions from Github
28
28
  forge :git_repository do
@@ -22,7 +22,8 @@
22
22
 
23
23
  :javascript
24
24
  $(document).ready(function() {
25
- $.getJSON("modules.json?q=#{query}", function(modules) {
25
+ var source = "modules.json#{ query.nil? ? '' : '?q=' + query }";
26
+ $.getJSON(source, function(modules) {
26
27
  $.each(modules, function(index, module) {
27
28
  var item = $("<li/>");
28
29
  item.append($("<b/>").append($("<a/>").attr("href", module.full_name).text(module.full_name)));
@@ -26,7 +26,7 @@ module PuppetLibrary::Archive
26
26
  def read_entry(entry_name_regex)
27
27
  tar = Gem::Package::TarReader.new(Zlib::GzipReader.open(@path))
28
28
  tar.rewind
29
- entry = tar.find {|e| e.full_name =~ entry_name_regex } or raise "Couldn't find entry in archive"
29
+ entry = tar.find {|e| e.full_name =~ entry_name_regex } or raise "Couldn't find entry in archive matching #{entry_name_regex.inspect}"
30
30
  entry.read
31
31
  end
32
32
  end
@@ -65,16 +65,23 @@ module PuppetLibrary::Forge
65
65
  end
66
66
  end
67
67
 
68
+ def get_all_metadata
69
+ get_metadata("*", "*")
70
+ end
71
+
68
72
  def get_metadata(author, module_name)
69
- Dir["#{@module_dir.path}/#{author}-#{module_name}*"].map do |module_path|
70
- archive = PuppetLibrary::Archive::ArchiveReader.new(module_path)
71
- metadata_file = archive.read_entry %r[[^/]+/metadata\.json$]
72
- JSON.parse(metadata_file)
73
- end
73
+ archives = Dir["#{@module_dir.path}/**/#{author}-#{module_name}-*.tar.gz"]
74
+ archives.map {|path| read_metadata(path) }.compact
74
75
  end
75
76
 
76
- def get_all_metadata
77
- get_metadata("*", "")
77
+ private
78
+ def read_metadata(archive_path)
79
+ archive = PuppetLibrary::Archive::ArchiveReader.new(archive_path)
80
+ metadata_file = archive.read_entry %r[[^/]+/metadata\.json$]
81
+ JSON.parse(metadata_file)
82
+ rescue => error
83
+ warn "Error reading from module archive #{archive_path}: #{error}"
84
+ return nil
78
85
  end
79
86
  end
80
87
  end
@@ -14,8 +14,12 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
+ require 'puppet_library/util/logging'
18
+
17
19
  module PuppetLibrary::Forge
18
20
  class Forge
21
+ include PuppetLibrary::Util::Logging
22
+
19
23
  def prime
20
24
  end
21
25
 
@@ -60,8 +60,8 @@ module PuppetLibrary::Forge
60
60
  super(self)
61
61
  @version_tag_regex = version_tag_regex
62
62
  @git = git
63
- @modulefile_cache = PuppetLibrary::Http::Cache::InMemory.new
64
- @tags_cache = PuppetLibrary::Http::Cache::InMemory.new
63
+ @metadata_cache = PuppetLibrary::Http::Cache::InMemory.new(60)
64
+ @tags_cache = PuppetLibrary::Http::Cache::InMemory.new(60)
65
65
  end
66
66
 
67
67
  def prime
@@ -75,11 +75,11 @@ module PuppetLibrary::Forge
75
75
  def get_module(author, name, version)
76
76
  return nil unless tags.include? tag_for(version)
77
77
 
78
- metadata = modulefile_for(version).to_metadata
78
+ metadata = metadata_for(version)
79
79
  return nil unless metadata["name"] == "#{author}-#{name}"
80
80
 
81
- on_tag_for(version) do
82
- PuppetLibrary::Archive::Archiver.archive_dir('.', "#{metadata["name"]}-#{version}") do |archive|
81
+ with_tag_for(version) do |tag_path|
82
+ PuppetLibrary::Archive::Archiver.archive_dir(tag_path, "#{metadata["name"]}-#{version}") do |archive|
83
83
  archive.add_file("metadata.json", 0644) do |entry|
84
84
  entry.write metadata.to_json
85
85
  end
@@ -89,7 +89,7 @@ module PuppetLibrary::Forge
89
89
 
90
90
  def get_all_metadata
91
91
  tags.map do |tag|
92
- modulefile_for_tag(tag).to_metadata
92
+ metadata_for_tag(tag)
93
93
  end
94
94
  end
95
95
 
@@ -106,23 +106,33 @@ module PuppetLibrary::Forge
106
106
  @tags_cache.get do
107
107
  tags = @git.tags
108
108
  tags = tags.select {|tag| tag =~ @version_tag_regex }
109
- tags = tags.select {|tag| @git.file_exists?("Modulefile", tag) }
109
+ tags = tags.select do |tag|
110
+ @git.file_exists?("metadata.json", tag) || @git.file_exists?("Modulefile", tag)
111
+ end
110
112
  end
111
113
  end
112
114
 
113
- def modulefile_for_tag(tag)
114
- @modulefile_cache.get(tag) do
115
- modulefile_source = @git.read_file("Modulefile", tag)
116
- PuppetLibrary::PuppetModule::Modulefile.parse(modulefile_source)
115
+ def metadata_for_tag(tag)
116
+ @metadata_cache.get(tag) do
117
+ metadata_file_exists = @git.file_exists?("metadata.json", tag)
118
+ modulefile_exists = @git.file_exists?("Modulefile", tag)
119
+ if metadata_file_exists && !modulefile_exists
120
+ metadata_file = @git.read_file("metadata.json", tag)
121
+ JSON.parse(metadata_file)
122
+ else
123
+ modulefile_source = @git.read_file("Modulefile", tag)
124
+ modulefile = PuppetLibrary::PuppetModule::Modulefile.parse(modulefile_source)
125
+ modulefile.to_metadata
126
+ end
117
127
  end
118
128
  end
119
129
 
120
- def modulefile_for(version)
121
- modulefile_for_tag(tag_for(version))
130
+ def metadata_for(version)
131
+ metadata_for_tag(tag_for(version))
122
132
  end
123
133
 
124
- def on_tag_for(version, &block)
125
- @git.on_tag(tag_for(version), &block)
134
+ def with_tag_for(version, &block)
135
+ @git.with_tag(tag_for(version), &block)
126
136
  end
127
137
 
128
138
  def tag_for(version)
@@ -131,7 +141,7 @@ module PuppetLibrary::Forge
131
141
 
132
142
  def tag_versions
133
143
  tags_to_versions = tags.map do |tag|
134
- [ modulefile_for_tag(tag).get_version, tag ]
144
+ [ metadata_for_tag(tag)["version"], tag ]
135
145
  end
136
146
  Hash[tags_to_versions]
137
147
  end
@@ -25,7 +25,8 @@ module PuppetLibrary::Forge
25
25
  # Metadata (+metadata.json+) is generated on the fly.
26
26
  #
27
27
  # <b>Note:</b>
28
- # The module directory must have a +Modulefile+.
28
+ # The module directory must have either a +metadata.json+ or a +Modulefile+.
29
+ # If it contains both, +metadata.json+ will be used.
29
30
  #
30
31
  # <b>Usage:</b>
31
32
  #
@@ -52,41 +53,47 @@ module PuppetLibrary::Forge
52
53
  raise "Module directory '#{module_dir.path}' doesn't exist" unless File.directory? module_dir.path
53
54
  raise "Module directory '#{module_dir.path}' isn't readable" unless File.executable? module_dir.path
54
55
  @module_dir = module_dir
55
- @cache = PuppetLibrary::Http::Cache::InMemory.new(CACHE_TTL_MILLIS)
56
+ @metadata_cache = PuppetLibrary::Http::Cache::InMemory.new(CACHE_TTL_MILLIS)
56
57
  end
57
58
 
58
59
  def get_module(author, name, version)
59
60
  return nil unless this_module?(author, name, version)
60
61
  PuppetLibrary::Archive::Archiver.archive_dir(@module_dir.path, "#{author}-#{name}-#{version}") do |archive|
61
62
  archive.add_file("metadata.json", 0644) do |entry|
62
- entry.write modulefile.to_metadata.to_json
63
+ entry.write metadata.to_json
63
64
  end
64
65
  end
65
66
  end
66
67
 
67
68
  def get_metadata(author, module_name)
68
69
  return [] unless this_module?(author, module_name)
69
- [ modulefile.to_metadata ]
70
+ [ metadata ]
70
71
  end
71
72
 
72
73
  def get_all_metadata
73
- get_metadata(modulefile.get_author, modulefile.get_simple_name)
74
+ get_metadata(metadata["author"], metadata["name"].split("-").last)
74
75
  end
75
76
 
76
77
  private
77
78
  def this_module?(author, module_name, version = nil)
78
- same_module = modulefile.get_name == "#{author}-#{module_name}"
79
+ same_module = metadata["name"] == "#{author}-#{module_name}"
79
80
  if version.nil?
80
81
  return same_module
81
82
  else
82
- return same_module && modulefile.get_version == version
83
+ return same_module && metadata["version"] == version
83
84
  end
84
85
  end
85
86
 
86
- def modulefile
87
- modulefile_path = File.join(@module_dir.path, "Modulefile")
88
- @cache.get modulefile_path do
89
- PuppetLibrary::PuppetModule::Modulefile.read(modulefile_path)
87
+ def metadata
88
+ @metadata_cache.get "metadata" do
89
+ metadata_file_path = File.join(@module_dir.path, "metadata.json")
90
+ modulefile_path = File.join(@module_dir.path, "Modulefile")
91
+ if File.exist?(metadata_file_path) && ! File.exist?(modulefile_path)
92
+ JSON.parse(File.read(metadata_file_path))
93
+ else
94
+ modulefile = PuppetLibrary::PuppetModule::Modulefile.read(modulefile_path)
95
+ modulefile.to_metadata
96
+ end
90
97
  end
91
98
  end
92
99
  end
@@ -39,11 +39,11 @@ module PuppetLibrary::Util
39
39
  git("tag").split
40
40
  end
41
41
 
42
- def on_tag(tag)
42
+ def with_tag(tag)
43
43
  update_cache!
44
44
  PuppetLibrary::Util::TempDir.use "git" do |path|
45
45
  git "checkout #{tag}", path
46
- yield
46
+ yield(path)
47
47
  end
48
48
  end
49
49
 
@@ -75,14 +75,14 @@ module PuppetLibrary::Util
75
75
  def create_cache
76
76
  @mutex.synchronize do
77
77
  info "Cloning Git repository from #{@source} to #{@git_dir}"
78
- git "clone --bare #{@source} #{@git_dir}"
78
+ git "clone --mirror #{@source} #{@git_dir}"
79
79
  FileUtils.touch fetch_file
80
80
  end
81
81
  end
82
82
 
83
83
  def update_cache
84
84
  @mutex.synchronize do
85
- git "fetch --tags"
85
+ git "fetch origin --tags --update-head-ok"
86
86
  end
87
87
  end
88
88
 
@@ -18,12 +18,21 @@ require 'logger'
18
18
 
19
19
  module PuppetLibrary::Util
20
20
  module Logging
21
- def log_io
22
- @log_io ||= StringIO.new
21
+ class LogCollector < Array
22
+ def write(message)
23
+ self << message
24
+ end
25
+
26
+ def close
27
+ end
28
+ end
29
+
30
+ def logs
31
+ @logs ||= LogCollector.new
23
32
  end
24
33
 
25
34
  def logger
26
- destination = ENV["TESTING"] ? log_io : STDERR
35
+ destination = ENV["TESTING"] ? logs : STDERR
27
36
  @logger ||= Logger.new(destination).tap do |logger|
28
37
  logger.progname = self.class.name
29
38
  logger.level = Logger::DEBUG
@@ -21,7 +21,14 @@ module PuppetLibrary::Util
21
21
  class TempDir
22
22
  attr_reader :path
23
23
 
24
- def self.use(name, &block)
24
+ def self.use(name)
25
+ path = create(name)
26
+ yield(path)
27
+ ensure
28
+ FileUtils.rm_rf path
29
+ end
30
+
31
+ def self.cd(name, &block)
25
32
  path = create(name)
26
33
  Dir.chdir(path, &block)
27
34
  ensure
@@ -16,5 +16,5 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module PuppetLibrary
19
- VERSION = "0.13.0"
19
+ VERSION = "0.14.0"
20
20
  end
@@ -47,11 +47,11 @@ Gem::Specification.new do |spec|
47
47
  spec.add_development_dependency "gitsu"
48
48
  spec.add_development_dependency "librarian-puppet", "0.9.10" # 0.9.12 breaks on Ruby 1.8.7
49
49
  spec.add_development_dependency "mime-types", "< 2"
50
- spec.add_development_dependency "pry"
50
+ spec.add_development_dependency "pry", "0.9.12.6"
51
51
  spec.add_development_dependency "puppet", "~> 3.3.0"
52
52
  spec.add_development_dependency "rack-test"
53
53
  spec.add_development_dependency "rake"
54
- spec.add_development_dependency "rspec"
54
+ spec.add_development_dependency "rspec", "~> 3.0.0"
55
55
  spec.add_development_dependency "simplecov"
56
56
 
57
57
  # Guard has dependencies that don't work with Ruby < 1.9