jah 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jah/cli.rb ADDED
@@ -0,0 +1,124 @@
1
+ #
2
+ # Jah Gem CLI
3
+ #
4
+
5
+ #TODO: def init
6
+ require 'logger'
7
+
8
+ module Jah
9
+
10
+ HOME = ENV['HOME'] + "/.jah/"
11
+ unless File.exists? HOME
12
+ FileUtils.mkdir_p HOME
13
+ end
14
+
15
+ Log = Logger.new(HOME + "jah.log")
16
+ def Log.write(d); self.warn(d); end
17
+ $stderr = Log
18
+
19
+ Opt = {}
20
+
21
+ def self.hostname
22
+ `hostname`.chomp.gsub(/\W/, "") rescue "jah#{rand(42000)}"
23
+ end
24
+
25
+ def self.locale
26
+ `locale | grep LANG`.scan(/LANG=(.*)\./)[0][0].downcase rescue "en_us"
27
+ end
28
+
29
+ def self.method_missing(w)
30
+ Opt[w.to_s.gsub("?", "").to_sym]
31
+ end
32
+
33
+ class Cli
34
+
35
+ def self.parse_options(argv)
36
+ options = {}
37
+
38
+ ARGV.options do |opts|
39
+ opts.banner = <<BANNER
40
+ Jah Gem Usage:
41
+
42
+ jah [command] [opts] -c [config file]
43
+
44
+ Commands:
45
+
46
+ start
47
+ stop
48
+ restart
49
+ install
50
+
51
+ BANNER
52
+ opts.separator "Config file:"
53
+ opts.on("-c", "--config CONFIG", String, "Jah Config file path" ) { |file| options[:config] = file }
54
+ opts.separator ""
55
+ opts.separator "Operation mode:"
56
+ opts.on("-m", "--mode MODE", String, "Jah operation mode") { |val| options[:mode] = val.to_sym }
57
+ opts.separator ""
58
+ opts.separator " xmpp - Use xmpp client, requires JID and Password"
59
+ opts.separator " post - Use post client, requires Jah Web Key"
60
+ opts.separator " dump - Just dump to disk, Jah Web can login and read"
61
+ opts.separator ""
62
+ opts.separator "Server Options:"
63
+ opts.on("-j", "--jid JID", String, "Client JID (user@domain)") { |val| options[:jid] = val }
64
+ opts.on("-k", "--key KEY", String, "Client XMPP Password or Jah Web Key") { |val| options[:key] = val }
65
+ opts.on("-s", "--server SERVER", String, "Jah Server URL" ) { |url| options[:server] = url }
66
+ opts.on("-p", "--port PORT", Integer, "Jah Server Port") { |val| options[:port] = val.to_i }
67
+ opts.separator ""
68
+
69
+ opts.on("-t", "--talk TALK", String, "Which locale to use" ) { |i18n| options[:i18n] = i18n }
70
+ opts.on("-f", "--file FILE", String, "Local temp file to track history" ) { |file| options[:history] = file }
71
+ opts.on("-i", "--interval INTERVAL", Integer, "Poller interval") { |val| options[:interval] = val.to_i }
72
+ opts.on("-l", "--level LEVEL", Logger::SEV_LABEL.map { |l| l.downcase }, "The level of logging to report" ) { |level| options[:level] = level }
73
+ opts.on("-g", "--[no-]god", "Don't use god") { |val| options[:god] = false }
74
+ opts.on("-d", "--daemonize", "Run in background" ) { |d| options[:daemon] = d }
75
+ opts.on("-r", "--report REPORT", "Report status to others on roster" ) { |r| options[:report] = r }
76
+
77
+ opts.separator ""
78
+ opts.separator "Common Options:"
79
+ opts.on("-h", "--help", "Show this message" ) { puts opts; exit }
80
+ opts.on("-v", "--[no-]verbose", "Turn on logging to STDOUT" ) { |bool| options[:verbose] = bool }
81
+ opts.on("-V", "--version", "Show version") { |version| puts Jah::VERSION; exit }
82
+ opts.separator ""
83
+ begin
84
+ opts.parse!
85
+ @usage = opts.to_s
86
+ rescue
87
+ puts opts
88
+ exit
89
+ end
90
+ end
91
+ options
92
+ end
93
+ private_class_method :parse_options
94
+
95
+ def self.dispatch(argv)
96
+ Jah::Opt.merge! autoload_config(parse_options(argv))
97
+ if comm = argv.shift
98
+ Jah::Agent.send(comm) rescue puts "Command not found: #{comm}"
99
+ else
100
+ Jah.mode ? Jah::Agent.start : Install.new
101
+ end
102
+ end
103
+
104
+ # Load config [., ~/.jah, /etc]
105
+ def self.autoload_config(options)
106
+ conf = "jah.yaml"
107
+ file = options[:config] || [nil, HOME, "/etc/"].select { |c| File.exists? "#{c}#{conf}" }[0]
108
+ options = YAML.load(File.read(file + conf)).merge!(options) if file
109
+
110
+ # Map acl and group arrays
111
+ [:acl, :groups].each do |g|
112
+ options[g] = options[g].split(",").map(&:strip)
113
+ end
114
+ options[:groups].map! { |g| "#{g}@conference.#{options[:host]}" }
115
+
116
+ # find a better place for this
117
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', 'locales', "*.{rb,yml}")]
118
+ I18n.default_locale = options[:i18n] || "en_us"
119
+ options
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,12 @@
1
+ module Jah
2
+
3
+ class Collector
4
+
5
+
6
+ def self.quick_results
7
+ "CPU #{Cpu.get.load}, MEM #{Mem.get.percent}%"
8
+ end
9
+
10
+
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ module Jah
2
+ class Cpu < Collector
3
+ attr_reader :load, :one, :five, :ten, :med
4
+ EXEC = "uptime"
5
+
6
+ def self.get
7
+ new
8
+ end
9
+
10
+ def initialize
11
+ l = cpu_load
12
+ @one = l[:one]
13
+ @five = l[:five]
14
+ @ten = l[:ten]
15
+ @load = l.values.join(", ")
16
+ @med = @ten / cores
17
+ end
18
+
19
+ def cpu_load
20
+ if `#{EXEC}` =~ /load average(s*): ([\d.]+)(,*) ([\d.]+)(,*) ([\d.]+)\Z/
21
+ { :one => $2.to_f,
22
+ :five => $4.to_f,
23
+ :ten => $6.to_f }
24
+ end
25
+ end
26
+
27
+ def cores
28
+ case RUBY_PLATFORM
29
+ when /linux/ then `cat /proc/cpuinfo | grep 'model name' | wc -l`.to_i
30
+ when /darwin/ then `hwprefs cpu_count`.to_i
31
+ else 1
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Jah
2
+
3
+ class Disk < Collector
4
+ EXEC = "df -h"
5
+
6
+ def self.all
7
+ @disks = `#{EXEC}`.to_a.reject { |dl| dl =~ /Size|none/ }.map do |l|
8
+ l = l.split(" ")
9
+ { :path => l[0], :total => l[1], :used => l[2], :avail => l[3], :percent => l[4]}
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,51 @@
1
+ module Jah
2
+
3
+ class Mem < Collector
4
+ attr_reader :total, :free, :used, :percent, :cached, :buffered,
5
+ :swap_total, :swap_free, :swap_used, :swap_percent
6
+
7
+ EXEC = "cat /proc/meminfo"
8
+
9
+ def self.get
10
+ new
11
+ end
12
+
13
+ def initialize
14
+ do_something
15
+ end
16
+
17
+ def do_something
18
+ mem_info = {}
19
+ `#{EXEC}`.each do |line|
20
+ _, key, value = *line.match(/^(\w+):\s+(\d+)\s/)
21
+ mem_info[key] = value.to_i
22
+ end
23
+
24
+ # memory info is empty - operating system may not support it (why doesn't an exception get raised earlier on mac osx?)
25
+ raise "No such file or directory" if mem_info.empty?
26
+
27
+ @total = mem_info['MemTotal'] / 1024
28
+ @free = (mem_info['MemFree'] + mem_info['Buffers'] + mem_info['Cached']) / 1024
29
+ @used = @total - @free
30
+ @percent = (@used / @total.to_f * 100).to_i
31
+
32
+ @swap_total = mem_info['SwapTotal'] / 1024
33
+ @swap_free = mem_info['SwapFree'] / 1024
34
+ @swap_used = swap_total - swap_free
35
+ unless @swap_total == 0
36
+ @swap_percent = (@swap_used / @swap_total.to_f * 100).to_i
37
+ end
38
+ rescue Exception => e
39
+ if e.message =~ /No such file or directory/
40
+ puts "/proc/meminfo not found.. trying top!"
41
+ top = `top -l 1`.to_a[5].split.map!{|m| m[0..-2].to_i}.reject(&:zero?)
42
+ @used, @free = top[3,4]
43
+ @total = @used + @free
44
+ @percent = (@used / @total.to_f * 100).to_i
45
+ else
46
+ raise e
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,27 @@
1
+ module Jah
2
+ class Net < Collector
3
+ # :net => "netstat -n | grep -i established | wc -l"
4
+ class << self
5
+ # attr_reader :count, :ips
6
+
7
+
8
+ def count
9
+ `netstat -n | grep -i established | wc -l`.to_i
10
+ end
11
+
12
+ def connections
13
+ `netstat -ntu | grep ESTAB | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr`.to_a.map do |l|
14
+ count, ip = l.split
15
+ [ip, count]
16
+ end
17
+ end
18
+ end
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+ end
27
+ end
@@ -0,0 +1,88 @@
1
+ module Jah
2
+
3
+ class Ps < Collector
4
+ COMM = "ps auxww"
5
+
6
+ def self.all
7
+ `#{COMM}`.to_a[1..-1].map do |l|
8
+ Prok.new(l.split)
9
+ end
10
+ end
11
+
12
+ def self.find(name)
13
+
14
+ end
15
+
16
+
17
+ end
18
+
19
+ class Prok
20
+ BANLIST = [/^ata/, /^init$/, /^scsi_/, /\/\d$/, /agetty/ ]
21
+ attr_reader :pid, :comm, :cpu, :mem, :rss, :vsz, :stat
22
+
23
+ def initialize(args) # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
24
+ return unless args[0]
25
+ @user = args[0]
26
+ @pid = args[1].chomp.to_i
27
+ @cpu = args[2].chomp.to_f
28
+ @mem = args[3].chomp.to_f
29
+ @vsz = args[4].chomp.to_i
30
+ @rss = args[5].chomp.to_i
31
+ @tty = args[6]
32
+ @stat = args[7]
33
+ @start = args[8]
34
+ @time = args[9]
35
+ @comm = args[10]
36
+ #@shr = args[6]
37
+ end
38
+
39
+ def hup!
40
+ exec "kill -1 #{pid}"
41
+ end
42
+
43
+ def kill!
44
+ exec "kill #{pid}"
45
+ end
46
+
47
+ def move_to_acre!
48
+ exec "kill -9 #{pid}"
49
+ end
50
+
51
+ def self.genocide!(ary, f = nil)
52
+ for prok in ary
53
+ prok.kill
54
+ end
55
+ end
56
+
57
+ def exec(comm)
58
+ # SSHWorker.new(@host, @host.user, comm)
59
+ end
60
+
61
+ def force(f)
62
+ { :hup => "-1", :die => "-9"}[f]
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ # COMM = {
69
+ # :top => "top -n 1",
70
+ # }
71
+
72
+
73
+
74
+ # def top
75
+ # info, tasks, cpus, mem, swap, n, n, *rest = *@res[:top]
76
+ # n, total, used, free, buffered = *mem.match(/(\d*)k\D*(\d*)k\D*(\d*)k\D*(\d*)k.*/)
77
+ # cached = swap.match(/(\d*)k cached/)[0]
78
+ # proks = rest.map do |r|
79
+ # r.split(" ")
80
+ # end
81
+
82
+ # # fail... top don't show a good stat....
83
+ # @proks = proks.reject do |p|
84
+ # p[0] == nil || Prok::BANLIST.select{ |pl| pl =~ p[11] }[0]
85
+ # end
86
+ # rescue => e
87
+ # nil
88
+ # end
@@ -0,0 +1,13 @@
1
+ module Jah
2
+ class Services < Collector
3
+
4
+
5
+
6
+
7
+
8
+ end
9
+
10
+
11
+
12
+
13
+ end
@@ -0,0 +1,20 @@
1
+ module Jah
2
+
3
+ class Who < Collector
4
+ EXEC = "who"
5
+
6
+ def self.all
7
+ @who = `#{EXEC}`.to_a.map do |l|
8
+ l = l.split(" ")
9
+
10
+ hash = {}
11
+
12
+ hash[:who] = l[0]
13
+ hash[:terminal] = l[1]
14
+ 2.times{ l.delete(l[0]) }
15
+ hash[:date] = l.join(" ")
16
+ hash
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module Jah
2
+ REG = []
3
+
4
+ module Command
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ def self.find(msg)
11
+ REG.select { |r| r[1] =~ msg.squeeze(" ").strip }.first
12
+ end
13
+
14
+ module ClassMethods
15
+
16
+ def register(handler, regex)
17
+ REG << [handler, /^#{regex}/, self]
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module Jah
2
+
3
+ class Admin
4
+ include Command
5
+
6
+ register(:get_roster, "roster$")
7
+ register(:drop_user, "drop\s")
8
+ #Jah::Command.register(:create_group, "")
9
+
10
+ class << self
11
+
12
+
13
+ def get_roster
14
+ out = ""
15
+ client.roster.grouped.each do |group, items|
16
+ out << "#{'*'*3} #{group || 'Ungrouped'} #{'*'*3}\n"
17
+ items.each { |item| out << "- #{item.name} (#{item.jid})\n" }
18
+ out << "\n"
19
+ end
20
+ out
21
+ end
22
+
23
+ def drop_user(user)
24
+ puts "DROP..."
25
+ end
26
+
27
+ def join_group()
28
+ end
29
+
30
+
31
+
32
+
33
+ def create_group(name)
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ module Jah
2
+ class Extra
3
+ include Command
4
+ register :change_lang, 'change\slang.*\s(\w*)$'
5
+
6
+ # change\slang.*\s(\w*)$
7
+ def self.change_lang(_, new)
8
+ I18n.default_locale = new
9
+
10
+ end
11
+
12
+
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ require "blather/client/dsl"
2
+
3
+ module Jah
4
+
5
+ class Pub
6
+ include Command
7
+
8
+ register :create, 'create\spubsub.*'
9
+
10
+
11
+ def self.create(_, node)
12
+ # pubsub = Blather::DSL::PubSub.new()
13
+ request(Blather::Stanza::PubSub::Create.new(:set,
14
+ "Jah.host.com", node)) { |n| yield n if block_given? }
15
+
16
+
17
+ end
18
+
19
+ def self.all
20
+
21
+
22
+ end
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+ end
34
+ end
@@ -0,0 +1,61 @@
1
+ module Jah
2
+
3
+ class Status
4
+ include Command
5
+ register(:ok, 'ok\??$')
6
+ register(:who, 'who\??$')
7
+ register(:mem, 'mem\??$')
8
+ register(:cpu, 'cpu\??$')
9
+ register(:net, 'net\??$')
10
+ register(:disk, 'disk\??$')
11
+ register(:proks, 'prok$|top$')
12
+
13
+
14
+ class << self
15
+
16
+ def ok
17
+ I18n.t("states." + case Jah::Cpu.get.med
18
+ when 0..0.5 then :green
19
+ when 0.51..0.7 then :yellow
20
+ else :red
21
+ end.to_s)
22
+ end
23
+
24
+ def mem
25
+ Mem.get.percent.to_s + "%"
26
+ end
27
+
28
+ def cpu
29
+ Cpu.get.load
30
+ end
31
+
32
+ def net
33
+ out = ""
34
+ Net.connections.each do |c|
35
+ out << "#{c[0]} => #{c[1]} connections\n"
36
+ end
37
+ out << "Total: #{Net.count}"
38
+ end
39
+
40
+ def disk
41
+ Disk.all.map do |d|
42
+ "\n*#{d[:path]}* => #{d[:percent]}"
43
+ end.join("\n")
44
+ end
45
+
46
+ def who
47
+ Who.all.map do |w|
48
+ "#{w[:who]} Logado via #{w[:terminal]} desde a data: #{w[:date]}"
49
+ end.join("\n")
50
+ end
51
+
52
+ def proks(find = nil)
53
+ Ps.all.map do |p|
54
+ next if find && p.comm !~ /#{find}/i
55
+ "#{p.comm} => #{p.mem}\n"
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
data/lib/jah/god.rb ADDED
@@ -0,0 +1,24 @@
1
+ # def setup
2
+ # DRb.start_service
3
+ # @server = DRbObject.new(nil, God::Socket.socket(@config['god_port'])) || nil
4
+ # rescue => e
5
+ # @config[:god] = false
6
+ # end
7
+
8
+ # # ping server to ensure that it is responsive
9
+ # def ping
10
+ # if god?
11
+ # tries = 3
12
+ # begin
13
+ # @server.ping
14
+ # rescue Exception => e
15
+ # retry if (tries -= 1) > 1
16
+ # raise e, "The server is not available (or you do not have permissions to access it)"
17
+ # end
18
+ # end
19
+ # end
20
+
21
+
22
+ # def god?
23
+ # @config[:god]
24
+ # end