simple_provision 0.99.5 → 0.99.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1b94eb29ab3fa531033b62ec0f7b9f957c54122
4
- data.tar.gz: 716bd8499c0435e8055c432b1561cbd17733d8da
3
+ metadata.gz: c1ff2a55eb683cc8e6f25b12c8565bd62c93bc99
4
+ data.tar.gz: 2ac7128c70fde4cac971896fab7132a46e9446f5
5
5
  SHA512:
6
- metadata.gz: 42580941b0da8fa9e8c977a8a3f6326153c32aa9f3090b51f9bedbcd18d5683e060c2b9f5397674a281f0e54da6198c7ab9b8eae20cf22fc2f7a417e9ad9845a
7
- data.tar.gz: c10a3d916d57b1d1f8b84401ffcbb2935e9bff921df3e57ec842a9187409789516af3b088fcd250a28c7e7dbb5402fe0358cddf8e77603d8c3fdce00d406ad66
6
+ metadata.gz: a6fb5a3e387013d6db44ab56e0ba6213f0d762d0ffbcd4dc72afacebe0e6232a3ef4cbf51a3503094af68fbe2a7a026a8959c1a4cb05819d8ee58943a859168a
7
+ data.tar.gz: 67d345ad0b1fe411acc5c14710025153dde7dc3e91ddc8b1474b00161e824aa42825a3cf4b1eddc0f14a4cafef59b2e6ca1c8d99a86d9996e2117513c2e2c48e
data/README.md CHANGED
@@ -1,12 +1,10 @@
1
1
  # Introduction
2
2
  This is based on the work that brandonhilkert initally carried to automate
3
- EC2 instance provision with YAML and SHELL script. It tries to bring the good spirit: SIMPLE, and JUST WORK to the world of Digital Ocean.
3
+ EC2 instance provision with YAML and SHELL script. It tries to bring the good spirit: SIMPLE, and JUST WORK to the world of every remote machine.
4
4
 
5
- If you own a Digital Ocean, here is my advice: Chef and Puppet is shitty
6
- thing that just create more problems than it solves. It will take you
7
- days even weeks just to get familar and put things in the right order.
8
-
9
- With simple_provision, you get your hand dirty in a few minutes and
5
+ I had been banging my head trying to work with Chef and Puppet in the
6
+ past, so this is my attempt to make the provision stuff easier to be
7
+ implemented. With this tool, you get your hand dirty in a few minutes and
10
8
  we have the working provision profile in just half an hour. From that
11
9
  moment, provision another instance is just the matter of kicking off
12
10
  a command from the terminal.
@@ -19,7 +17,7 @@ Let's rock.
19
17
  ### Recipes repo
20
18
 
21
19
  Don't forget to also checkout the recipes collection
22
- https://github.com/phuongnd08/simple_privision_recipes
20
+ https://github.com/phuongnd08/simple_provision_recipes
23
21
 
24
22
  # How it works
25
23
  This gem carries the provision by uploading a set of scripts (and
@@ -64,7 +62,7 @@ It's up to you to use ERB, HAML or any kind of template processors.
64
62
 
65
63
  So: You put definition of each type of server in `servers/type.yml`.
66
64
  In `files` and `scripts` folder, you place files and scripts that will be
67
- uploaded to the Digital Ocean droplet and executed.
65
+ uploaded to the server machine and executed there.
68
66
 
69
67
  ## Installation
70
68
 
@@ -114,8 +112,8 @@ Variables defined in `env` will be exposed to scripts during execution.
114
112
  That way you can use the same scripts for different type of server and
115
113
  still be able to produce different outcomes.
116
114
 
117
- ## Provision your Digital Ocean server:
118
- `simpro y-awesome-server --droplet-name YOUR_DROPLET_NAME`
115
+ ## Provision your server
116
+ `simpro my-awesome-server root@my-host`
119
117
 
120
118
  ## Contributing
121
119
 
data/bin/simpro CHANGED
@@ -4,25 +4,13 @@ require 'optparse'
4
4
  require_relative '../lib/simple_provision'
5
5
 
6
6
  options = {}
7
-
8
- OptionParser.new do |opts|
9
- opts.banner = "Usage: fss [options] type"
10
-
11
- opts.on('--droplet-name NAME', 'An exiting Droplet Name' ) do |name|
12
- options[:droplet_name] = name
13
- end
14
-
15
- opts.on('-h', '--help', 'Display this screen' ) do
16
- puts opts
17
- exit
18
- end
19
-
20
- opts.on('-v', '--version', 'Show version' ) do
21
- puts SimpleProvision::Version
22
- end
23
- end.parse!
24
-
25
- options.merge!(type: ARGV.first)
26
-
27
- cli = SimpleProvision::CLI.new(options)
7
+ invalid_argument = false
8
+ invalid_argument = true if ARGV.length != 2
9
+ unless invalid_argument
10
+ username, host = ARGV.last.split('@')
11
+ invalid_argument = username.nil? || host.nil?
12
+ end
13
+
14
+ cli = SimpleProvision::CLI.new(profile: ARGV.first, username: username, host: host)
15
+ cli.bootstrap
28
16
  cli.configure
@@ -1,4 +1,4 @@
1
- require "simple_provision/version"
1
+ require_relative "simple_provision/version"
2
2
 
3
3
  begin
4
4
  require 'pry'
@@ -7,8 +7,4 @@ end
7
7
 
8
8
  require_relative 'simple_provision/cli'
9
9
  require_relative 'simple_provision/configuration'
10
- require_relative 'simple_provision/connection'
11
10
  require_relative 'simple_provision/scp'
12
- require_relative 'simple_provision/server'
13
-
14
- require_relative 'ext/fog'
@@ -1,30 +1,48 @@
1
+ require 'net/ssh'
2
+
1
3
  module SimpleProvision
2
4
  class CLI
3
- def initialize(opts = {})
4
- @opts = opts
5
- @connection = SimpleProvision::Connection.new(options).connection
5
+ attr_reader :profile, :username, :host
6
+ def initialize(args)
7
+ @profile = args[:profile]
8
+ @username = args[:username]
9
+ @host = args[:host]
6
10
  end
7
11
 
8
12
  def bootstrap
9
- server.bootstrap
10
- end
11
-
12
- def build
13
- server.build
13
+ SimpleProvision::SCP.new(username, host, options).copy_files
14
14
  end
15
15
 
16
16
  def configure
17
- server.configure
17
+ Net::SSH.start(host, username) do |ssh|
18
+ ssh.exec! "tar -xzf #{SimpleProvision::SCP::FILENAME}"
19
+ scripts = options.fetch(:scripts).each do |script|
20
+ puts "Execute #{script}"
21
+ ssh.exec!("#{environment_exports} bash -c '#{script}'") do |channel, stream, data|
22
+ print data
23
+ end
24
+ end
25
+ end
18
26
  end
19
27
 
20
28
  private
21
29
 
30
+ def environment_exports
31
+ @environment_exports ||= begin
32
+ if options[:env].nil?
33
+ ""
34
+ else
35
+ options[:env].map { |k, v| [k, Shellwords.escape(v)].join("=") }.join(" ")
36
+ end
37
+ end
38
+ end
39
+
22
40
  def server
23
41
  SimpleProvision::Server.new(@connection, options)
24
42
  end
25
43
 
26
44
  def options
27
- @options ||= SimpleProvision::Configuration.new(@opts).options
45
+ @options ||= SimpleProvision::Configuration.new(@profile).options
28
46
  end
29
47
  end
30
48
  end
@@ -6,13 +6,12 @@ module SimpleProvision
6
6
  MissingServerConfiguration = Class.new(StandardError)
7
7
 
8
8
  attr_reader :options
9
+ attr_reader :profile
9
10
 
10
- def initialize(command_line_options = {})
11
- @command_line_options = command_line_options
11
+ def initialize(profile)
12
+ @profile = profile
12
13
 
13
14
  read_and_parse_server_options
14
-
15
- raise MissingServerType, "Please specify a type of server you want to create using the --type option" unless options[:type]
16
15
  end
17
16
 
18
17
  private
@@ -29,21 +28,17 @@ module SimpleProvision
29
28
  begin
30
29
  YAML.load(File.read(server_file))
31
30
  rescue Errno::ENOENT
32
- raise MissingServerConfiguration, "Please create a configuration file './servers/#{type}.yml'"
31
+ raise MissingServerConfiguration, "Please create a configuration file './servers/#{profile}.yml'"
33
32
  end
34
33
  end
35
34
 
36
35
  def server_file
37
- "servers/#{type}.yml"
36
+ "servers/#{profile}.yml"
38
37
  end
39
38
 
40
39
  def read_and_parse_server_options
41
- options_string_hash = default_options.merge(server_options).merge(@command_line_options)
40
+ options_string_hash = default_options.merge(server_options)
42
41
  @options = Hash[options_string_hash.map{ |(k,v)| [k.to_sym, v] }]
43
42
  end
44
-
45
- def type
46
- @command_line_options[:type]
47
- end
48
43
  end
49
44
  end
@@ -1,15 +1,17 @@
1
+ require 'net/scp'
2
+ require 'byebug'
3
+
1
4
  module SimpleProvision
2
5
  class SCP
3
6
  FILENAME = "simpro.tar.gz"
4
7
 
5
- def initialize(server, opts)
6
- @server, @opts = server, opts
8
+ def initialize(username, host, opts)
9
+ @username, @host, @opts = username, host, opts
7
10
  end
8
11
 
9
- def to_server
12
+ def copy_files
10
13
  create_local_archive
11
14
  scp_files_to_server
12
- extract_remote_archive
13
15
  remove_local_archive
14
16
  end
15
17
 
@@ -38,11 +40,11 @@ module SimpleProvision
38
40
  end
39
41
 
40
42
  def scp_files_to_server
41
- @server.scp("tmp/#{FILENAME}", ".")
42
- end
43
-
44
- def extract_remote_archive
45
- @server.ssh("tar -xzf #{FILENAME}")
43
+ Net::SCP.start(@host, @username) do |scp|
44
+ scp.upload!("tmp/#{FILENAME}", ".")
45
+ end
46
+ rescue Net::SSH::HostKeyMismatch
47
+ puts "Please run ssh #{@username}@#{@host} to verify the fingerprint first"
46
48
  end
47
49
 
48
50
  def remove_local_archive
@@ -1,3 +1,3 @@
1
1
  module SimpleProvision
2
- VERSION = "0.99.5"
2
+ VERSION = "0.99.6"
3
3
  end
@@ -21,5 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
23
 
24
- spec.add_dependency "fog", ">= 1.21.0"
24
+ spec.add_dependency "net-scp"
25
+ spec.add_dependency "net-ssh"
25
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_provision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.99.5
4
+ version: 0.99.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phuong Gia Su
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-09 00:00:00.000000000 Z
12
+ date: 2014-07-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -40,19 +40,33 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: fog
43
+ name: net-scp
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - '>='
47
47
  - !ruby/object:Gem::Version
48
- version: 1.21.0
48
+ version: '0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - '>='
54
54
  - !ruby/object:Gem::Version
55
- version: 1.21.0
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: net-ssh
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  description: The easiest, most common sense server provision tool.
57
71
  email:
58
72
  - phuongnd08@gmail.com
@@ -68,13 +82,10 @@ files:
68
82
  - README.md
69
83
  - Rakefile
70
84
  - bin/simpro
71
- - lib/ext/fog.rb
72
85
  - lib/simple_provision.rb
73
86
  - lib/simple_provision/cli.rb
74
87
  - lib/simple_provision/configuration.rb
75
- - lib/simple_provision/connection.rb
76
88
  - lib/simple_provision/scp.rb
77
- - lib/simple_provision/server.rb
78
89
  - lib/simple_provision/version.rb
79
90
  - simple_provision.gemspec
80
91
  homepage: https://github.com/phuongnd08/simple_provision
data/lib/ext/fog.rb DELETED
@@ -1,52 +0,0 @@
1
- require 'fog'
2
- require 'fog/core/ssh'
3
-
4
- # Monkey-patch Fog 1.3.1 to stream SSH output
5
- # (in real time) to stdout.
6
- class Fog::SSH::Real
7
- def run(commands)
8
- commands = [*commands]
9
- results = []
10
- begin
11
- Net::SSH.start(@address, @username, @options) do |ssh|
12
- commands.each do |command|
13
- result = Fog::SSH::Result.new(command)
14
- ssh.open_channel do |ssh_channel|
15
- ssh_channel.request_pty
16
- ssh_channel.exec(command) do |channel, success|
17
- unless success
18
- raise "Could not execute command: #{command.inspect}"
19
- end
20
-
21
- channel.on_data do |ch, data|
22
- result.stdout << data
23
- puts data
24
- end
25
-
26
- channel.on_extended_data do |ch, type, data|
27
- next unless type == 1
28
- result.stderr << data
29
- puts data
30
- end
31
-
32
- channel.on_request('exit-status') do |ch, data|
33
- result.status = data.read_long
34
- end
35
-
36
- channel.on_request('exit-signal') do |ch, data|
37
- result.status = 255
38
- end
39
- end
40
- end
41
- ssh.loop
42
- results << result
43
- end
44
- end
45
- rescue Net::SSH::HostKeyMismatch => exception
46
- exception.remember_host!
47
- sleep 0.2
48
- retry
49
- end
50
- results
51
- end
52
- end
@@ -1,25 +0,0 @@
1
- require 'fog'
2
-
3
- module SimpleProvision
4
- class Connection
5
- MissingDigitalOceanCredentials = Class.new(StandardError)
6
-
7
- def initialize(opts)
8
- @opts = opts
9
-
10
- if ENV["DIGITAL_OCEAN_API_KEY"].nil? || ENV["DIGITAL_OCEAN_CLIENT_ID"].nil?
11
- raise SimpleProvision::Connection::MissingDigitalOceanCredentials, "Make sure DIGITAL_OCEAN_API_KEY and DIGITAL_OCEAN_CLIENT_ID are environmental variables with your credentials"
12
- end
13
- end
14
-
15
- def connection
16
- @connection ||= begin
17
- Fog::Compute.new(
18
- provider: "DigitalOcean",
19
- digitalocean_client_id: ENV["DIGITAL_OCEAN_CLIENT_ID"],
20
- digitalocean_api_key: ENV["DIGITAL_OCEAN_API_KEY"]
21
- )
22
- end
23
- end
24
- end
25
- end
@@ -1,55 +0,0 @@
1
- require 'shellwords'
2
-
3
- module SimpleProvision
4
- class Server
5
- ServerNotFound = Class.new(StandardError)
6
- MissingDropletName = Class.new(StandardError)
7
-
8
- attr_reader :server
9
-
10
- def initialize(connection, options)
11
- @connection, @options = connection, options
12
- end
13
-
14
- def configure
15
- get(options[:droplet_name]) if server.nil?
16
- raise ServerNotFound, "Unable to find server with Droplet name #{options[:droplet_name]}." if server.nil?
17
-
18
- SimpleProvision::SCP.new(server, options).to_server
19
- scripts = options.fetch(:scripts).map do |script|
20
- "#{environment_exports} bash -c '#{script}'"
21
- end
22
- server.ssh(scripts)
23
- end
24
-
25
- def environment_exports
26
- @environment_exports ||= begin
27
- if options[:env].nil?
28
- ""
29
- else
30
- options[:env].map { |k, v| [k, Shellwords.escape(v)].join("=") }.join(" ")
31
- end
32
- end
33
- end
34
-
35
- private
36
-
37
- attr_reader :options, :connection
38
-
39
- def get(droplet_name)
40
- if droplet_name.nil?
41
- raise SimpleProvision::Server::MissingDropletName ,
42
- "Please specify the Droplet Name using the --droplet-name option."
43
- end
44
- @server = connection.servers.detect { |server| server.name == droplet_name }
45
- if options.has_key?(:private_key_path)
46
- @server.private_key_path = options.fetch(:private_key_path)
47
- end
48
- @server
49
- end
50
-
51
- def name
52
- "#{options.fetch(:name).downcase.sub(/ /, '-')}-#{Time.now.strftime("%y-%m-%d-%H-%M")}"
53
- end
54
- end
55
- end