sunzi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sunzi.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ Sunzi
2
+ =====
3
+
4
+ ```
5
+ "The supreme art of war is to subdue the enemy without fighting." - Sunzi
6
+ ```
7
+
8
+ Sunzi is a server provisioning tool for minimalists. Simplicity is the one and only goal - if Chef or Puppet is driving you nuts, try Sunzi.
9
+
10
+ Sunzi assumes that Linux distributions have (mostly) sane defaults.
11
+
12
+ Its design goals are:
13
+
14
+ * A big-bang overwriting with loads of custom configurations makes it difficult to know **what you are actually doing** - instead, Sunzi let you keep track of as little diff from default as possible.
15
+ * No mysterious Ruby DSL involved. Sunzi recipes are written in a plain shell script. Why? Because, most of the information about server configuration you get on the web is written in a set of shell commands. Why should you translate it into a proprietary DSL, rather than just copy-paste?
16
+ * No configuration server. No dependency. You don't even need a Ruby runtime on the remote server.
17
+
18
+ Quickstart
19
+ ----------
20
+
21
+ Install:
22
+
23
+ $ gem install sunzi
24
+
25
+ Go to your project directory, then:
26
+
27
+ $ sunzi create
28
+
29
+ It generates a `sunzi` folder, subdirectories and some templates for you. Inside `sunzi`, there's `here` folder, which will be kept in your local machine, that contains some scripts and definition files. Also there's `there` folder, which will be transferred to the remote server, that contains recipes and dynamic variables compiled from the definition files in the `here` folder.
30
+
31
+ Go into the `here` directory, then run the `deploy.sh`:
32
+
33
+ $ cd sunzi/here
34
+ $ bash deploy.sh root@example.com
35
+
36
+ Now, what it actually does is:
37
+
38
+ 1. SSH to `example.com` and login as `root`
39
+ 1. Transfer the content of the `there` directory to the remote server and extract in `$HOME/sunzi`
40
+ 1. Run `install.sh` in the remote server
41
+
42
+ As you can see, what you need to do is edit `install.sh` and add some shell commands. That's it.
43
+
44
+ Tutorial
45
+ --------
46
+
47
+ Here's the directory structure that `sunzi create` automatically generates:
48
+
49
+ ```
50
+ sunzi/
51
+ here/ ---- kept in your local machine
52
+ attributes.yml ---- add custom variables here
53
+ compile.rb ---- compile the content of attributes.yml to there/attributes/*
54
+ deploy.sh ---- invoke this script
55
+ there/ ---- transferred to the remote server
56
+ attributes/ ---- compiled from attributes.yml at deploy
57
+ env
58
+ ssh_key
59
+ recipes/ ---- put commonly used scripts here, referred from install.sh
60
+ ssh_key.sh
61
+ install.sh ---- main scripts that gets run on the remote server
62
+ ```
63
+
64
+ Vagrant
65
+ -------
66
+
67
+ If you're using Sunzi with [Vagrant](http://vagrantup.com/), make sure you allowed SSH access for root, then:
68
+
69
+ $ vagrant up
70
+ $ bash deploy.sh root@localhost -p 2222
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/sunzi ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path('../../lib/sunzi',__FILE__)
3
+ Sunzi::Cli.start
data/lib/sunzi/base.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'yaml'
2
+
3
+ module Sunzi
4
+ class Base
5
+ def initialize(project)
6
+ # Do something
7
+ end
8
+ end
9
+ end
data/lib/sunzi/cli.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'thor'
2
+
3
+ module Sunzi
4
+ CONFIG_DIR = File.join(ENV['HOME'],'.config','sunzi')
5
+
6
+ class Cli < Thor
7
+ include Thor::Actions
8
+
9
+ class << self
10
+ def source_root
11
+ File.expand_path('../../',__FILE__)
12
+ end
13
+ end
14
+
15
+ map "c" => :create
16
+
17
+ desc "create [PROJECT]", "Create sunzi project (Shortcut: c)"
18
+ def create(project = 'sunzi')
19
+ empty_directory project
20
+ empty_directory "#{project}/here"
21
+ empty_directory "#{project}/there"
22
+ empty_directory "#{project}/there/recipes"
23
+ template "templates/here/attributes.yml", "#{project}/here/attributes.yml"
24
+ template "templates/here/compile.rb", "#{project}/here/compile.rb"
25
+ template "templates/here/deploy.sh", "#{project}/here/deploy.sh"
26
+ template "templates/there/install.sh", "#{project}/there/install.sh"
27
+ template "templates/there/recipes/ssh_key.sh", "#{project}/there/recipes/ssh_key.sh"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Sunzi
2
+ VERSION = "0.0.1"
3
+ end
data/lib/sunzi.rb ADDED
@@ -0,0 +1,8 @@
1
+ LIB_PATH = File.join(File.dirname(__FILE__), 'sunzi')
2
+
3
+ module Sunzi
4
+ autoload :Base, File.join(LIB_PATH, 'base')
5
+ autoload :Cli, File.join(LIB_PATH, 'cli')
6
+ autoload :Dependency, File.join(LIB_PATH, 'dependency')
7
+ autoload :Version, File.join(LIB_PATH, 'version')
8
+ end
@@ -0,0 +1,3 @@
1
+ --- # Dynamic variables here will be compiled to individual files in there/attributes.
2
+ env: production
3
+ ssh_key: id_rsa.pub
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+ hash = YAML.load(File.read('attributes.yml'))
5
+
6
+ require 'fileutils'
7
+ FileUtils.mkdir_p('../there/attributes')
8
+
9
+ hash.each do |key, value|
10
+ File.open("../there/attributes/#{key}", 'w'){|file| file.write(value) }
11
+ end
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+
3
+ # Usage: bash deploy.sh [host] [-p 2222]
4
+
5
+ if [ -z "$1" ]; then
6
+ echo "Usage: bash deploy.sh user@example.com"
7
+ exit 1
8
+ fi
9
+
10
+ # Compile attributes
11
+ ruby compile.rb
12
+
13
+ # The host key might change when we instantiate a new VM, so
14
+ # we remove (-R) the old host key from known_hosts
15
+ host="$1"
16
+ ssh-keygen -R "${host#*@}" 2> /dev/null
17
+
18
+ # Connect to the remote server and deploy
19
+ cd ../there
20
+ tar cz . | ssh -o 'StrictHostKeyChecking no' "$host" "$2" "$3" '
21
+ rm -rf ~/sunzi &&
22
+ mkdir ~/sunzi &&
23
+ cd ~/sunzi &&
24
+ tar xz &&
25
+ bash install.sh'
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ # SSH key
4
+ source recipes/ssh_key.sh $(cat attributes/ssh_key)
5
+
6
+ # Update apt catalog
7
+ aptitude update
8
+ aptitude -y safe-upgrade
@@ -0,0 +1,17 @@
1
+ # SSH key
2
+ # $1: SSH key filename
3
+
4
+ if [ -f ~/.ssh/authorized_keys ]; then
5
+ echo 'authorized_keys already created'
6
+ else
7
+ if [ -f "$1" ]; then
8
+ mkdir -p ~/.ssh
9
+ cat $1 > ~/.ssh/authorized_keys
10
+ rm $1
11
+ chmod 700 ~/.ssh
12
+ chmod 600 ~/.ssh/authorized_keys
13
+ else
14
+ echo 'The public key file ($1) not found! Copy it from $HOME/.ssh to the "there" directory.'
15
+ echo 'If the file name found in .ssh is different from $1, edit here/attributes.yml as appropriate.'
16
+ fi
17
+ fi
data/sunzi.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sunzi/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sunzi"
7
+ s.version = Sunzi::VERSION
8
+ s.authors = ["Kenn Ejima"]
9
+ s.email = ["kenn.ejima@gmail.com"]
10
+ s.homepage = "http://github.com/kenn/sunzi"
11
+ s.summary = %q{Server provisioning tool for minimalists}
12
+ s.description = %q{The supreme art of war is to subdue the enemy without fighting.}
13
+
14
+ s.rubyforge_project = "sunzi"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # s.add_development_dependency "rspec"
22
+ s.add_runtime_dependency "thor"
23
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sunzi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kenn Ejima
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &2160818440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2160818440
25
+ description: The supreme art of war is to subdue the enemy without fighting.
26
+ email:
27
+ - kenn.ejima@gmail.com
28
+ executables:
29
+ - sunzi
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - bin/sunzi
38
+ - lib/sunzi.rb
39
+ - lib/sunzi/base.rb
40
+ - lib/sunzi/cli.rb
41
+ - lib/sunzi/version.rb
42
+ - lib/templates/here/attributes.yml
43
+ - lib/templates/here/compile.rb
44
+ - lib/templates/here/deploy.sh
45
+ - lib/templates/there/install.sh
46
+ - lib/templates/there/recipes/ssh_key.sh
47
+ - sunzi.gemspec
48
+ homepage: http://github.com/kenn/sunzi
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project: sunzi
68
+ rubygems_version: 1.8.15
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Server provisioning tool for minimalists
72
+ test_files: []