puppet-library 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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