leanci 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,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ crape-proto
19
+ vendor
20
+ leanci.log*
21
+ leanci.pid
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "serverengine", github: 'frsyuki/serverengine'
4
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Naoyuki Hirayama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Leanci
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'leanci'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install leanci
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/leanci ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'leanci'
5
+
6
+ config = {
7
+ script: 'default.leanci',
8
+ pid_path: 'leanci.pid',
9
+ log: 'leanci.log'
10
+ }
11
+ OptionParser.new do |opt|
12
+ opt.on('-f VALUE', 'specify leanci file') do |f|
13
+ config[:script] = f
14
+ end
15
+ opt.on('--pid VALUE', 'pid file') do |f|
16
+ config[:pid_path] = f
17
+ end
18
+ opt.parse!(ARGV)
19
+ end
20
+
21
+ run_daemon(config)
data/default.leanci ADDED
@@ -0,0 +1,18 @@
1
+ per_sec(10) do
2
+ bash do
3
+ code <<-EOC
4
+ cd crape-proto
5
+ hg incoming
6
+ EOC
7
+ success do
8
+ bash do
9
+ log "pull --update crape-proto"
10
+ echo true
11
+ code <<-EOC
12
+ cd crape-proto
13
+ hg pull --update
14
+ EOC
15
+ end
16
+ end
17
+ end
18
+ end
data/init.d/leanci ADDED
@@ -0,0 +1,160 @@
1
+ #! /bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: leanci
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: leanci
9
+ # Description: This file should be used to construct scripts to be
10
+ # placed in /etc/init.d.
11
+ ### END INIT INFO
12
+
13
+ # Author: Naoyuki Hirayama <naoyuki.hirayama@gmail.com>
14
+ #
15
+ # Please remove the "Author" lines above and replace them
16
+ # with your own name if you copy and modify this script.
17
+
18
+ # Do NOT "set -e"
19
+
20
+ # PATH should only include /usr/* if it runs after the mountnfs.sh script
21
+ PATH=/sbin:/usr/sbin:/bin:/usr/bin
22
+ DESC="Description of the service"
23
+ NAME=leanci
24
+ PIDFILE=/var/run/$NAME.pid
25
+ DIRECTORY=/home/hirayama/leanci
26
+ DAEMON=$DIRECTORY/$NAME
27
+ DAEMON_ARGS="--pid $PIDFILE"
28
+ SCRIPTNAME=/etc/init.d/$NAME
29
+
30
+ # Exit if the package is not installed
31
+ [ -x "$DAEMON" ] || exit 0
32
+
33
+ # Read configuration variable file if it is present
34
+ [ -r /etc/default/$NAME ] && . /etc/default/$NAME
35
+
36
+ # Load the VERBOSE setting and other rcS variables
37
+ . /lib/init/vars.sh
38
+
39
+ # Define LSB log_* functions.
40
+ # Depend on lsb-base (>= 3.2-14) to ensure that this file is present
41
+ # and status_of_proc is working.
42
+ . /lib/lsb/init-functions
43
+
44
+ #
45
+ # Function that starts the daemon/service
46
+ #
47
+ do_start()
48
+ {
49
+ # Return
50
+ # 0 if daemon has been started
51
+ # 1 if daemon was already running
52
+ # 2 if daemon could not be started
53
+ start-stop-daemon --start --pidfile $PIDFILE --chdir $DIRECTORY --exec $DAEMON --test > /dev/null \
54
+ || return 1
55
+ start-stop-daemon --start --pidfile $PIDFILE --chdir $DIRECTORY --exec $DAEMON -- \
56
+ $DAEMON_ARGS \
57
+ || return 2
58
+ # Add code here, if necessary, that waits for the process to be ready
59
+ # to handle requests from services started subsequently which depend
60
+ # on this one. As a last resort, sleep for some time.
61
+ }
62
+
63
+ #
64
+ # Function that stops the daemon/service
65
+ #
66
+ do_stop()
67
+ {
68
+ # Return
69
+ # 0 if daemon has been stopped
70
+ # 1 if daemon was already stopped
71
+ # 2 if daemon could not be stopped
72
+ # other if a failure occurred
73
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
74
+ RETVAL="$?"
75
+ [ "$RETVAL" = 2 ] && return 2
76
+ # Wait for children to finish too if this is a daemon that forks
77
+ # and if the daemon is only ever run from this initscript.
78
+ # If the above conditions are not satisfied then add some other code
79
+ # that waits for the process to drop all resources that could be
80
+ # needed by services started subsequently. A last resort is to
81
+ # sleep for some time.
82
+ start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
83
+ [ "$?" = 2 ] && return 2
84
+ # Many daemons don't delete their pidfiles when they exit.
85
+ rm -f $PIDFILE
86
+ return "$RETVAL"
87
+ }
88
+
89
+ #
90
+ # Function that sends a SIGHUP to the daemon/service
91
+ #
92
+ do_reload() {
93
+ #
94
+ # If the daemon can reload its configuration without
95
+ # restarting (for example, when it is sent a SIGHUP),
96
+ # then implement that here.
97
+ #
98
+ start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
99
+ return 0
100
+ }
101
+
102
+ case "$1" in
103
+ start)
104
+ [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
105
+ do_start
106
+ case "$?" in
107
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
108
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
109
+ esac
110
+ ;;
111
+ stop)
112
+ [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
113
+ do_stop
114
+ case "$?" in
115
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
116
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
117
+ esac
118
+ ;;
119
+ status)
120
+ status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
121
+ ;;
122
+ #reload|force-reload)
123
+ #
124
+ # If do_reload() is not implemented then leave this commented out
125
+ # and leave 'force-reload' as an alias for 'restart'.
126
+ #
127
+ #log_daemon_msg "Reloading $DESC" "$NAME"
128
+ #do_reload
129
+ #log_end_msg $?
130
+ #;;
131
+ restart|force-reload)
132
+ #
133
+ # If the "reload" option is implemented then remove the
134
+ # 'force-reload' alias
135
+ #
136
+ log_daemon_msg "Restarting $DESC" "$NAME"
137
+ do_stop
138
+ case "$?" in
139
+ 0|1)
140
+ do_start
141
+ case "$?" in
142
+ 0) log_end_msg 0 ;;
143
+ 1) log_end_msg 1 ;; # Old process is still running
144
+ *) log_end_msg 1 ;; # Failed to start
145
+ esac
146
+ ;;
147
+ *)
148
+ # Failed to stop
149
+ log_end_msg 1
150
+ ;;
151
+ esac
152
+ ;;
153
+ *)
154
+ #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
155
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
156
+ exit 3
157
+ ;;
158
+ esac
159
+
160
+ :
data/leanci.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'leanci/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "leanci"
8
+ spec.version = Leanci::VERSION
9
+ spec.authors = ["Naoyuki Hirayama"]
10
+ spec.email = ["naoyuki.hirayama@gmail.com"]
11
+ spec.description = %q{minimal CI servant}
12
+ spec.summary = %q{minimal CI servant work with chef-like DSL}
13
+ spec.homepage = "https://github.com/jonigata/leanci"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/lib/daemon.rb ADDED
@@ -0,0 +1,38 @@
1
+ require_relative 'script'
2
+
3
+ module MyWorker
4
+ def run
5
+ reload
6
+ until @stop
7
+ if @script_source
8
+ Script.new(logger, @script_source)
9
+ else
10
+ sleep 1
11
+ end
12
+ end
13
+ end
14
+
15
+ def reload
16
+ begin
17
+ @script_source = nil
18
+ File.open(config[:script]) do |f|
19
+ @script_source = f.read
20
+ end
21
+ rescue
22
+ logger.fatal "can't open script file"
23
+ end
24
+ end
25
+
26
+ def stop
27
+ @stop = true
28
+ end
29
+ end
30
+
31
+ def run_daemon(config)
32
+ se = ServerEngine.create(nil, MyWorker, {
33
+ daemonize: true,
34
+ supervisor: true,
35
+ worker_type: 'process',
36
+ }.merge!(config))
37
+ se.run
38
+ end
@@ -0,0 +1,3 @@
1
+ module Leanci
2
+ VERSION = "0.0.1"
3
+ end
data/lib/leanci.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'serverengine'
5
+ require 'optparse'
6
+ require 'logger'
7
+
8
+ require_relative 'daemon'
data/lib/script.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'open3'
2
+
3
+ class Bash
4
+ def initialize(logger, &block)
5
+ @logger = logger
6
+ instance_eval(&block)
7
+
8
+ if @code
9
+ if @user
10
+ if @user == 'root'
11
+ exec_code("sudo /bin/bash")
12
+ else
13
+ group = @group || @user
14
+ exec_code("sudo -u #{@user} -g #{group} /bin/bash", stdin_data: @code)
15
+ end
16
+ else
17
+ exec_code("/bin/bash")
18
+ end
19
+ if status == 0
20
+ InnerScript.new(@logger, &@success) if @success
21
+ else
22
+ InnerScript.new(@logger, &@failure) if @failure
23
+ end
24
+ end
25
+ end
26
+
27
+ def exec_code(cmd)
28
+ @logger.info @logtext if @logtext
29
+ @logger.info @code.chomp if @echo
30
+ o, e, s = Open3.capture3(cmd, stdin_data: @code)
31
+ @logger.info o.chomp if @echo
32
+ @status = s
33
+ end
34
+
35
+ attr_reader :status
36
+
37
+ def user(s)
38
+ @user = s
39
+ end
40
+
41
+ def group(s)
42
+ @group = s
43
+ end
44
+
45
+ def code(s)
46
+ @code = s
47
+ end
48
+
49
+ def success(&block)
50
+ @success = block
51
+ end
52
+
53
+ def failure(&block)
54
+ @failure = block
55
+ end
56
+
57
+ def log(logtext)
58
+ @logtext = logtext
59
+ end
60
+
61
+ def echo(flag)
62
+ @echo = flag
63
+ end
64
+ end
65
+
66
+ class InnerScript
67
+ def initialize(logger, &block)
68
+ @logger = logger
69
+ instance_eval(&block)
70
+ end
71
+
72
+ def bash(&block)
73
+ Bash.new(@logger, &block).status
74
+ end
75
+ end
76
+
77
+
78
+ class Script
79
+ def initialize(logger, script_source)
80
+ @logger = logger
81
+ instance_eval(script_source)
82
+ end
83
+
84
+ def per_sec(sec = 1, &block)
85
+ sleep sec
86
+ instance_eval(&block)
87
+ end
88
+
89
+ def bash(&block)
90
+ Bash.new(@logger, &block).status
91
+ end
92
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leanci
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Naoyuki Hirayama
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: minimal CI servant
47
+ email:
48
+ - naoyuki.hirayama@gmail.com
49
+ executables:
50
+ - leanci
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bin/leanci
60
+ - default.leanci
61
+ - init.d/leanci
62
+ - leanci.gemspec
63
+ - lib/daemon.rb
64
+ - lib/leanci.rb
65
+ - lib/leanci/version.rb
66
+ - lib/script.rb
67
+ homepage: https://github.com/jonigata/leanci
68
+ licenses:
69
+ - MIT
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.23
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: minimal CI servant work with chef-like DSL
92
+ test_files: []