simple-puppet-forge 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d9a436780a81d6ccd62a2432a74d36ee603d8e1b
4
+ data.tar.gz: 927fb61434c3d02f80d3ed1a90fff1dddad4dae4
5
+ SHA512:
6
+ metadata.gz: 723108b8ae4ef4c60a4793f4e3dea4e53d9405cd86675b5622d00354e7f55febd3144b8f5e7672dc7b8eb25b356939bee61baa72d13ee91c5a94458820e7d3c7
7
+ data.tar.gz: 24aec504a486dd006a0fed8f8d7e4489b9d77f49172a6baef4578c11ba9b0ed6669ce1f8974612b45b3c8f10105041c0e6ed81fe7d2308ae6f94bff74874f741
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2012 by Erik Dal�n <erik.gustav.dalen@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ Simple Puppet Forge
2
+ ===================
3
+
4
+ A simple Puppet forge implementation which requires no database backend and will just read the metadata from the modules from disk instead.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ It requires Sinatra (at least version 1.3+). Can be run as a regular Rack application under for example Passenger.
10
+ There is a sample apache vhost configuration in the archive.
11
+
12
+ It also requires GNU tar (hopefully other variants can be supported in the future).
13
+
14
+ By default modules should be stored under `/var/lib/simple-puppet-forge/modules`. It expects the directory structure to be `user/module/user-module-version.tar.gz`.
15
+
16
+ Usage
17
+ -----
18
+
19
+ Set the `module_repository` setting in Puppet to point to your simple puppet forge instance, for example `module_repository=http://forge.example.com/`.
20
+
21
+ After that you should be able to install modules using `puppet module install` provided they exist on disk.
@@ -0,0 +1,4 @@
1
+ <VirtualHost *:80>
2
+ PassengerAppRoot /usr/share/simple-puppet-forge
3
+ DocumentRoot /usr/share/simple-puppet-forge
4
+ </VirtualHost>
data/config.ru ADDED
@@ -0,0 +1,2 @@
1
+ require 'simple_puppet_forge'
2
+ run SimplePuppetForge
@@ -0,0 +1,63 @@
1
+ require 'simple_puppet_forge'
2
+ require 'json'
3
+
4
+ class SimplePuppetForge::Module
5
+ attr_reader :path, :uripath, :metadata
6
+
7
+ def initialize(path, uri_root_path)
8
+ @path = path
9
+ @uripath = '/modules' + path[uri_root_path.chomp('/').length..-1].chomp('/')
10
+ @metadata_path = path + '.metadata'
11
+
12
+ extract_metadata
13
+ read_metadata
14
+ end
15
+
16
+ # Extract the metdata if it doesn't exist or if the module has been updated
17
+ def extract_metadata
18
+ if File.exist?(@metadata_path)
19
+ if File.stat(@metadata_path).mtime > File.stat(@path).mtime
20
+ return
21
+ end
22
+ end
23
+ # TODO: support others than GNU tar
24
+ `gtar -z -x -O --wildcards -f #{@path} '*/metadata.json' > #{@metadata_path}`
25
+ raise "Failed to extract metadata for #{@path}" unless $?.success?
26
+ end
27
+
28
+ # Read the metadata file
29
+ def read_metadata
30
+ begin
31
+ metadata_file = File.open(@metadata_path, 'r')
32
+ @metadata = JSON.parse metadata_file.read
33
+ metadata_file.close
34
+ @metadata
35
+ rescue
36
+ raise "Failed to read metadata file #{@metadata_path}"
37
+ end
38
+ end
39
+
40
+ def dependencies
41
+ @metadata['dependencies'].collect do |dep|
42
+ ret = [dep['name']]
43
+ ret << dep['version_requirement'] if dep['version_requirement']
44
+ ret
45
+ end
46
+ end
47
+
48
+ def version
49
+ @metadata['version']
50
+ end
51
+
52
+ def name
53
+ @metadata['name']
54
+ end
55
+
56
+ def to_hash
57
+ {
58
+ 'file' => @uripath,
59
+ 'version' => version,
60
+ 'dependencies' => dependencies,
61
+ }
62
+ end
63
+ end
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sinatra/base'
4
+ require 'json'
5
+
6
+ class SimplePuppetForge < Sinatra::Base
7
+
8
+ configure do
9
+ set :module_dir, '/var/lib/simple-puppet-forge/modules'
10
+ enable :logging
11
+ end
12
+
13
+ # API request for a module
14
+ get '/api/v1/releases.json' do
15
+ modules = {}
16
+ unprocessed = [params[:module]]
17
+ while mod = unprocessed.shift
18
+ next if modules[mod] # This module has already been added
19
+
20
+ user, modname = mod.split '/'
21
+ release_list = list_modules(user, modname)
22
+ if !release_list.empty?
23
+ modules[mod] = release_list
24
+ unprocessed += modules_dependencies(release_list)
25
+ end
26
+ end
27
+
28
+ if modules.empty?
29
+ status 410
30
+ return { 'error' => "Module #{user}/#{modname} not found"}.to_json
31
+ else
32
+ modules.each_key do |m|
33
+ modules[m] = modules[m].collect { |release| release.to_hash }
34
+ end
35
+ return modules.to_json
36
+ end
37
+ end
38
+
39
+ # Serve the module itself
40
+ get '*/modules/:user/:module/:file' do
41
+ send_file File.join(settings.module_dir, params[:user], params[:module], params[:file])
42
+ end
43
+
44
+ # From a list of modules get a list of modules (names) they depend on
45
+ def modules_dependencies(modules)
46
+ modules.collect { |m| m.dependencies.collect { |d| d.first } }.flatten.uniq
47
+ end
48
+
49
+ # List modules matching user and module
50
+ def list_modules(user, mod)
51
+ require 'simple_puppet_forge/module'
52
+
53
+ dir = File.join(settings.module_dir, user, mod)
54
+
55
+ begin
56
+ Dir.entries(dir).select do |e|
57
+ e.match(/^#{Regexp.escape user}-#{Regexp.escape mod}-.*.tar\.gz$/)
58
+ end.sort.reverse.collect do |f|
59
+ path = File.join(dir, f)
60
+ begin
61
+ Module.new(path, settings.module_dir)
62
+ rescue RuntimeError => e
63
+ logger.error e.message
64
+ nil
65
+ end
66
+ end.compact
67
+ rescue Errno::ENOENT
68
+ return []
69
+ end
70
+ end
71
+
72
+ # start the server if ruby file executed directly
73
+ run! if app_file == $0
74
+ end
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "simple-puppet-forge"
3
+ s.version = %x{git describe --tags}.split('-')[0..1].join('.')
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = ["Erik Dalén"]
6
+ s.email = ["dalen@spotify.com"]
7
+ s.summary = %q{Simple Puppet Forge}
8
+ s.description = %q{A simple implementation of the Puppet Forge.}
9
+ s.license = 'Apache v2'
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test,spec,features,examples}/*`.split("\n")
13
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ s.require_paths = ["lib"]
15
+ s.add_dependency('json')
16
+ s.add_dependency('sinatra')
17
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-puppet-forge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Erik Dalén
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sinatra
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A simple implementation of the Puppet Forge.
42
+ email:
43
+ - dalen@spotify.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE
49
+ - README.md
50
+ - apache.vhost.example
51
+ - config.ru
52
+ - lib/simple_puppet_forge.rb
53
+ - lib/simple_puppet_forge/module.rb
54
+ - simple-puppet-forge.gemspec
55
+ homepage:
56
+ licenses:
57
+ - Apache v2
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.0.3
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: Simple Puppet Forge
79
+ test_files: []
80
+ has_rdoc: