cupper 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +16 -0
  5. data/Gemfile +18 -0
  6. data/README.md +30 -0
  7. data/Rakefile +6 -0
  8. data/bin/cupper +1 -1
  9. data/cupper.gemspec +28 -0
  10. data/lib/cupper.rb +18 -1
  11. data/lib/cupper/cli.rb +63 -0
  12. data/lib/cupper/collect.rb +51 -0
  13. data/lib/cupper/cookbook.rb +71 -0
  14. data/lib/cupper/cookbook_file.rb +10 -0
  15. data/lib/cupper/cupperfile.rb +22 -0
  16. data/lib/cupper/entity.rb +63 -0
  17. data/lib/cupper/environment.rb +177 -0
  18. data/lib/cupper/errors.rb +84 -0
  19. data/lib/cupper/ohai_plugins.rb +13 -0
  20. data/lib/cupper/platform_collector.rb +40 -0
  21. data/lib/cupper/plugins/cupper/arch.rb +43 -0
  22. data/lib/cupper/plugins/cupper/debian.rb +48 -0
  23. data/lib/cupper/plugins/ohai/dpci.rb +30 -0
  24. data/lib/cupper/plugins/ohai/files.rb +68 -0
  25. data/lib/cupper/plugins/ohai/init_system.rb +14 -0
  26. data/lib/cupper/plugins/ohai/pacman.rb +31 -0
  27. data/lib/cupper/plugins/ohai/pkg_deps.rb +30 -0
  28. data/lib/cupper/plugins/ohai/pkg_manager.rb +31 -0
  29. data/lib/cupper/plugins/ohai/services.rb +20 -0
  30. data/lib/cupper/project.rb +40 -0
  31. data/lib/cupper/recipe.rb +240 -0
  32. data/lib/cupper/templates/CupperFile.erb +1 -0
  33. data/lib/cupper/templates/_cookbook_file.erb +9 -0
  34. data/lib/cupper/templates/_groups.erb +10 -0
  35. data/lib/cupper/templates/_links.erb +10 -0
  36. data/lib/cupper/templates/_package.erb +19 -0
  37. data/lib/cupper/templates/_services.erb +7 -0
  38. data/lib/cupper/templates/_templates.erb +11 -0
  39. data/lib/cupper/templates/_users.erb +10 -0
  40. data/lib/cupper/templates/cookbook_file.erb +1 -0
  41. data/lib/cupper/templates/recipe.erb +7 -0
  42. data/lib/cupper/version.rb +3 -0
  43. data/templates/locales/en.yml +17 -0
  44. metadata +125 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2987796a753b3738ed695df15aa19fe0ae21881
4
- data.tar.gz: 1ac44330efe68aa62f0151e654132227f9f55125
3
+ metadata.gz: 4cb1f5ee3842ee97e25770577a390f8547a47e3a
4
+ data.tar.gz: c2e64363e16d0d940d9a542fec515b1524d93b1c
5
5
  SHA512:
6
- metadata.gz: bb25e0972fb24b3467dc476c3052a01731cf5b70ce88f1287ea214a00714d210106c1d9bfa57d4afdf44dab93e01945d7d0561cb089096aa5ba24030e7025094
7
- data.tar.gz: c08a8b850643e6857324d198df1b9f5cbf8bf0e16c52c2db3440a916b48343f5ac7da4eb3843f5d5535dd6bcb1182e51fce30614d17d8bd0feb5e492e36aa733
6
+ metadata.gz: c4216eeb5b6377d1e1240b15dde4b585fc347a1e34d1188529b0e7ffc0a8337626e80f24dc1cb35153e11080f4b1e4ac267590660591744343a9103499581fda
7
+ data.tar.gz: 394040efd699a88b89d51ff7361abc483f93b9b034fb90929d79c033201bdbac469425819c6c15a75274677285b4d5673d25ea404b09f4863e555d1e290bcb84
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ sudo: false
3
+ branches:
4
+ - master
5
+ - dev
6
+
7
+ rvm:
8
+ - 2.2.1
9
+ - 2.3.0
10
+
11
+ before_install:
12
+ - gem update --system
13
+ - gem install bundler
14
+
15
+ after_success:
16
+ - coveralls
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cupper.gemspec
4
+ gemspec
5
+
6
+ gem 'ohai'
7
+ gem 'thor'
8
+ gem 'i18n'
9
+ gem 'colorize'
10
+ gem 'coveralls', require: false
11
+
12
+ group :development do
13
+ gem 'rubocop'
14
+ end
15
+
16
+ group :test do
17
+ gem 'rspec'
18
+ end
@@ -0,0 +1,30 @@
1
+ # Cupper
2
+
3
+ [![Join the chat at https://gitter.im/cupper-reverse-recipe/cupper](https://badges.gitter.im/cupper-reverse-recipe/cupper.svg)](https://gitter.im/cupper-reverse-recipe/cupper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+ [![Coverage Status](https://coveralls.io/repos/github/cupper-reverse-recipe/cupper/badge.svg?branch=master)](https://coveralls.io/github/cupper-reverse-recipe/cupper?branch=master)
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'cupper'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install cupper
21
+
22
+ ## Usage
23
+
24
+
25
+ ## Development
26
+
27
+
28
+ ## Contributing
29
+
30
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/cupper CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'cupper'
4
-
4
+ Cupper::Cli.start
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cupper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cupper'
8
+ spec.version = Cupper::VERSION
9
+ spec.authors = ['Paulo Tada', 'Lucas Severo']
10
+ spec.email = ['paulohtfs@gmail.com', 'lucassalves65@gmail.com']
11
+
12
+ spec.summary = 'Reverse recipe'
13
+ spec.description = 'Taste your system and create a recipe'
14
+ spec.homepage = 'https://github.com/cupper-reverse-recipe/cupper'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = 'bin'
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|featires)/)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.12'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+
26
+ spec.add_runtime_dependency 'thor', '~> 0.19.1'
27
+ spec.add_runtime_dependency 'ohai', '~> 8.15', '>= 8.15.1'
28
+ end
@@ -1,3 +1,20 @@
1
+ require 'cupper/version'
2
+ require 'cupper/project'
3
+ require 'cupper/cli'
4
+ require 'cupper/ohai_plugins'
5
+ require 'cupper/collect'
6
+ require 'cupper/cookbook'
7
+ require 'cupper/entity'
1
8
 
2
- class Cupper
9
+
10
+ module Cupper
11
+ CUPPER_ROOT = File.expand_path(File.dirname(__FILE__))
12
+ OHAI_PLUGINS_PATH = CUPPER_ROOT + '/cupper/plugins/ohai'
13
+ CUPPER_PLUGINS_PATH = CUPPER_ROOT + '/cupper/plugins/cupper'
14
+ TEMPLATE_PATH = CUPPER_ROOT + '/cupper/templates'
15
+
16
+ # REVIEW: maybe there is a better way and place to load all plugins
17
+ # Loading all cupper plugins
18
+ Dir["#{CUPPER_PLUGINS_PATH}/*.rb"].each { |file| require file }
3
19
  end
20
+
@@ -0,0 +1,63 @@
1
+ # This module defines all the class responsable for the command line tool
2
+ # It should call all the others module and classes to provides for the user
3
+ # all the features avaible
4
+ #
5
+
6
+ require 'thor'
7
+ require 'cupper/project'
8
+ require 'cupper/cookbook'
9
+ require 'cupper/ohai_plugins'
10
+
11
+ module Cupper
12
+ class Cli < Thor
13
+ desc 'create [PROJECT_NAME]', 'Create the project structure'
14
+ def create(project_name)
15
+ project = Project.new(project_name)
16
+ project.create
17
+ end
18
+
19
+ desc 'ohai', 'List Ohai plugins'
20
+ def ohai_plugins
21
+ ohai_plugins = OhaiPlugin.new
22
+ plugins = ohai_plugins.list
23
+ puts "Ohai Plugins"
24
+ puts "------------"
25
+ plugins.each do |plugin|
26
+ puts plugin
27
+ end
28
+ end
29
+
30
+ desc 'generate', 'Extract configuration and create a cookbook'
31
+ method_option :verbose, :aliases => '-v', :desc => 'Enable output log'
32
+ def generate
33
+ puts "Generating the Cookbook"
34
+ cookbook = Cookbook.new
35
+ if options.verbose?
36
+ puts "Verbose mode enabled"
37
+ cookbook.generate
38
+ else
39
+ Cupper.suppress_output{ cookbook.generate }
40
+ end
41
+ end
42
+ end
43
+
44
+ # When necessary, use this method to supress outputs
45
+ # don't suppress Exeptions
46
+ def self.suppress_output
47
+ begin
48
+ origin_stderr = $stderr.clone
49
+ origin_stdout = $stdout.clone
50
+ $stderr.reopen(File.new('/dev/null', 'w'))
51
+ $stdout.reopen(File.new('/dev/null', 'w'))
52
+ retval = yield
53
+ rescue Exception => e
54
+ $stderr.reopen(origin_stderr)
55
+ $stdout.reopen(origin_stdout)
56
+ raise e
57
+ ensure
58
+ $stderr.reopen(origin_stderr)
59
+ $stdout.reopen(origin_stdout)
60
+ end
61
+ retval
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ require 'ohai'
2
+ require 'cupper/ohai_plugins'
3
+
4
+ module Cupper
5
+ class Collect
6
+ ADDITIONAL_OHAI_PLUGINS = [
7
+ 'packages',
8
+ 'platform_family',
9
+ 'etc'
10
+ ]
11
+
12
+ def initialize
13
+ @data_extraction = Hash.new('No data!')
14
+ @ohai = Ohai::System.new
15
+ @ohai_plugin = OhaiPlugin.new
16
+
17
+ # TODO: Ohai::Config[:plugin_path] is decrepted
18
+ @plugins_path = Cupper::OHAI_PLUGINS_PATH
19
+ Ohai::Config[:plugin_path] << @plugins_path
20
+ end
21
+
22
+ def extract(attribute)
23
+ begin
24
+ object = 'Cupper::'.concat self.platform.capitalize
25
+ platform = Object.const_get(object).new
26
+ extract = platform.method attribute
27
+ extract.call @data_extraction
28
+ rescue NameError
29
+ puts 'Not supported platform' # TODO: treat this better
30
+ end
31
+ end
32
+
33
+ def setup
34
+ plugins = @ohai_plugin.list
35
+ plugins.concat ADDITIONAL_OHAI_PLUGINS
36
+ plugins.each do |plugin|
37
+ extract = @ohai.all_plugins(plugin)
38
+ @data_extraction.update({ plugin => extract.first.data }) # Assuming that the first is the default plugin extractor
39
+ end
40
+ true
41
+ end
42
+
43
+ def platform
44
+ @data_extraction['platform_family']['platform_family']
45
+ end
46
+
47
+ def data
48
+ @data_extraction
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,71 @@
1
+ require 'cupper/collect'
2
+ require 'cupper/recipe'
3
+ require 'cupper/cookbook_file'
4
+
5
+ module Cupper
6
+ class Cookbook
7
+ # TODO: Read config file to tell the project path and configs
8
+ def initialize(cookbookname='default')
9
+ @cookbook_path = "#{Dir.getwd}/#{cookbookname}"
10
+ @cookbook_files_path = "#{@cookbook_path}/files"
11
+ @cookbook_recipes_path = "#{@cookbook_path}/recipes"
12
+ @recipe_deps = [ # TODO this is hard code to reflect all_recipes. Refactor this later
13
+ "#{cookbookname}::cookbook_file",
14
+ "#{cookbookname}::links",
15
+ "#{cookbookname}::groups",
16
+ "#{cookbookname}::services",
17
+ "#{cookbookname}::users",
18
+ "#{cookbookname}::packages",
19
+ ]
20
+ setup_paths
21
+ end
22
+
23
+ def setup_paths
24
+ Dir.mkdir(@cookbook_path) unless Dir.exists?(@cookbook_path)
25
+ Dir.mkdir(@cookbook_files_path) unless Dir.exists?(@cookbook_files_path)
26
+ Dir.mkdir(@cookbook_recipes_path) unless Dir.exists?(@cookbook_recipes_path)
27
+ end
28
+
29
+ def generate
30
+ collector = Collect.new
31
+ collector.setup
32
+ all_recipes(collector)
33
+ all_cookbook_files(collector)
34
+ end
35
+
36
+ def all_recipes(collector)
37
+ Recipe.new(@cookbook_recipes_path, collector, 'recipe', 'default', @recipe_deps).create
38
+ Recipe.new(@cookbook_recipes_path, collector, '_cookbook_file', 'cookbook_files').create
39
+ Recipe.new(@cookbook_recipes_path, collector, '_links', 'links').create
40
+ Recipe.new(@cookbook_recipes_path, collector, '_groups', 'groups').create
41
+ Recipe.new(@cookbook_recipes_path, collector, '_services', 'services').create
42
+ Recipe.new(@cookbook_recipes_path, collector, '_users', 'users').create
43
+ Recipe.new(@cookbook_recipes_path, collector, '_package', 'packages').create
44
+ end
45
+
46
+ def all_cookbook_files(collector)
47
+ expand_cookbook_files(collector.extract 'files')
48
+ end
49
+
50
+ def text_type?(file)
51
+ file[1]['type'].match('text') or file[1]['type'].match('ASCII')
52
+ end
53
+
54
+ def expand_cookbook_files(files)
55
+ files.each do |attr|
56
+ if text_type?(attr) and !(attr[1]['related'].nil?)
57
+ source = attr[0].split('/').last
58
+ content = attr[1]['content']
59
+ CookbookFile.new(@cookbook_files_path, source, content, 'cookbook_file').create
60
+ end
61
+ # TODO: This is a work around to source list file
62
+ # should be replaced for a better logic
63
+ if text_type?(attr) and attr[0].include? "/etc/apt/sources.list"
64
+ source = attr[0].split('/').last
65
+ content = attr[1]['content']
66
+ CookbookFile.new(@cookbook_files_path, source, content, 'cookbook_file').create
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,10 @@
1
+ module Cupper
2
+ class CookbookFile
3
+ include Entity
4
+ def initialize(dest_path, source, content, erb_file = nil, type = nil)
5
+ @source = source
6
+ @content = content
7
+ super(@source, dest_path, erb_file, type)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Cupper
2
+ class Cupperfile
3
+
4
+ def initialize(loader, keys)
5
+ @keys = keys
6
+ @loader = loader
7
+ @config, _ = loader.load(keys)
8
+ end
9
+
10
+ protected
11
+
12
+ def find_cupperfile(search_path)
13
+ ["Cupperfile", "cupperfile"].each do |cupperfile|
14
+ current_path = search_path.join(cupperfile)
15
+ return current_path if current_path.file?
16
+ end
17
+
18
+ nil
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ module Cupper
2
+ # Entity represents a Entity
3
+ module Entity
4
+ require 'erb'
5
+
6
+ FILE = 'file'
7
+ DIR = 'dir'
8
+
9
+ # As default the Entity is treated as a file
10
+ def initialize(name, dest_path, erb_file = nil, type = nil, extension = '')
11
+ @name = name
12
+ @dest_path = dest_path
13
+ @erb_file = erb_file
14
+ @type = type.nil? ? FILE : type
15
+ @ext = extension
16
+
17
+ @full_path = "#{@dest_path}/#{@name}#{@ext}"
18
+ end
19
+
20
+ # Create the actual file or dir in the correct place
21
+ def create
22
+ content(@erb_file)
23
+ save
24
+ end
25
+
26
+ # Returns the content of the file
27
+ def content(erb_file)
28
+ return false if self.dir?
29
+ @template = File.read("#{TEMPLATE_PATH}/#{erb_file}.erb")
30
+ end
31
+
32
+ def save
33
+ File.open(@full_path,"a+") { |f| f.write(self.render_template) } if self.file?
34
+ Dir.mkdir(@full_path) if self.dir? && !(self.exist?)
35
+ end
36
+
37
+ def render_template
38
+ ERB.new(@template).result(binding)
39
+ end
40
+
41
+ # Treats entity as a file or as a dir
42
+ def file?
43
+ @type == FILE
44
+ end
45
+ def dir?
46
+ @type == DIR
47
+ end
48
+
49
+ def exist?
50
+ return File.exist?(@full_path) if self.file?
51
+ return Dir.exist?(@full_path) if self.dir?
52
+ end
53
+
54
+ def full_path
55
+ @full_path
56
+ end
57
+ end
58
+
59
+ class Attribute
60
+ attr_reader :attr
61
+ end
62
+
63
+ end