cloudler 0.1.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/README.markdown +31 -0
- data/bin/cloud +22 -0
- data/cloudler.gemspec +16 -0
- data/lib/cloudler.rb +123 -0
- metadata +59 -0
data/README.markdown
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Introduction
|
2
|
+
============
|
3
|
+
|
4
|
+
Cloudler is a way to easily run a command on one or many remote servers. It logs into a server via SSH, uploads either the entire current project, or some specified project, installs any specified gems, and runs a specified command in the project's directory.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
To install Cloudler, run
|
10
|
+
|
11
|
+
$ gem install cloudler
|
12
|
+
|
13
|
+
Usage
|
14
|
+
-----
|
15
|
+
|
16
|
+
To create a cloudler project:
|
17
|
+
|
18
|
+
$ cloud init
|
19
|
+
|
20
|
+
This creates a Cloudfile in the current directory. Just update the Cloudfile with your information and you're all set to go.
|
21
|
+
|
22
|
+
To run a command, simply use:
|
23
|
+
|
24
|
+
$ cloud run
|
25
|
+
|
26
|
+
Notes
|
27
|
+
-----
|
28
|
+
|
29
|
+
Cloudler runs commands blockingly, so if you have a long task that you want run, and/or multiple servers you want to run it on, it's probably a good idea to use screen. For example,
|
30
|
+
|
31
|
+
command 'screen -dmS [Your Command]'
|
data/bin/cloud
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cloudler'
|
4
|
+
if ARGV.first == 'init'
|
5
|
+
Cloudler.init
|
6
|
+
elsif ARGV.first == 'run'
|
7
|
+
if File.exists? 'Cloudfile'
|
8
|
+
File.open 'Cloudfile', 'r' do |f|
|
9
|
+
config = f.read
|
10
|
+
eval config
|
11
|
+
end
|
12
|
+
|
13
|
+
Cloudler.run
|
14
|
+
else
|
15
|
+
puts "It doesn't like this is a cloudler project. Try running 'cloud init'"
|
16
|
+
end
|
17
|
+
else
|
18
|
+
puts "Usage: cloud [command]"
|
19
|
+
puts " commands:"
|
20
|
+
puts " init -- create a new cloudler project"
|
21
|
+
puts " run -- run a cloud project"
|
22
|
+
end
|
data/cloudler.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require './lib/cloudler.rb'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'cloudler'
|
5
|
+
s.version = '0.1.1'
|
6
|
+
s.authors = ["Bruce Spang"]
|
7
|
+
s.date = Time.now.utc.strftime("%Y-%m-%d")
|
8
|
+
s.email = %q{bruce@brucespang.com}
|
9
|
+
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
s.summary = %q{Runs a script on a remote server}
|
13
|
+
s.executables = %w(cloud)
|
14
|
+
s.default_executable = 'cloud'
|
15
|
+
end
|
16
|
+
|
data/lib/cloudler.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
require 'net/scp'
|
3
|
+
|
4
|
+
class Cloudler
|
5
|
+
def self.hosts= hosts
|
6
|
+
@hosts = hosts
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.username= username
|
10
|
+
@username = username
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.command= string
|
14
|
+
@command = string
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.gems= array
|
18
|
+
@gems = array
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.password= password
|
22
|
+
@password = password
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.files= files
|
26
|
+
@files = files
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.precommands= precommands
|
30
|
+
@precommands = precommands
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.run
|
34
|
+
@files ||= []
|
35
|
+
@gems ||= []
|
36
|
+
@precommands ||= []
|
37
|
+
|
38
|
+
@hosts.each do |host|
|
39
|
+
Net::SSH.start(host, @username, :password => @password) do |ssh|
|
40
|
+
puts "Uploading files..."
|
41
|
+
ssh.exec! "rm -rf /home/#{@username}/.cloudler"
|
42
|
+
ssh.exec! "mkdir /home/#{@username}/.cloudler"
|
43
|
+
if @files.length > 0
|
44
|
+
ssh.scp.upload(@files.join(' '), "/home/#{@username}/.cloudler", :recursive => true)
|
45
|
+
else
|
46
|
+
ssh.scp.upload!('.', "/home/#{@username}/.cloudler", :recursive => true)
|
47
|
+
end
|
48
|
+
|
49
|
+
puts "Files uploaded."
|
50
|
+
|
51
|
+
if @gems.length > 0
|
52
|
+
puts "Installing gems..."
|
53
|
+
ssh.exec! "gem install #{@gems.join ' '}" do |ch, stream, data|
|
54
|
+
puts data
|
55
|
+
end
|
56
|
+
puts "Gems installed"
|
57
|
+
end
|
58
|
+
|
59
|
+
if @precommands.length > 0
|
60
|
+
puts "Executing pre-commands"
|
61
|
+
@precommands.each do |command|
|
62
|
+
ssh.exec "cd /home/#{@username}/.cloudler && #{command}" do |ch,stream,data|
|
63
|
+
puts data
|
64
|
+
end
|
65
|
+
end
|
66
|
+
puts "Pre-commands executed."
|
67
|
+
end
|
68
|
+
|
69
|
+
puts "Executing command..."
|
70
|
+
ssh.exec! "cd /home/#{@username}/.cloudler && #{@command}" do |ch, stream, data|
|
71
|
+
puts data
|
72
|
+
end
|
73
|
+
puts "Command finished."
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.init
|
79
|
+
File.open "Cloudfile", 'w' do |f|
|
80
|
+
f.write <<-EOS
|
81
|
+
host 'HOSTNAME' # or for multiple servers, use ['HOST1', 'HOST2', ...]
|
82
|
+
username 'USERNAME'
|
83
|
+
password 'PASSWORD'
|
84
|
+
precommands [] # Optional list of commands to run before executing the main command
|
85
|
+
command 'COMMAND'
|
86
|
+
files [] # Optional list of files to upload
|
87
|
+
gems [] # Optional list of gems to install
|
88
|
+
EOS
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def host hosts
|
94
|
+
if hosts.is_a? Array
|
95
|
+
Cloudler.hosts = hosts
|
96
|
+
else
|
97
|
+
Cloudler.hosts = [hosts]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def username name
|
102
|
+
Cloudler.username = name
|
103
|
+
end
|
104
|
+
|
105
|
+
def command string
|
106
|
+
Cloudler.command = string
|
107
|
+
end
|
108
|
+
|
109
|
+
def gems array
|
110
|
+
Cloudler.gems = array
|
111
|
+
end
|
112
|
+
|
113
|
+
def password pass
|
114
|
+
Cloudler.password = pass
|
115
|
+
end
|
116
|
+
|
117
|
+
def files array
|
118
|
+
Cloudler.files = array
|
119
|
+
end
|
120
|
+
|
121
|
+
def precommands array
|
122
|
+
Cloudler.precommands = array
|
123
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bruce Spang
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-02-22 00:00:00 -05:00
|
14
|
+
default_executable: cloud
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description:
|
18
|
+
email: bruce@brucespang.com
|
19
|
+
executables:
|
20
|
+
- cloud
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- README.markdown
|
27
|
+
- bin/cloud
|
28
|
+
- cloudler.gemspec
|
29
|
+
- lib/cloudler.rb
|
30
|
+
has_rdoc: true
|
31
|
+
homepage:
|
32
|
+
licenses: []
|
33
|
+
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.5.2
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Runs a script on a remote server
|
58
|
+
test_files: []
|
59
|
+
|