simple-puppet-forge 0.1.0

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