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 +7 -7
- data/.gitignore +1 -1
- data/CHANGELOG.yml +6 -0
- data/README.md +21 -5
- data/TODO.yml +1 -3
- data/config.ru +4 -4
- data/lib/puppet_library/app/views/index.haml +2 -1
- data/lib/puppet_library/archive/archive_reader.rb +1 -1
- data/lib/puppet_library/forge/directory.rb +14 -7
- data/lib/puppet_library/forge/forge.rb +4 -0
- data/lib/puppet_library/forge/git_repository.rb +26 -16
- data/lib/puppet_library/forge/source.rb +18 -11
- data/lib/puppet_library/util/git.rb +4 -4
- data/lib/puppet_library/util/logging.rb +12 -3
- data/lib/puppet_library/util/temp_dir.rb +8 -1
- data/lib/puppet_library/version.rb +1 -1
- data/puppet-library.gemspec +2 -2
- data/spec/forge/directory_spec.rb +47 -0
- data/spec/forge/git_repository_spec.rb +40 -10
- data/spec/forge/source_spec.rb +48 -28
- data/spec/server_spec.rb +1 -1
- data/spec/spec_helper.rb +17 -5
- data/spec/util/git_spec.rb +8 -7
- data/spec/util/temp_dir_spec.rb +19 -3
- metadata +320 -127
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
|
4
|
-
|
5
|
-
SHA512:
|
6
|
-
|
7
|
-
|
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
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
|
-
[](https://travis-ci.org/drrb/puppet-library)
|
6
|
+
[](https://coveralls.io/r/drrb/puppet-library)
|
7
|
+
[](https://codeclimate.com/github/drrb/puppet-library)
|
8
8
|
|
9
|
-
[](http://badge.fury.io/rb/puppet-library)
|
10
|
+
[](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
|
-
|
23
|
-
forge :directory do
|
24
|
-
|
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
|
-
|
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}
|
70
|
-
|
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
|
-
|
77
|
-
|
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
|
-
@
|
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 =
|
78
|
+
metadata = metadata_for(version)
|
79
79
|
return nil unless metadata["name"] == "#{author}-#{name}"
|
80
80
|
|
81
|
-
|
82
|
-
PuppetLibrary::Archive::Archiver.archive_dir(
|
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
|
-
|
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
|
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
|
114
|
-
@
|
115
|
-
|
116
|
-
|
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
|
121
|
-
|
130
|
+
def metadata_for(version)
|
131
|
+
metadata_for_tag(tag_for(version))
|
122
132
|
end
|
123
133
|
|
124
|
-
def
|
125
|
-
@git.
|
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
|
-
[
|
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
|
-
@
|
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
|
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
|
-
[
|
70
|
+
[ metadata ]
|
70
71
|
end
|
71
72
|
|
72
73
|
def get_all_metadata
|
73
|
-
get_metadata(
|
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 =
|
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 &&
|
83
|
+
return same_module && metadata["version"] == version
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
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 --
|
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
|
-
|
22
|
-
|
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"] ?
|
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
|
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
|
data/puppet-library.gemspec
CHANGED
@@ -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
|