off_the_grid 0.0.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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/lib/off_the_grid.rb +19 -0
- data/lib/off_the_grid/access_list.rb +50 -0
- data/lib/off_the_grid/admin_host.rb +20 -0
- data/lib/off_the_grid/erb_helpers.rb +7 -0
- data/lib/off_the_grid/execute_host.rb +48 -0
- data/lib/off_the_grid/grid_resource.rb +65 -0
- data/lib/off_the_grid/host.rb +18 -0
- data/lib/off_the_grid/host_group.rb +37 -0
- data/lib/off_the_grid/project.rb +51 -0
- data/lib/off_the_grid/submit_host.rb +20 -0
- data/lib/off_the_grid/templates/execute_host.rb +17 -0
- data/lib/off_the_grid/templates/project.rb +13 -0
- data/lib/off_the_grid/templates/user.rb +13 -0
- data/lib/off_the_grid/user.rb +77 -0
- data/lib/off_the_grid/version.rb +5 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 07155e2121e33460113166ae7876130af5698fff
|
4
|
+
data.tar.gz: ef80d7252bedc9328729276b1a2e0c8cd78b760a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cfd6d1f0c1b1ef367c6b1fdcee8aa5a09ff6cdeaee40245ed719138ec91edd62f9c7bdaafee36a7c5b909cae9974bc12b8d09200e378ccb3e519f79e6cb5da4d
|
7
|
+
data.tar.gz: a9e08a7cc9ace51e28536cd0b272edbe481b7c5bf1df299ab3f77437716e6df9b7a04ea2115118f82c06124df09d84c1d84b1c6ca6c5654cebcd132aa891e5fe
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 KnuEdge Corporation
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/off_the_grid.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Standard Library
|
2
|
+
require 'erb'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
# Internal Requirements
|
6
|
+
require 'off_the_grid/version'
|
7
|
+
require 'off_the_grid/erb_helpers'
|
8
|
+
require 'off_the_grid/templates/execute_host'
|
9
|
+
require 'off_the_grid/templates/project'
|
10
|
+
require 'off_the_grid/templates/user'
|
11
|
+
require 'off_the_grid/grid_resource'
|
12
|
+
require 'off_the_grid/host'
|
13
|
+
require 'off_the_grid/host_group'
|
14
|
+
require 'off_the_grid/access_list'
|
15
|
+
require 'off_the_grid/admin_host'
|
16
|
+
require 'off_the_grid/execute_host'
|
17
|
+
require 'off_the_grid/submit_host'
|
18
|
+
require 'off_the_grid/project'
|
19
|
+
require 'off_the_grid/user'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class AccessList
|
3
|
+
attr_reader :name
|
4
|
+
include GridResource
|
5
|
+
|
6
|
+
# Get the list of SGE access lists
|
7
|
+
def self.list
|
8
|
+
`qconf -sul`.chomp.split("\n").sort.collect {|name| self.new(name) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def details
|
12
|
+
`qconf -su #{name}`.chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
def users
|
16
|
+
if new?
|
17
|
+
@unsaved_users ||= []
|
18
|
+
else
|
19
|
+
# Only returns users
|
20
|
+
extract_detail(:entries).select {|e| !e.match /^@/ }.collect {|user| User.new(user) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_user(user)
|
25
|
+
if new?
|
26
|
+
@unsaved_users ||= []
|
27
|
+
@unsaved_users << user
|
28
|
+
else
|
29
|
+
users.include?(user) ? true : system("qconf -au #{user.name} #{name}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_user(user)
|
34
|
+
users.include?(user) ? system("qconf -du #{user.name} #{name}") : true
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Add an SGE access list
|
40
|
+
def add
|
41
|
+
fail "Creating ACL Requires One or More Users" if users.empty?
|
42
|
+
system("qconf -au #{users.map(&:name).join(',')} #{name}")
|
43
|
+
end
|
44
|
+
|
45
|
+
# Remove an SGE access list
|
46
|
+
def remove
|
47
|
+
system("qconf -dul #{name}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class AdminHost < Host
|
3
|
+
# Get the list of SGE adminstrative hosts
|
4
|
+
def self.list
|
5
|
+
`qconf -sh`.chomp.split("\n").sort.collect {|name| self.new(name) }
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Add an SGE administrative host
|
11
|
+
def add
|
12
|
+
system("qconf -ah #{hostname}")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Remove an SGE administrative host
|
16
|
+
def remove
|
17
|
+
system("qconf -dh #{hostname}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class ExecuteHost < Host
|
3
|
+
# Get the list of SGE execute hosts
|
4
|
+
def self.list
|
5
|
+
`qconf -sel`.chomp.split("\n").sort.collect {|name| self.new(name) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def details
|
9
|
+
`qconf -se #{name}`.chomp
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_scaling
|
13
|
+
extract_detail(:load_scaling).last
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_values
|
17
|
+
extract_detail(:load_values)
|
18
|
+
end
|
19
|
+
|
20
|
+
def processors
|
21
|
+
value = extract_detail(:processors).last
|
22
|
+
value.match(/[0-9]+/) ? Integer(value) : value
|
23
|
+
end
|
24
|
+
|
25
|
+
# very slow method for now
|
26
|
+
def host_groups
|
27
|
+
HostGroup.list.select {|group| group.hosts.include?(self) }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Add an SGE execution host
|
33
|
+
def add
|
34
|
+
# TODO construct a template
|
35
|
+
Tempfile.open do |tmpfile|
|
36
|
+
tmpfile.puts render(Templates::ExecuteHost::ERB)
|
37
|
+
tmpfile.flush
|
38
|
+
system("qconf -Ae #{tmpfile.path}")
|
39
|
+
sleep 5
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Remove an SGE execution host
|
44
|
+
def remove
|
45
|
+
system("qconf -de #{hostname}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
module GridResource
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
def initalize(name)
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.list
|
10
|
+
[]
|
11
|
+
end
|
12
|
+
|
13
|
+
def new?
|
14
|
+
!self.class.list.map(&:name).include?(name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def save(safe = true)
|
18
|
+
if safe
|
19
|
+
raise "Validation Failed" unless validate_before_save
|
20
|
+
add
|
21
|
+
else
|
22
|
+
add # don't bother checking if the resource exists
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(safe = true)
|
27
|
+
if safe
|
28
|
+
raise "Validation Failed" unless validate_before_delete
|
29
|
+
remove
|
30
|
+
else
|
31
|
+
remove # don't bother checking if the resource exists
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def extract_detail(detail, options = {})
|
36
|
+
options[:split_on] ||= /,|\s/
|
37
|
+
return [] unless respond_to?(:details)
|
38
|
+
|
39
|
+
values = []
|
40
|
+
details.split("\n").each do |line|
|
41
|
+
if values.size > 0
|
42
|
+
# Add follow-up lines from the weird word-wrapped output
|
43
|
+
line.match(/^( ){8}/) ? values << line : break
|
44
|
+
end
|
45
|
+
values << line if line.match /^#{detail.to_s} /
|
46
|
+
end
|
47
|
+
values.join
|
48
|
+
.gsub(/(#{detail.to_s} |\\|\s{2,})/, '')
|
49
|
+
.split(options[:split_on])
|
50
|
+
.uniq - ['']
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_before_save
|
54
|
+
new?
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate_before_delete
|
58
|
+
!new?
|
59
|
+
end
|
60
|
+
|
61
|
+
def <=>(other)
|
62
|
+
name <=> other.name
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class HostGroup
|
3
|
+
attr_reader :name
|
4
|
+
include GridResource
|
5
|
+
|
6
|
+
# Get the list of SGE host groups
|
7
|
+
def self.list
|
8
|
+
`qconf -shgrpl`.chomp.split("\n").sort.collect {|name| self.new(name)}
|
9
|
+
end
|
10
|
+
|
11
|
+
def details
|
12
|
+
`qconf -shgrp #{name}`.chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_tree
|
16
|
+
`qconf -shgrp_tree #{name}`.chomp
|
17
|
+
end
|
18
|
+
|
19
|
+
def hosts
|
20
|
+
extract_detail(:hostlist).map {|host| ExecuteHost.new(host) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# TODO Adding a Host to a HostGroup...
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Add an SGE host group
|
28
|
+
def add
|
29
|
+
system("qconf -ahgrp #{name}")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Remove an SGE host group
|
33
|
+
def remove
|
34
|
+
system("qconf -dhgrp #{name}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class Project
|
3
|
+
attr_reader :name
|
4
|
+
include GridResource
|
5
|
+
|
6
|
+
# Get the list of SGE projects
|
7
|
+
def self.list
|
8
|
+
`qconf -sprjl`.chomp.split("\n").sort.collect {|name| self.new(name) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def details
|
12
|
+
`qconf -sprj #{name}`.chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
def acls
|
16
|
+
extract_detail(:acl).each do |acl|
|
17
|
+
AccessList.new(acl)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def xacls
|
22
|
+
extract_detail(:xacl).each do |acl|
|
23
|
+
AccessList.new(acl)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# A Read-only list of users that can use this project
|
28
|
+
# Uses ACL association
|
29
|
+
def users
|
30
|
+
acls.map(&:users).flatten.uniq
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Add an SGE project
|
36
|
+
def add
|
37
|
+
# TODO construct a template
|
38
|
+
Tempfile.open do |tmpfile|
|
39
|
+
tmpfile.puts render(Templates::Project::ERB)
|
40
|
+
tmpfile.flush
|
41
|
+
system("qconf -Aprj #{tmpfile.path}")
|
42
|
+
sleep 5
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Remove an SGE project
|
47
|
+
def remove
|
48
|
+
system("qconf -dprj #{name}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class SubmitHost < Host
|
3
|
+
# Get the list of SGE submit hosts
|
4
|
+
def self.list
|
5
|
+
`qconf -ss`.chomp.split("\n").sort.collect {|name| self.new(name)}
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Add an SGE submit host
|
11
|
+
def add
|
12
|
+
system("qconf -as #{hostname}")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Remove an SGE submit host
|
16
|
+
def remove
|
17
|
+
system("qconf -ds #{hostname}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
module Templates
|
3
|
+
module ExecuteHost
|
4
|
+
ERB = <<EOF
|
5
|
+
hostname <%= @hostname %>
|
6
|
+
load_scaling NONE
|
7
|
+
complex_values NONE
|
8
|
+
user_lists NONE
|
9
|
+
xuser_lists NONE
|
10
|
+
projects NONE
|
11
|
+
xprojects NONE
|
12
|
+
usage_scaling NONE
|
13
|
+
report_variables NONE
|
14
|
+
EOF
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module OffTheGrid
|
2
|
+
class User
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
include GridResource
|
6
|
+
|
7
|
+
# Get the list of all SGE users
|
8
|
+
def self.list
|
9
|
+
`qconf -suserl`.chomp.split("\n").sort.collect {|name| self.new(name)}
|
10
|
+
end
|
11
|
+
|
12
|
+
# Get the list of admin users
|
13
|
+
def self.admins
|
14
|
+
`qconf -sm`.chomp.split("\n").sort.collect {|name| self.new(name)}
|
15
|
+
end
|
16
|
+
|
17
|
+
# An alias for admins
|
18
|
+
def self.managers
|
19
|
+
admins
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the list of operator users
|
23
|
+
def self.operators
|
24
|
+
`qconf -so`.chomp.split("\n").sort.collect {|name| self.new(name)}
|
25
|
+
end
|
26
|
+
|
27
|
+
def details
|
28
|
+
`qconf -suser #{name}`.chomp
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_project=(project)
|
32
|
+
@default_project = project
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_project
|
36
|
+
@default_project
|
37
|
+
end
|
38
|
+
|
39
|
+
def admin?
|
40
|
+
admins.include?(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :manager?, :admin?
|
44
|
+
|
45
|
+
def operator?
|
46
|
+
# TODO learn more about the difference between "operator" and "manager"
|
47
|
+
# Maybe admins are always operators?
|
48
|
+
operators.include?(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Add an SGE user
|
54
|
+
def add
|
55
|
+
Tempfile.open do |tmpfile|
|
56
|
+
tmpfile.puts render(Templates::User::ERB)
|
57
|
+
tmpfile.flush
|
58
|
+
system("qconf -Auser #{tmpfile.path}")
|
59
|
+
sleep 5
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Remove an SGE user
|
64
|
+
def remove
|
65
|
+
system("qconf -duser #{name}")
|
66
|
+
end
|
67
|
+
|
68
|
+
# Validations go here
|
69
|
+
def validate_before_save
|
70
|
+
if super
|
71
|
+
(@default_project && @default_project.is_a?(Project))
|
72
|
+
else
|
73
|
+
false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: off_the_grid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Gnagy
|
8
|
+
- Daniel Schaaff
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-10-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.1'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.1'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rubocop
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.35'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.35'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: yard
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.8'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.8'
|
56
|
+
description: The Ruby library for interacting with Son of Grid Engine
|
57
|
+
email: jgnagy@knuedge.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- LICENSE
|
63
|
+
- lib/off_the_grid.rb
|
64
|
+
- lib/off_the_grid/access_list.rb
|
65
|
+
- lib/off_the_grid/admin_host.rb
|
66
|
+
- lib/off_the_grid/erb_helpers.rb
|
67
|
+
- lib/off_the_grid/execute_host.rb
|
68
|
+
- lib/off_the_grid/grid_resource.rb
|
69
|
+
- lib/off_the_grid/host.rb
|
70
|
+
- lib/off_the_grid/host_group.rb
|
71
|
+
- lib/off_the_grid/project.rb
|
72
|
+
- lib/off_the_grid/submit_host.rb
|
73
|
+
- lib/off_the_grid/templates/execute_host.rb
|
74
|
+
- lib/off_the_grid/templates/project.rb
|
75
|
+
- lib/off_the_grid/templates/user.rb
|
76
|
+
- lib/off_the_grid/user.rb
|
77
|
+
- lib/off_the_grid/version.rb
|
78
|
+
homepage: https://github.com/knuedge/off_the_grid
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message: Thanks for installing Off The Grid!
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '2.2'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.5.1
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Off The Grid can perform basic management tasks for SGE.
|
102
|
+
test_files: []
|