silk 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +58 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/silk +4 -0
- data/lib/silk.rb +39 -0
- data/lib/silk/http.rb +2 -0
- data/lib/silk/options.rb +70 -0
- data/lib/silk/server.rb +49 -0
- data/lib/silk/tasks.rb +25 -0
- data/test/helper.rb +10 -0
- data/test/test_silk.rb +7 -0
- metadata +99 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Myles Eftos
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
= silk
|
2
|
+
|
3
|
+
Silk is a a flexible framework for building web hosting consoles. It's based around a rake task runner that has a HTTP/JSON interface.
|
4
|
+
It allows you to build rake tasks to do things like add users, create email addresses etc. Then you simply wrap the response in a JSON
|
5
|
+
envelope, and you can then build your own custom web hosting console.
|
6
|
+
|
7
|
+
This gem is just the runner, that need to be installed on all client servers.
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
(Requires Gemcutter)
|
12
|
+
|
13
|
+
gem install silk
|
14
|
+
|
15
|
+
Create /etc/silk and drop in a Rakefile - you can also add *.rake files in /etc/silk (or $HOME/.silk/) and they will automatically be read in.
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
The gem should install an executable called silk
|
20
|
+
|
21
|
+
run silk -h for full argument descriptions.
|
22
|
+
|
23
|
+
The system automatically converts the rest URL (only GETs at the moment) into a rake task name - if the name doesn't exist, you'll get a 404. Any query params get passed into the task
|
24
|
+
|
25
|
+
So http://localhost:8888/users/get?login=myles
|
26
|
+
|
27
|
+
would run the users:get task. do something like this in the rake task:
|
28
|
+
|
29
|
+
namespace :users do
|
30
|
+
task :get do |t, args|
|
31
|
+
# args[:login] will be populated with myles
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
NOTE: The idea is you write your own rake task to do stuff, and then interface them how you want. The project doesn't care what data you transfer and represent, although it would be possible to share rakefiles and interfaces for common tasks.
|
36
|
+
|
37
|
+
By default it runs on port 8888 and will probably need to be run as root to make sure you can do all the stuff you need to do.
|
38
|
+
|
39
|
+
Eventually it'll support SSL certificates etc, but until then, I suggest you either use SSH tunnels, and/or (at the very least) lock down via a firewall. You could also build a rack.up file, and run it behind a web server that gives you more control (Rack.up file is on the todo list).
|
40
|
+
|
41
|
+
== Status
|
42
|
+
|
43
|
+
This is a really early release, that still needs formal testing (This is so far more proof of concept at this point), and may blow up at any given moment. Feel free to fork and help out.
|
44
|
+
|
45
|
+
== Note on Patches/Pull Requests
|
46
|
+
|
47
|
+
* Fork the project.
|
48
|
+
* Make your feature addition or bug fix.
|
49
|
+
* Add tests for it. This is important so I don't break it in a
|
50
|
+
future version unintentionally.
|
51
|
+
* Commit, do not mess with rakefile, version, or history.
|
52
|
+
(if you want to have your own version, that is fine but
|
53
|
+
bump version in a commit by itself I can ignore when I pull)
|
54
|
+
* Send me a pull request. Bonus points for topic branches.
|
55
|
+
|
56
|
+
== Copyright
|
57
|
+
|
58
|
+
Copyright (c) 2010 Myles Eftos. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "silk"
|
8
|
+
gem.executables = "silk"
|
9
|
+
gem.summary = %Q{A framework for creating a hosting console}
|
10
|
+
gem.description = %Q{It allows you to write rake tasks to do common tasks, such as creating email addresses, adding users etc. Silk provides a HTTP wrapper the the rake tasks, and allows communication via JSON objects, which makes it dead easy for them to be called from a web app.}
|
11
|
+
gem.email = "myles@madpilot.com.au"
|
12
|
+
gem.homepage = "http://github.com/madpilot/silk"
|
13
|
+
gem.authors = ["Myles Eftos"]
|
14
|
+
|
15
|
+
gem.add_dependency 'daemons'
|
16
|
+
gem.add_dependency 'SyslogLogger'
|
17
|
+
|
18
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
19
|
+
end
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
Rake::TestTask.new(:test) do |test|
|
26
|
+
test.libs << 'lib' << 'test'
|
27
|
+
test.pattern = 'test/**/test_*.rb'
|
28
|
+
test.verbose = true
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
require 'rcov/rcovtask'
|
33
|
+
Rcov::RcovTask.new do |test|
|
34
|
+
test.libs << 'test'
|
35
|
+
test.pattern = 'test/**/test_*.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
38
|
+
rescue LoadError
|
39
|
+
task :rcov do
|
40
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
task :test => :check_dependencies
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "silk #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/silk
ADDED
data/lib/silk.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(File.expand_path(__FILE__)), 'silk')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'syslog_logger'
|
6
|
+
require 'daemons'
|
7
|
+
require 'options'
|
8
|
+
require 'server'
|
9
|
+
require 'tasks'
|
10
|
+
|
11
|
+
module Silk
|
12
|
+
def self.run
|
13
|
+
options = Options.parse
|
14
|
+
|
15
|
+
if options[:ontop]
|
16
|
+
options[:logger] = Logger.new(STDOUT)
|
17
|
+
else
|
18
|
+
options[:logger] = SyslogLogger.new('silk')
|
19
|
+
end
|
20
|
+
|
21
|
+
Silk.options = options
|
22
|
+
|
23
|
+
old_proc_name = $0
|
24
|
+
pwd = Dir.pwd
|
25
|
+
Daemons.call(options) do
|
26
|
+
$0 = old_proc_name
|
27
|
+
Dir.chdir pwd
|
28
|
+
Server.run! :host => options[:bind], :port => options[:port], :environment => :production
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.options
|
33
|
+
@options
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.options=(options)
|
37
|
+
@options = options
|
38
|
+
end
|
39
|
+
end
|
data/lib/silk/http.rb
ADDED
data/lib/silk/options.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
class Options
|
4
|
+
def self.parse
|
5
|
+
options = {
|
6
|
+
:multiple => false
|
7
|
+
}
|
8
|
+
|
9
|
+
optparse = OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: #{opts.program_name} [options]"
|
11
|
+
|
12
|
+
options[:verbose] = false
|
13
|
+
opts.on('-V', '--verbose', 'Be more verbose') do
|
14
|
+
options[:verbose] = true
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on('-h', '--help', "You're looking at it") do
|
18
|
+
puts opts
|
19
|
+
exit(-1)
|
20
|
+
end
|
21
|
+
|
22
|
+
options[:ontop] = false
|
23
|
+
opts.on('-f', '--foreground', "Run in the foreground") do
|
24
|
+
options[:ontop] = true
|
25
|
+
end
|
26
|
+
|
27
|
+
options[:filter_paths] = [ File.join('', 'etc', 'silk') ]
|
28
|
+
options[:filter_paths] << File.join(ENV['HOME'], '.silk') if ENV['HOME']
|
29
|
+
|
30
|
+
opts.on('-r [recipe]', '--recipes [recipe]', /.+/, 'Reads in additional recipes') do |recipes|
|
31
|
+
options[:filter_paths] << recipes
|
32
|
+
end
|
33
|
+
|
34
|
+
options[:port] = 8888
|
35
|
+
opts.on('-p [port]', '--port', /\d+/, 'Port to run the server on (Default: 8888)') do |port|
|
36
|
+
options[:port] = port.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
options[:lock] = false
|
40
|
+
opts.on('-x', '--lock', 'Set a mutex lock') do
|
41
|
+
options[:lock] = true
|
42
|
+
end
|
43
|
+
|
44
|
+
options[:bind] = '0.0.0.0'
|
45
|
+
opts.on('-b', '--bind', /.+/, 'Set the IP address to listen to') do |host|
|
46
|
+
options[:bind] = host
|
47
|
+
end
|
48
|
+
|
49
|
+
options[:server] = %w[thin mongrel webrick]
|
50
|
+
opts.on('-s', '--server', /.+/, 'handler used for built-in web server') do |server|
|
51
|
+
options[:server] = server
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on('-v', '--version') do
|
55
|
+
File.open(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')) do |fh|
|
56
|
+
puts fh.read
|
57
|
+
end
|
58
|
+
exit(0)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
begin
|
63
|
+
optparse.parse!
|
64
|
+
options
|
65
|
+
rescue OptionParser::InvalidOption => e
|
66
|
+
puts optparse
|
67
|
+
exit(-1)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/silk/server.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'sinatra/base'
|
3
|
+
|
4
|
+
module Silk
|
5
|
+
class Server < Sinatra::Base
|
6
|
+
get %r{\/(.+)} do |c|
|
7
|
+
content_type('application/json')
|
8
|
+
|
9
|
+
options = Silk.options
|
10
|
+
task = c.gsub("/", ":")
|
11
|
+
|
12
|
+
tasks = Silk::Tasks.new
|
13
|
+
unless tasks.list.include?(task)
|
14
|
+
not_found("Not Found".to_json)
|
15
|
+
end
|
16
|
+
|
17
|
+
results = { :stdout => '', :stderr => '' }
|
18
|
+
params.delete("captures")
|
19
|
+
|
20
|
+
stdout_read, stdout_write = IO.pipe
|
21
|
+
stderr_read, stderr_write = IO.pipe
|
22
|
+
pid = Process.fork do
|
23
|
+
$stdout.reopen stdout_write
|
24
|
+
$stderr.reopen stderr_write
|
25
|
+
stdout_read.close
|
26
|
+
stderr_read.close
|
27
|
+
tasks.run(task, params)
|
28
|
+
end
|
29
|
+
|
30
|
+
stdout_write.close
|
31
|
+
stderr_write.close
|
32
|
+
stdout_read.each do |line|
|
33
|
+
results[:stdout] += line
|
34
|
+
end
|
35
|
+
stderr_read.each do |line|
|
36
|
+
results[:stderr] += line
|
37
|
+
end
|
38
|
+
Process.waitpid(pid)
|
39
|
+
|
40
|
+
headers('X_PROCESS_EXIT_STATUS' => $?.exitstatus.to_s)
|
41
|
+
|
42
|
+
if $?.exitstatus != 0
|
43
|
+
error(500, results[:stderr])
|
44
|
+
else
|
45
|
+
results[:stdout]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/silk/tasks.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
module Silk
|
4
|
+
class Tasks
|
5
|
+
def initialize
|
6
|
+
Rake::Task.clear
|
7
|
+
@app = Rake::Application.new
|
8
|
+
@app.init
|
9
|
+
Silk.options[:filter_paths].each do |path|
|
10
|
+
FileList.new("#{path}/*.rake").each do |file|
|
11
|
+
@app.add_import(file)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@app.load_rakefile
|
15
|
+
end
|
16
|
+
|
17
|
+
def list
|
18
|
+
return Rake::Task.tasks.map { |task| task.name }
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(task, arguments)
|
22
|
+
Rake::Task[task].execute(arguments)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_silk.rb
ADDED
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: silk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Myles Eftos
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-18 00:00:00 +08:00
|
13
|
+
default_executable: silk
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: daemons
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: SyslogLogger
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: thoughtbot-shoulda
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: It allows you to write rake tasks to do common tasks, such as creating email addresses, adding users etc. Silk provides a HTTP wrapper the the rake tasks, and allows communication via JSON objects, which makes it dead easy for them to be called from a web app.
|
46
|
+
email: myles@madpilot.com.au
|
47
|
+
executables:
|
48
|
+
- silk
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README.rdoc
|
54
|
+
files:
|
55
|
+
- .document
|
56
|
+
- .gitignore
|
57
|
+
- LICENSE
|
58
|
+
- README.rdoc
|
59
|
+
- Rakefile
|
60
|
+
- VERSION
|
61
|
+
- bin/silk
|
62
|
+
- lib/silk.rb
|
63
|
+
- lib/silk/http.rb
|
64
|
+
- lib/silk/options.rb
|
65
|
+
- lib/silk/server.rb
|
66
|
+
- lib/silk/tasks.rb
|
67
|
+
- test/helper.rb
|
68
|
+
- test/test_silk.rb
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://github.com/madpilot/silk
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options:
|
75
|
+
- --charset=UTF-8
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: "0"
|
83
|
+
version:
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: "0"
|
89
|
+
version:
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.3.5
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: A framework for creating a hosting console
|
97
|
+
test_files:
|
98
|
+
- test/test_silk.rb
|
99
|
+
- test/helper.rb
|