spacewalk 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/Gemfile +4 -0
- data/LICENSE +58 -0
- data/README.rdoc +35 -0
- data/Rakefile +6 -0
- data/bin/actions.rb +6 -0
- data/doc/protocol.doc +203 -0
- data/lib/spacewalk.rb +6 -0
- data/lib/spacewalk/capabilities.rb +18 -0
- data/lib/spacewalk/config.rb +26 -0
- data/lib/spacewalk/server.rb +155 -0
- data/lib/spacewalk/status_report.rb +20 -0
- data/lib/spacewalk/system_id.rb +26 -0
- data/lib/spacewalk/version.rb +3 -0
- data/lib/spacewalk/xmlrpc.rb +58 -0
- data/spacewalk.gemspec +28 -0
- data/tasks/clean.rake +8 -0
- data/tasks/doc.rake +14 -0
- data/tasks/test.rake +6 -0
- metadata +117 -0
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
(see COPYING.txt file), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict
|
21
|
+
with standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
45
|
+
files under the ./missing directory. See each file for the copying
|
46
|
+
condition.
|
47
|
+
|
48
|
+
5. The scripts and library files supplied as input to or produced as
|
49
|
+
output from the software do not automatically fall under the
|
50
|
+
copyright of the software, but belong to whomever generated them,
|
51
|
+
and may be sold commercially, and may be aggregated with this
|
52
|
+
software.
|
53
|
+
|
54
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
55
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
56
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
57
|
+
PURPOSE.
|
58
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
= About Spacewalk
|
2
|
+
|
3
|
+
* http://github.com/kkaempf/ruby-spacewalk
|
4
|
+
* http://spacewalk.redhat.com/
|
5
|
+
* http://www.suse.com/products/suse-manager
|
6
|
+
|
7
|
+
== DESCRIPTION:
|
8
|
+
|
9
|
+
Spacewalk is a pure-Ruby implementation of the Spacewalk client
|
10
|
+
protocol stack.
|
11
|
+
|
12
|
+
== SYNOPSIS:
|
13
|
+
|
14
|
+
require 'spacewalk'
|
15
|
+
|
16
|
+
# Assuming that /etc/sysconfig/rhn/ exists
|
17
|
+
server = Spacewalk::Server.new
|
18
|
+
# get pending action for system
|
19
|
+
action = server.actions
|
20
|
+
|
21
|
+
== REQUIREMENTS:
|
22
|
+
|
23
|
+
* - none -
|
24
|
+
|
25
|
+
== INSTALL:
|
26
|
+
|
27
|
+
* sudo gem install spacewalk
|
28
|
+
|
29
|
+
== LICENSE:
|
30
|
+
|
31
|
+
(The Ruby License)
|
32
|
+
|
33
|
+
Copyright (c) 2011 SUSE Linux Products GmbH
|
34
|
+
|
35
|
+
See http://www.ruby-lang.org/en/LICENSE.txt for the full text
|
data/Rakefile
ADDED
data/bin/actions.rb
ADDED
data/doc/protocol.doc
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
Client protocol
|
2
|
+
|
3
|
+
From looking at spacewalk/client/rhel/rhn-client-tools/src/up2date_client/up2dateAuth.py
|
4
|
+
|
5
|
+
- client configuration
|
6
|
+
- /etc/sysconfig/rhn/up2date
|
7
|
+
- text
|
8
|
+
- augmented <key>[<comment>] = <value>
|
9
|
+
'cfg'
|
10
|
+
|
11
|
+
- where is my server ?
|
12
|
+
- ./rhn-client-tools/src/up2date_client/rpcServer.py
|
13
|
+
- access through proxy
|
14
|
+
if cfg["enableProxy"]:
|
15
|
+
proxyHost = config.getProxySetting()
|
16
|
+
|
17
|
+
if cfg["enableProxyAuth"]:
|
18
|
+
proxyUser = cfg["proxyUser"] or None
|
19
|
+
proxyPassword = cfg["proxyPassword"] or None
|
20
|
+
|
21
|
+
- support for multiple servers
|
22
|
+
serverUrls = config.getServerlURL()
|
23
|
+
./rhn-client-tools/src/up2date_client/config.py
|
24
|
+
-> cfg["serverURL"] = https://manager.suse.de/XMLRPC
|
25
|
+
handler = /RPC2
|
26
|
+
-> could be multiple
|
27
|
+
serverList = ServerList(serverUrls)
|
28
|
+
|
29
|
+
- secure communication with server
|
30
|
+
ca = cfg["sslCACert"]
|
31
|
+
if isinstance(ca, basestring):
|
32
|
+
ca = [ca]
|
33
|
+
|
34
|
+
rhns_ca_certs = ca or ["/usr/share/rhn/RHNS-CA-CERT"]
|
35
|
+
|
36
|
+
- build up http(s) header
|
37
|
+
s.add_header("X-Up2date-Version", up2dateUtils.version())
|
38
|
+
|
39
|
+
- send up the (client) capabality info
|
40
|
+
headerlist = clientCaps.caps.headerFormat()
|
41
|
+
for (headerName, value) in headerlist:
|
42
|
+
s.add_header(headerName, value)
|
43
|
+
|
44
|
+
- client needs to authenticate
|
45
|
+
- cfg["systemIdPath] -> systemIdPath=/etc/sysconfig/rhn/systemid
|
46
|
+
- /etc/sysconfig/rhn/systemid
|
47
|
+
- xml formatted
|
48
|
+
|
49
|
+
- does a version check of rpmdb with systemid
|
50
|
+
- spacewalk/client/rhel/rhn-client-tools/src/up2date_client/up2dateUtils.py
|
51
|
+
- spacewalk/client/rhel/rhn-client-tools/src/up2date_client/transaction.py
|
52
|
+
- checks provider of redhat-release or distribution-release
|
53
|
+
- if the system was updated, client will get a new id
|
54
|
+
- can be overridden via cfg["versionOverride"]
|
55
|
+
|
56
|
+
- populates http header
|
57
|
+
from /etc/sysconfig/rhn/clientCaps.d
|
58
|
+
with "X-RHN-Client-Capability: <name>(<version>)=<value>"
|
59
|
+
|
60
|
+
- report = { "uname" => [<uname>], "uptime" => <uptime>]
|
61
|
+
os.uname(): ('Linux', 'kkaempf', '3.0.4-43-desktop', '#1 SMP PREEMPT Wed Aug 31 09:30:44 UTC 2011 (a432f18)', 'i686')
|
62
|
+
(uname -s, uname -n, uname -r, uname -v, uname -m)
|
63
|
+
uptime : /proc/uptime as [int, int]
|
64
|
+
|
65
|
+
= server side xmlrpc
|
66
|
+
spacewalk/backend/server/handlers/xmlrpc
|
67
|
+
call <file>.<method>
|
68
|
+
|
69
|
+
- call registration.welcome_message
|
70
|
+
=> sets 'checked in' in database
|
71
|
+
|
72
|
+
- call get.actions systemid, ACTION_VERSION, report until empty
|
73
|
+
Remove example:
|
74
|
+
{"action"=>["packages.remove", [[["alsa-devel", "1.0.24.1", "30.1", "", ""]]]], "id"=>1061, "version"=>2}
|
75
|
+
id == action id
|
76
|
+
-> https://manager.suse.de/rhn/schedule/ActionDetails.do?aid=1061
|
77
|
+
Install/Update example:
|
78
|
+
{"action"=>["packages.update", [[["aqbanking", "5.0.10", "5.12", "", ""], ["epdfview", "0.1.8", "5.1", "", ""]]]], "id"=>1063, "version"=>2}
|
79
|
+
Reboot action:
|
80
|
+
{"action"=>["reboot.reboot", []], "id"=>1066, "version"=>2}
|
81
|
+
Hardware refresh:
|
82
|
+
{"action"=>["hardware.refresh_list", []], "id"=>1067, "version"=>2}
|
83
|
+
|
84
|
+
=> only gets the next scheduled action, not all scheduled actions
|
85
|
+
|
86
|
+
queue.submit(up2dateAuth.getSystemId(), action_id, status, message,data)
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
- run local actions
|
91
|
+
LOCAL_ACTIONS = [("packages.checkNeedUpdate", ("rhnsd=1",))]
|
92
|
+
-> method = getMethod.getMethod(method, "/usr/share/rhn/","actions")
|
93
|
+
(status,message,data) = method(*params, **kwargs)
|
94
|
+
|
95
|
+
- packages.checkNeedUpdate
|
96
|
+
compate st_mtime of (cfg["dbpath"] || "/var/lib/rpm")/Packages with /var/lib/up2date/dbtimestamp
|
97
|
+
-> rhnPackageInfo.updatePackageProfile
|
98
|
+
rhel/rhn-client-tools/src/up2date_client/rhnPackageInfo.py
|
99
|
+
get package hash (pkgUtils.getInstalledPackageList(getArch=1)
|
100
|
+
rhel/rhn-client-tools/src/up2date_client/rpmUtils.py
|
101
|
+
"Return list of packages. Package is hash with keys name, epoch,
|
102
|
+
version, release and optionaly arch and cookie"
|
103
|
+
"name": <string-value>
|
104
|
+
"epoch": <string-value>
|
105
|
+
"version": <string-value>
|
106
|
+
"release": <string-value>
|
107
|
+
"installtime": <string-value>
|
108
|
+
"arch": <string-value>
|
109
|
+
"cookie"
|
110
|
+
unless server.has_capability xmlrpc.packages.extended_profile=2
|
111
|
+
convert hash to list
|
112
|
+
xmlrpc registration.update_packages(systemid, packages)
|
113
|
+
|
114
|
+
============
|
115
|
+
|
116
|
+
First call to Server: registration.welcome_message
|
117
|
+
returns
|
118
|
+
Header
|
119
|
+
- "x-transport-info"=>["Extended Capabilities Transport (C) Red Hat, Inc (version $Revision$)"],
|
120
|
+
- "x-rhn-server-capability"=>
|
121
|
+
["registration.finish_message(1)=1",
|
122
|
+
"applet.has_base_channel(1)=1",
|
123
|
+
"rhncfg.filetype.directory(1)=1",
|
124
|
+
"registration.register_osad(1)=1",
|
125
|
+
"registration.delta_packages(1)=1",
|
126
|
+
"xmlrpc.packages.extended_profile(1-2)=1",
|
127
|
+
"registration.remaining_subscriptions(1)=1",
|
128
|
+
"registration.update_contact_info(1)=1",
|
129
|
+
"staging_content(1)=1",
|
130
|
+
"registration.extended_update_support(1)=1",
|
131
|
+
"xmlrpc.packages.suse_products(1)=1",
|
132
|
+
"rhncfg.content.base64_decode(1)=1",
|
133
|
+
"registration.smbios(1)=1",
|
134
|
+
"xmlrpc.errata.patch_names(1)=1",
|
135
|
+
"xmlrpc.login.extra_data(1)=1"],
|
136
|
+
- "x-rhn-client-version"=>["0"],
|
137
|
+
- "content-transfer-encoding"=>["base64"],
|
138
|
+
- "connection"=>["close"],
|
139
|
+
- "content-type"=>["text/base64"],
|
140
|
+
- "x-rhn-proxy-version"=>["None"],
|
141
|
+
- "date"=>["Wed, 14 Dec 2011 10:54:55 GMT"],
|
142
|
+
- "server"=>["Apache"],
|
143
|
+
- "content-length"=>["163"],
|
144
|
+
- "content-encoding"=>["x-zlib"]
|
145
|
+
Body
|
146
|
+
eJyzsa/IzVEoSy0qzszPs1U31DNQt7fjsslNLcnITwlKLS7IzytOBQoUJBYl5hbDGEC6LDGnNNXO
|
147
|
+
prikKDMv3S4oNUXBI7FEwS+1pDy/KFshPDUnOT83VcE3tbg4MT3VRh+qzkYfoo/LRh9mkD7caH10
|
148
|
+
WwGMyDXu
|
149
|
+
-> zlib.deflate.decodebase64
|
150
|
+
<?xml version='1.0'?>
|
151
|
+
<methodResponse>
|
152
|
+
<params>
|
153
|
+
<param>
|
154
|
+
<value><string>Red Hat Network Welcome Message</string></value>
|
155
|
+
</param>
|
156
|
+
</params>
|
157
|
+
</methodResponse>
|
158
|
+
===========
|
159
|
+
|
160
|
+
rhnreg_ks
|
161
|
+
|
162
|
+
- needs user/pass or activation code
|
163
|
+
|
164
|
+
- registered? cfg["systemIdPath] exists
|
165
|
+
|
166
|
+
- server.capabilities.validate()
|
167
|
+
|
168
|
+
- packageList = pkgUtils.getInstalledPackageList(getArch=getArch)
|
169
|
+
hardwareList = hardware.Hardware()
|
170
|
+
profilename = self.options.profilename || RegisterKsCli.__generateProfileName(hardwareList)
|
171
|
+
other = {}
|
172
|
+
if self.options.systemorgid:
|
173
|
+
other['org_id'] = self.options.systemorgid
|
174
|
+
(virt_uuid, virt_type) = rhnreg.get_virt_info()
|
175
|
+
if not virt_uuid is None:
|
176
|
+
other['virt_uuid'] = virt_uuid
|
177
|
+
other['virt_type'] = virt_type
|
178
|
+
systemId = rhnreg.registerSystem(token = self.options.activationkey,
|
179
|
+
profileName = profilename,
|
180
|
+
other = other)
|
181
|
+
rhnreg.sendHardware(systemId, hardwareList)
|
182
|
+
rhnreg.sendPackages(systemId, packageList)
|
183
|
+
# write out the new id
|
184
|
+
if isinstance(systemId, unicode):
|
185
|
+
rhnreg.writeSystemId(unicode.encode(systemId, 'utf-8'))
|
186
|
+
else:
|
187
|
+
rhnreg.writeSystemId(systemId)
|
188
|
+
rhnreg.cfg.save()
|
189
|
+
rhnreg.sendVirtInfo(systemId)
|
190
|
+
rhnreg.startRhnsd()
|
191
|
+
|
192
|
+
- profileName
|
193
|
+
Convert Internationalized domain name from Pune encoding to Unicode
|
194
|
+
for hw in hardwareList:
|
195
|
+
if hw['class'] == 'NETINFO':
|
196
|
+
hostname = hw.get('hostname')
|
197
|
+
ipaddr = hw.get('ipaddr')
|
198
|
+
if hostname:
|
199
|
+
profileName = idn_pune_to_unicode(hostname)
|
200
|
+
else:
|
201
|
+
if ipaddr:
|
202
|
+
profileName = ipaddr
|
203
|
+
|
data/lib/spacewalk.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Spacewalk
|
2
|
+
class Capabilities
|
3
|
+
#
|
4
|
+
def initialize client
|
5
|
+
# hash of <capability> => <version>
|
6
|
+
@caps = {}
|
7
|
+
client.http_last_response["x-rhn-server-capability"].split(",").each do |caps|
|
8
|
+
caps.split(",").each do |cap|
|
9
|
+
# puts "#{cap}"
|
10
|
+
raise "Invalid cap '#{cap}'" unless cap =~ /(\s+)?(((\w+)|\.)+)\((\d(-\d)?)\)=(\d)/
|
11
|
+
# name = [ version, value ]
|
12
|
+
@caps[$2] = [$5, $7]
|
13
|
+
# puts "#{$2}(#{$5})=#{$7}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Spacewalk
|
2
|
+
class Config
|
3
|
+
def initialize path="/etc/sysconfig/rhn/up2date"
|
4
|
+
@path = path
|
5
|
+
@config = {}
|
6
|
+
File.open path do |f|
|
7
|
+
while l = f.gets
|
8
|
+
# split <name>=<value>, drop everything else
|
9
|
+
next unless l =~ /(\w+)=(.*)/
|
10
|
+
key = $1
|
11
|
+
val = $2
|
12
|
+
# fixme: handle array-type values
|
13
|
+
@config[key.downcase] = val.empty? ? nil : val
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def [] key
|
19
|
+
@config[key.downcase]
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing name
|
23
|
+
@config[name.to_s.downcase]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module XMLRPC
|
2
|
+
class Client
|
3
|
+
def get_parser
|
4
|
+
parser
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Spacewalk
|
10
|
+
class Server
|
11
|
+
# from /usr/sbin/rhn_check
|
12
|
+
# action version we understand
|
13
|
+
ACTION_VERSION = 2
|
14
|
+
|
15
|
+
require "xmlrpc/client"
|
16
|
+
require 'uri'
|
17
|
+
require 'zlib'
|
18
|
+
require 'base64'
|
19
|
+
require 'rexml/document'
|
20
|
+
|
21
|
+
private
|
22
|
+
def call name, *args
|
23
|
+
# puts "Call #{name}(#{args.inspect})"
|
24
|
+
begin
|
25
|
+
# remove trailing nil values, nil is not supported in xmlrpc
|
26
|
+
while args.size > 0 && args[-1].nil? do
|
27
|
+
args.pop
|
28
|
+
end
|
29
|
+
result = @client.call(name, *args)
|
30
|
+
rescue Exception => e
|
31
|
+
raise e unless e.message =~ /Wrong content-type/
|
32
|
+
end
|
33
|
+
response = @client.http_last_response
|
34
|
+
raise "XMLRPC failed with #{response.code}" unless response.code == "200"
|
35
|
+
body = response.body
|
36
|
+
case response["content-type"]
|
37
|
+
when "text/base64"
|
38
|
+
body = Base64.decode64(body)
|
39
|
+
when "text/xml"
|
40
|
+
# fallthru
|
41
|
+
else
|
42
|
+
STDERR.puts "Unhandled content-type #{response['content-type']}"
|
43
|
+
end
|
44
|
+
case response["content-encoding"]
|
45
|
+
when "x-zlib"
|
46
|
+
body = Zlib::Inflate.inflate(body)
|
47
|
+
when nil
|
48
|
+
# fallthru
|
49
|
+
else
|
50
|
+
STDERR.puts "Unhandled content-encoding #{response['content-encoding']}"
|
51
|
+
end
|
52
|
+
ok, result = @client.get_parser.parseMethodResponse(body)
|
53
|
+
raise unless ok
|
54
|
+
result
|
55
|
+
end
|
56
|
+
public
|
57
|
+
|
58
|
+
#
|
59
|
+
# Initialize server xmlrpc port
|
60
|
+
# options:
|
61
|
+
# :noconfig => true - don't load @config
|
62
|
+
# :server => string - url of server (for initial registration)
|
63
|
+
# :systemid => string
|
64
|
+
#
|
65
|
+
def initialize options = {}
|
66
|
+
@config = Spacewalk::Config.new
|
67
|
+
if options[:noconfig]
|
68
|
+
uri = URI.parse(options[:server])
|
69
|
+
uri.path = "/XMLRPC"
|
70
|
+
else
|
71
|
+
uri = URI.parse(@config.serverurl)
|
72
|
+
end
|
73
|
+
|
74
|
+
args = {:host=>uri.host, :path => uri.path, :use_ssl => (uri.scheme == "https")}
|
75
|
+
|
76
|
+
unless options[:noconfig]
|
77
|
+
if @config.httpProxy
|
78
|
+
args[:proxy_host], clientargs[:proxy_port] = @config.httpProxy.split ":"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
@client = XMLRPC::Client.new_from_hash args
|
83
|
+
|
84
|
+
@client.http_header_extra = {}
|
85
|
+
|
86
|
+
welcome
|
87
|
+
|
88
|
+
# parse server capabilities
|
89
|
+
@capabilities = Spacewalk::Capabilities.new @client
|
90
|
+
|
91
|
+
@client.http_header_extra["X-Up2date-Version"] = "1.6.42" # from rhn-client-tools.spec
|
92
|
+
@client.http_header_extra["X-RHN-Client-Capability"] = "packages.extended_profile(2)=1"
|
93
|
+
@systemid = options[:systemid]
|
94
|
+
unless @systemid || options[:noconfig]
|
95
|
+
@systemid = Spacewalk::SystemId.new(@client, @config).to_xml
|
96
|
+
end
|
97
|
+
# check for distribution update
|
98
|
+
# my_id = @systemid.os_release
|
99
|
+
# server_id = osversion
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# welcome to/from server
|
104
|
+
def welcome
|
105
|
+
result = call "registration.welcome_message"
|
106
|
+
puts "Welcome => #{result.inspect}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# get system O/S version
|
110
|
+
def osversion
|
111
|
+
result = @config.versionOverride
|
112
|
+
unless result
|
113
|
+
# find rpm provider of redhat-release or distribution-release, get its version
|
114
|
+
end
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
118
|
+
def actions
|
119
|
+
report = Spacewalk::StatusReport.status
|
120
|
+
|
121
|
+
result = call "queue.get", @systemid, ACTION_VERSION, report
|
122
|
+
puts "Actions => #{result.inspect}"
|
123
|
+
|
124
|
+
if action = result["action"]
|
125
|
+
result["action"] = @client.get_parser.parseMethodCall(action)
|
126
|
+
end
|
127
|
+
puts "Actions => #{result.inspect}"
|
128
|
+
end
|
129
|
+
|
130
|
+
def register activationkey, profile_name, other = {}
|
131
|
+
auth_dict = {}
|
132
|
+
auth_dict["profile_name"] = profile_name
|
133
|
+
#"os_release" : up2dateUtils.getVersion(),
|
134
|
+
#"release_name" : up2dateUtils.getOSRelease(),
|
135
|
+
#"architecture" : up2dateUtils.getArch() }
|
136
|
+
# dict of other bits to send
|
137
|
+
auth_dict.update other
|
138
|
+
auth_dict["token"] = activationkey
|
139
|
+
# auth_dict["username"] = username
|
140
|
+
# auth_dict["password"] = password
|
141
|
+
|
142
|
+
# if cfg['supportsSMBIOS']:
|
143
|
+
# auth_dict["smbios"] = _encode_characters(hardware.get_smbios())
|
144
|
+
STDERR.puts "registration.new_system #{auth_dict.inspect}"
|
145
|
+
@systemid = call "registration.new_system", auth_dict
|
146
|
+
end
|
147
|
+
|
148
|
+
def send_packages packages
|
149
|
+
call "registration.add_packages", @systemid, packages
|
150
|
+
end
|
151
|
+
def refresh_hardware devices
|
152
|
+
call "registration.refresh_hw_profile", @systemid, devices
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Spacewalk
|
2
|
+
class StatusReport
|
3
|
+
def self.status
|
4
|
+
status = {}
|
5
|
+
# Return a 5-tuple containing information identifying the current operating system.
|
6
|
+
# The tuple contains 5 strings: (sysname, nodename, release, version, machine).
|
7
|
+
# (uname -s, uname -n, uname -r, uname -v, uname -m)
|
8
|
+
status["uname"] = [`uname -s`.chomp, `uname -n`.chomp, `uname -r`.chomp, `uname -v`.chomp, `uname -m`.chomp]
|
9
|
+
begin
|
10
|
+
File.open("/proc/uptime") do |f|
|
11
|
+
status["uptime"] = f.read.split(" ").map{|v| v.to_i}
|
12
|
+
end
|
13
|
+
rescue
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
# puts status.inspect
|
17
|
+
status
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Spacewalk
|
2
|
+
class SystemId
|
3
|
+
require 'xmlrpc/client'
|
4
|
+
def initialize client, config
|
5
|
+
raise "Expecting a Spacewalk::Config parameter to #{self.class}.new" unless config.is_a?(Spacewalk::Config)
|
6
|
+
@path = config["systemIdPath"]
|
7
|
+
raise "systemIdPath is empty !" unless @path
|
8
|
+
# <params>
|
9
|
+
# <param>
|
10
|
+
# <value>
|
11
|
+
# <struct>
|
12
|
+
# <member>
|
13
|
+
# <name>username</name>
|
14
|
+
# <value><string>admin</string></value>
|
15
|
+
# </member>
|
16
|
+
File.open(@path) do |f|
|
17
|
+
@raw = f.read
|
18
|
+
@members = client.get_parser.parseMethodResponse(@raw)
|
19
|
+
end
|
20
|
+
puts "SystemId => #{@members.inspect}"
|
21
|
+
end
|
22
|
+
def to_xml
|
23
|
+
@raw
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Spacewalk
|
2
|
+
class Xmlrpc
|
3
|
+
require 'rexml/document'
|
4
|
+
private
|
5
|
+
def self.value2ruby element
|
6
|
+
puts "value2ruby element #{element}"
|
7
|
+
node = element[0]
|
8
|
+
puts "value2ruby node #{node}"
|
9
|
+
case node.name
|
10
|
+
when "string"
|
11
|
+
node.text
|
12
|
+
when "struct"
|
13
|
+
raise "value2ruby: <member> not following <struct>" unless node[0].name == "member"
|
14
|
+
value = {}
|
15
|
+
puts "Struct #{node}"
|
16
|
+
node.each_element("member") do |e|
|
17
|
+
name = e.elements["member/name"].text
|
18
|
+
v = value2ruby m.elements["member/value"]
|
19
|
+
value[name] = v
|
20
|
+
end
|
21
|
+
value
|
22
|
+
when "array"
|
23
|
+
raise "value2ruby: <data> not following <array>" unless node[0].name == "data"
|
24
|
+
value = []
|
25
|
+
# puts "Array #{node}"
|
26
|
+
node.each_element("data/value") do |e|
|
27
|
+
# puts "recursive #{e}"
|
28
|
+
value << value2ruby(e)
|
29
|
+
end
|
30
|
+
value
|
31
|
+
else
|
32
|
+
raise "value2ruby: Can't handle element '#{element.name}'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
public
|
36
|
+
# <params>
|
37
|
+
# <param>
|
38
|
+
# <value>
|
39
|
+
# <struct>
|
40
|
+
# <member>
|
41
|
+
# <name>username</name>
|
42
|
+
# <value><string>admin</string></value>
|
43
|
+
# </member>
|
44
|
+
# <value><string>...
|
45
|
+
# <value><array><data>...
|
46
|
+
#
|
47
|
+
def self.decode what
|
48
|
+
@doc.root.elements["params/param"]
|
49
|
+
|
50
|
+
initialize config
|
51
|
+
raise "Expecting a Spacewalk::Config parameter to #{self.class}.new" unless config.is_a?(Spacewalk::Config)
|
52
|
+
@path = config["systemIdPath"]
|
53
|
+
raise "systemIdPath is empty !" unless @path
|
54
|
+
@doc = REXML::Document.new(File.open(@path))
|
55
|
+
@members = @doc.root.elements["params/param"]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spacewalk.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "spacewalk/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "spacewalk"
|
7
|
+
s.version = Spacewalk::VERSION
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Klaus Kämpf"]
|
11
|
+
s.email = ["kkaempf@suse.de"]
|
12
|
+
s.homepage = "https://github.com/kkaempf/ruby-spacewalk"
|
13
|
+
s.summary = %q{A pure-Ruby implementation of the Spacewalk client side}
|
14
|
+
s.description = %q{Can be used for testing or to attach 'foreign'
|
15
|
+
systems}
|
16
|
+
|
17
|
+
s.rubyforge_project = "spacewalk"
|
18
|
+
|
19
|
+
s.add_development_dependency('rake')
|
20
|
+
s.add_development_dependency('bundler')
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.files.reject! { |fn| fn == '.gitignore' }
|
24
|
+
s.extra_rdoc_files = Dir['README*', 'TODO*', 'CHANGELOG*', 'LICENSE']
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
end
|
data/tasks/clean.rake
ADDED
data/tasks/doc.rake
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
begin
|
2
|
+
require 'yard'
|
3
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
4
|
+
t.files = ['lib/**/*.rb']
|
5
|
+
t.options = ['--no-private']
|
6
|
+
end
|
7
|
+
rescue LoadError
|
8
|
+
STDERR.puts "Install yard if you want prettier docs"
|
9
|
+
require 'rdoc/task'
|
10
|
+
Rake::RDocTask.new(:doc) do |rdoc|
|
11
|
+
rdoc.rdoc_dir = "doc"
|
12
|
+
rdoc.title = "Spacewalk #{Spacewalk::VERSION}"
|
13
|
+
end
|
14
|
+
end
|
data/tasks/test.rake
ADDED
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spacewalk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- "Klaus K\xC3\xA4mpf"
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-17 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rake
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bundler
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
description: |-
|
50
|
+
Can be used for testing or to attach 'foreign'
|
51
|
+
systems
|
52
|
+
email:
|
53
|
+
- kkaempf@suse.de
|
54
|
+
executables:
|
55
|
+
- actions.rb
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files:
|
59
|
+
- README.rdoc
|
60
|
+
- CHANGELOG
|
61
|
+
- LICENSE
|
62
|
+
files:
|
63
|
+
- CHANGELOG
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- README.rdoc
|
67
|
+
- Rakefile
|
68
|
+
- bin/actions.rb
|
69
|
+
- doc/protocol.doc
|
70
|
+
- lib/spacewalk.rb
|
71
|
+
- lib/spacewalk/capabilities.rb
|
72
|
+
- lib/spacewalk/config.rb
|
73
|
+
- lib/spacewalk/server.rb
|
74
|
+
- lib/spacewalk/status_report.rb
|
75
|
+
- lib/spacewalk/system_id.rb
|
76
|
+
- lib/spacewalk/version.rb
|
77
|
+
- lib/spacewalk/xmlrpc.rb
|
78
|
+
- spacewalk.gemspec
|
79
|
+
- tasks/clean.rake
|
80
|
+
- tasks/doc.rake
|
81
|
+
- tasks/test.rake
|
82
|
+
has_rdoc: true
|
83
|
+
homepage: https://github.com/kkaempf/ruby-spacewalk
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
requirements: []
|
110
|
+
|
111
|
+
rubyforge_project: spacewalk
|
112
|
+
rubygems_version: 1.5.0
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: A pure-Ruby implementation of the Spacewalk client side
|
116
|
+
test_files: []
|
117
|
+
|