sunzi 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +70 -0
- data/Rakefile +1 -0
- data/bin/sunzi +3 -0
- data/lib/sunzi/base.rb +9 -0
- data/lib/sunzi/cli.rb +30 -0
- data/lib/sunzi/version.rb +3 -0
- data/lib/sunzi.rb +8 -0
- data/lib/templates/here/attributes.yml +3 -0
- data/lib/templates/here/compile.rb +11 -0
- data/lib/templates/here/deploy.sh +25 -0
- data/lib/templates/there/install.sh +8 -0
- data/lib/templates/there/recipes/ssh_key.sh +17 -0
- data/sunzi.gemspec +23 -0
- metadata +72 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
data/lib/sunzi/base.rb
ADDED
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
|
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,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,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: []
|