Skip to content
This repository has been archived by the owner on Sep 24, 2019. It is now read-only.

Commit

Permalink
Inital check-in
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Maraglia committed Aug 27, 2012
1 parent f4bec97 commit 3a7ddac
Show file tree
Hide file tree
Showing 44 changed files with 4,774 additions and 3 deletions.
71 changes: 68 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,69 @@
origami
=======
# origami #
A templating engine which complements veewee.

Templating engine for Atsuya Kumano's VM provisioning tool: seisan-line
## Introduction ##
[veewee](http://github.com/jedi4ever/veewee) makes building virtual machines easy but origami takes a step further and makes the process even easier,
especially for those who wish to quickly deploy numbers of VMs that are configured differently.
Without origami a typical workflow of a veewee user would be

1. Choose a template to work with.
2. `veewee define my-CentOS-6.2-server CentOS-6.2-i386-netboot`
3. Modify `definition.rb` and `ks.cfg`
4. `veewee build box-name`.

By introducing origami it becomes

1. `origami --name CentOS-6.2-i386-server`
2. `veewee build CentOS-6.2-i386-server`

Thus origami lets you bypass the editing of templates and initiate building a virtual machine immediately.
Also, [a wrapper for origami and veewee](http://github.com/akumano/seisan-line) is available!

## Configuration ##
Managing veewee definitions is cumbersome because it requires you to create a configuration (i.e. `definition.rb` and `ks.cfg`) on a per-distro basis.
On the other hand, origami maintains configurations on a per-option basis.
The power of this approach is immense when you need to maintain a long list of VMs.
For example, if you want to change what packages are installed on your `Oracle-5.8-i386-server`,
you go to a corresponding yaml file, `pkgs.yml`, which might look like:

# pkgs.yml
---
Oracle:
'5.8':
server:
- openssh-server
desktop:
- openssh-server
- ruby
'6':
typeA:
- openssh-server
- git
typeB:
- openssh-server
- git
- ruby
CentOS:
'6': ...
.
.
Ubuntu:
'10': ...
.
.
.
SLES:
'11': ...

and change the corresponding value in the yaml hash.
Once you edit all yaml files (which may include `boot_cmd_sequence.yml`, `kickstart_file`, and so on),
you have a whole ensemble of different flavors of distros that you can start building just from their names.
I said 'all' in the previous sentence, but the number of yaml files can be small or large,
depending on your needs.
You need to create a yaml file for a parameter only if the parameter needs to be varied, and the others, which are fixed for any kind of VM,
are specified in a master template. The end result is instead of having an ever-growing number of definitions in your `veewee/definitions` directory,
you just have a fixed number of yaml files to configure installation parameters.

### How To ###
origami was written for [seisan-line](http://github.com/akumano/seisan-line).
The documentation for seisan-line includes how to use origami.
11 changes: 11 additions & 0 deletions bin/hello.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
                i
      、        i!
      i,`ヽ、     i |
      i   丶、  ,i :|
       i;::_,、-、`1_ | .:|
      -'‐'"1i !、'i゛ヽ:;、__
       ヽ:::|| | /' _,、‐'" '`‐、
        ヽ|i!r'/       \
         W'" ̄''‐-、_.     \
                `''‐-―一
origami.
29 changes: 29 additions & 0 deletions bin/mseed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env ruby
### mseed.rb
### Reads a seed with empty entries.
### Recursively follow hash, replace it with a disired
### entry when an empty entry is found.

require 'yaml'


def follow_hash(hash,input)
hash.each_pair do |key,val|
if val == ''
hash[key] = input
else
hash[key] = follow_hash(val,input)
end
end
return hash
end

if __FILE__ == $0
hash = YAML.load_file(ARGV[0])
if ARGV.length > 1
input = ARGV[1..-1]
else
input = ARGV[1]
end
puts eval(follow_hash(hash,input).inspect).to_yaml
end
74 changes: 74 additions & 0 deletions bin/namegen.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env ruby
### namegen.rb
### A neat script to produce a list of
### all combinations of distro-ver.-arch
### for EL family distros
eldistro = ['CentOS','RedHat','Oracle','SL']
elversion = ['5','6']
debdistro = ['Ubuntu','Debian']
debversion = ['10','12','6']
arch = ['32','64']
type = ['typeA','typeB'] # create full list
#type = ['typeA'] # only typeA for testing purpose

list = ['distro','version','arch','type']


def nested_hash(array_of_arrays)
hash = {}
arr = array_of_arrays
tmp = arr.pop
tmp.each do |val|
hash[val] = ''
end
return helper(hash,arr)
end

def helper(hash,array)
if array.empty?
return hash
end
tmp = {}
arr = array.pop
arr.each do |val|
tmp[val] = hash
end
return helper(tmp,array)
end

if __FILE__ == $0
require 'yaml'
if ARGV.length == 0
abort 'no input!'
end

hash = {}
if ARGV[0] == 'el'
hash = {
'distro' => eldistro,
'version' => elversion,
'arch' => arch,
'type' => type
}
elsif ARGV[0] == 'deb'
hash = {
'distro' => debdistro,
'version' => debversion,
'arch' => arch,
'type' => type
}
end

contents = []
list.each do |elm|
if ARGV[1..-1].include?(elm)
contents << hash[elm]
end
end

result = nested_hash(contents)
# the following line is weird but I had to hack it up
# if 'puts result.to_yaml' were used, it returns a
# yaml hash containing object reference
puts eval(result.inspect).to_yaml
end
21 changes: 21 additions & 0 deletions bin/origami
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env ruby
### origami

project_path = File.expand_path(
File.join(File.dirname(__FILE__), '..', 'lib')
)

$LOAD_PATH.unshift(project_path) unless $LOAD_PATH.include?(project_path)

if ARGV.length == 0
piece_of_art = File.new(File.join(File.dirname(__FILE__), 'hello.txt'),'r').read
print( piece_of_art + "\n\n")
abort("'--help' for usage\n\n")
end

require 'origami'

if __FILE__ == $0
options = Origami::Options.parse_args
Origami.craft(options)
end
49 changes: 49 additions & 0 deletions lib/optparsing.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
### optparsing.rb

require 'optparse'

module Origami
class Options
attr_reader :options

def self.parse_args
@options = {}
optparse = OptionParser.new do |opts|
opts.banner = "Usage: origami.rb name [options]"

@options[:name] = []
opts.on('--name NAME') do |name|
@options[:name] << name
end

@options[:target] = nil
opts.on('--target DIR') do |dir|
@options[:target] = dir
end

@options[:instruction] = nil
opts.on('--definition') do
@options[:instruction] = 'definition'
end
opts.on('--kickstart') do
@options[:instruction] = 'kickstart'
end

@options[:file] = nil
opts.on('--file FILE') do |file|
@options[:file] = file
end

opts.on('-h','--help') do
puts opts
exit
end

end

optparse.parse!

return @options
end
end
end
40 changes: 40 additions & 0 deletions lib/origami.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env ruby
### origami.rb
### Calls build_from_seed.rb
### Usage: origami.rb <name> [<target directory>] [<instruction=--kickstart,--definition>]
### OR!
### origami.rb --file <file.yml> [<target directory>] :: where <file.yml> contains an array of names

require 'origami/core/build'
require 'optparsing'

module Origami
extend self

def craft(options)
names = options[:name]

if options[:file] != nil
require 'yaml'
names = YAML.load_file(options[:file])
end
build_each(names,options)
end

def build_each(names,options)
target = options[:target]
names.each do |name|
instruction = OSName.new(name).instruction
if options[:instruction] == nil
build(name, instruction, target)
puts
build(name,'definition', target)
puts
else
build(name, options[:instruction], target)
puts
end
end
end

end#Module
73 changes: 73 additions & 0 deletions lib/origami/core/build.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env ruby
### Takes a string of the form <distro>-<version>-<arch>-<type> then
### 1. Create a directory inside the hierarchy structure of
### '~/veewee/definitions/**'
### 2. (assume instruction='kickstart') Make kickstart seed (seed_builder.rb kickstart)
### 3. Build kickstart.cfg (ks_builder.rb <ks_seed>)

### To use it: (== follow veewee instruction)
### Place definition.rb in the directory && place ks.cfg on a http server
### Launch VM creation (vwf <definition_name>)

### Usage: build_from_seed.rb <os_name> <instruction> <target>
### os_name = <distro>-<version>-<arch>-<type>
### instruction = kickstart or definition
### target = target directory to place the files in

require 'origami_config'
require 'origami_config_private'
require 'origami/core/erb_base'
require 'origami/core/seed_builder'
require 'origami/core/ks_defn_builder'

module Origami

## Originally I meant to manage directories from here.
## It will be managed by puppet now.
def create_dir(name)
puts "Creating directory for #{name}..."
puts "~/veewee/definition/distro/version/arch/type"
end

## The main fucntion.
## Uses ks_base.erb and definition_base.erb as template.
## ks_defn_builder creates ks.cfg and definition.rb. (see ks_defn_builder.rb)
## seed_builder provides a hash that specifies options.
def build(name,instruction,target=nil)
ks_erb = File.join(ks_dir, 'ks_base.erb')
defn_erb = File.join(defn_dir, 'definition_base.erb')
autoinst_erb = File.join(autoinst_dir, 'autoinst_base.erb')
preseed_erb = File.join(preseed_dir, 'preseed_base.erb')

erb_path = {'kickstart' => ks_erb, 'definition' => defn_erb, 'autoinst' => autoinst_erb, 'preseed' => preseed_erb}[instruction]

filename = {'kickstart' => 'ks.cfg', 'definition' => 'definition.rb', 'autoinst' => 'autoinst.xml', 'preseed' => 'preseed.cfg'}[instruction]

# build seed
seed = seed_builder(name,instruction)
if target == nil
target = project_root + '/products/'
end

# use the seed to create file
File.open( File.join( target , name + '_' + filename), 'w') do |file|
print "Creating #{name}_#{filename}... "
content = ks_defn_builder(instruction, erb_path, seed)
file.write(content)
end
puts "Done."
print("#{instruction} file was created in #{target}.\n\n")
end

if __FILE__ == $0
name = ARGV[0]
instruction = ARGV[1]
if ARGV.length == 3
target = ARGV[2]
else
target = nil
end
build(name,'kickstart', target)
build(name,'definition', target)
end
end
Loading

0 comments on commit 3a7ddac

Please sign in to comment.