commit 2bbc99dbd4961dae576fe97a55b8b59d496123ed
Author: Chris Duryee <cduryee(a)redhat.com>
Date: Mon Aug 26 20:43:16 2013 -0400
register one system per hypervisor
Previously, each cluster was registered as a single system. Instead, register
each hypervisor individually.
Also, use more descriptive hypervisor system names that include UUID and virt
type.
Makefile | 1 -
satellite.py | 161 +++++++++++++++++--------------------------
subscriptionmanager.py | 2 +-
virt-who-register-satellite | 10 ---
virt-who.py | 2 +-
virt-who.spec | 1 -
6 files changed, 64 insertions(+), 113 deletions(-)
---
diff --git a/Makefile b/Makefile
index 5331a4a..6dee540 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,6 @@ install:
install -d $(DESTDIR)/usr/share/$(name)/ $(DESTDIR)/usr/bin $(DESTDIR)/etc/rc.d/init.d
$(DESTDIR)/etc/sysconfig $(DESTDIR)/usr/share/man/man8/
install -pm 0644 *.py $(DESTDIR)/usr/share/$(name)/
install virt-who $(DESTDIR)/usr/bin/
- install virt-who-register-satellite $(DESTDIR)/usr/bin/
install virt-who-initscript $(DESTDIR)/etc/rc.d/init.d/virt-who
install -pm 0644 virt-who.conf $(DESTDIR)/etc/sysconfig/virt-who
gzip -c virt-who.8 > virt-who.8.gz
diff --git a/satellite.py b/satellite.py
index e25ae15..3a98beb 100644
--- a/satellite.py
+++ b/satellite.py
@@ -32,19 +32,20 @@ class SatelliteError(Exception):
class Satellite(object):
""" Class for interacting with satellite (RHN Classic).
"""
- VAR_DIR = "/var/lib/virt-who/"
- HYPERVISOR_SYSTEMID_FILE = VAR_DIR + "hypervisor-systemid"
+ HYPERVISOR_SYSTEMID_FILE="/var/lib/virt-who/hypervisor-systemid-%s"
def __init__(self, logger):
self.logger = logger
self.server = None
def connect(self, server, username, password, options=None, force_register=False):
- # initialize a new system if one doesn't already exist
if not server.startswith("http://") and not
server.startswith("https://"):
server = "https://%s" % server
if not server.endswith("XMLRPC"):
server = "%s/XMLRPC" % server
+ self.username = username
+ self.password = password
+
self.logger.debug("Initializing satellite connection to %s" % server)
try:
self.server = xmlrpclib.Server(server, verbose=0)
@@ -53,54 +54,36 @@ class Satellite(object):
raise SatelliteError("Unable to connect to the Satellite server")
self.logger.info("Initialized satellite connection")
- # initialize a new system if one doesn't already exist
- if force_register:
- new_system = self._register_hypervisor(username, password, options)
- else:
- try:
- self.logger.debug("Loading system id info from %s" %
self.HYPERVISOR_SYSTEMID_FILE)
- new_system = pickle.load(open(self.HYPERVISOR_SYSTEMID_FILE,
"rb"))
- except IOError:
- new_system = self._register_hypervisor(username, password, options)
-
- if new_system is None:
- raise SatelliteError("Unable to register hypervisor")
-
- self.systemid = new_system["system_id"]
-
- def _register_hypervisor(self, username, password, options):
- if options is None:
- # We need to emulate options object from argparse
- class O(object): pass
- options = O()
- # Fill in some defaults
- if not hasattr(options, "profile_name") or options.profile_name is
None:
- options.profile_name = "hypervisor"
- if not hasattr(options, "os_release_name") or options.os_release_name
is None:
- options.os_release_name = "unknown"
- if not hasattr(options, "version") or options.version is None:
- # TODO: what to do here? 6Server will consume subscription
- options.version = "6Server"
- if not hasattr(options, "arch") or options.arch is None:
- options.arch = "x86_64"
-
+ def _load_hypervisor(self, hypervisor_uuid, type):
+ systemid_filename = self.HYPERVISOR_SYSTEMID_FILE % hypervisor_uuid
+ # attempt to read the existing systemid file for the hypervisor
try:
- new_system =
self.server.registration.new_system_user_pass(options.profile_name,
- options.os_release_name, options.version, options.arch, username,
password, {})
- self.server.registration.refresh_hw_profile(new_system['system_id'],
[])
- except Exception, e:
- self.logger.exception("Unable to refresh HW profile")
- raise SatelliteError("Unable to refresh HW profile: %s" % str(e))
- try:
- f = open(self.HYPERVISOR_SYSTEMID_FILE, "w")
+ self.logger.debug("Loading system id info from %s" %
systemid_filename)
+ new_system = pickle.load(open(systemid_filename, "rb"))
+ except IOError:
+ # assume file was not found, create a new hypervisor
+ try:
+ # TODO: what to do here? 6Server will consume subscription
+ new_system = self.server.registration.new_system_user_pass("%s
hypervisor %s" % (type, hypervisor_uuid),
+ "unknown", "6Server", "x86_64",
self.username, self.password, {})
+
self.server.registration.refresh_hw_profile(new_system['system_id'], [])
+ except Exception, e:
+ self.logger.exception("Unable to refresh HW profile")
+ raise SatelliteError("Unable to refresh HW profile: %s" %
str(e))
+ # save the hypervisor systemid
try:
- pickle.dump(new_system, f)
- finally:
- f.close()
- except (OSError, IOError), e:
- self.logger.error("Unable to write system id to %s: %s" %
(self.HYPERVISOR_SYSTEMID_FILE, str(e)))
+ f = open(systemid_filename, "w")
+ try:
+ pickle.dump(new_system, f)
+ finally:
+ f.close()
+ except (OSError, IOError), e:
+ self.logger.error("Unable to write system id to %s: %s" %
(systemid_filename, str(e)))
- self.logger.debug("New system created in satellite, system id saved in
%s" % self.HYPERVISOR_SYSTEMID_FILE)
+ self.logger.debug("New system created in satellite, system id saved in
%s" % systemid_filename)
+
+ if new_system is None:
+ raise SatelliteError("Unable to register hypervisor %s" %
hypervisor_uuid)
return new_system
@@ -110,8 +93,10 @@ class Satellite(object):
"""
pass
- def _assemble_plan(self, uuids):
+ def _assemble_plan(self, hypervisor_mapping, hypervisor_uuid, type):
+ # Get rid of dashes from UUID, spacewalk does not like them
+ #hypervisor_uuid = (str(hypervisor_uuid).replace("-", ""))
events = []
# the stub_instance_info is not used by the report. When the guest system checks
in, it will provide
@@ -121,17 +106,23 @@ class Satellite(object):
'memory_size' : 0,
'virt_type' : 'fully_virtualized',
'state' : 'running',
- # TODO: put hypervisor's hostname here maybe
- 'name': "virtual machine from %s" % 'vmware
hypervisor'
}
- # declare the hypervisor. always use 16 zeros for the hypervisor's UUID, per
rhn-virtualization-host
- events.append([0, 'exists', 'system', {'identity':
'host', 'uuid': self.uuid()}])
+ # again, remove dashes
+ guest_uuids = []
+ for g_uuid in hypervisor_mapping:
+ guest_uuids.append(str(g_uuid).replace("-", ""))
+
+
+ # TODO: spacewalk wants all zeroes for the hypervisor uuid??
+ events.append([0, 'exists', 'system', {'identity':
'host', 'uuid': '0000000000000000'}])
events.append([0, 'crawl_began', 'system', {}])
- for uuid in uuids:
- stub_instance_info['uuid'] = uuid
+ for guest_uuid in guest_uuids:
+ stub_instance_info['uuid'] = guest_uuid
+ stub_instance_info['name'] = "VM from %s hypervisor %s" %
(type, hypervisor_uuid)
events.append([0, 'exists', 'domain',
stub_instance_info.copy()])
+
events.append([0, 'crawl_ended', 'system', {}])
return events
@@ -139,27 +130,21 @@ class Satellite(object):
def sendVirtGuests(self, domains):
raise SatelliteError("virt-who does not support sending local hypervisor
data to satellite; use rhn-virtualization-host instead")
- def hypervisorCheckIn(self, owner, env, mapping):
- self.logger.debug("Building plan for mapping: %s" % mapping)
- if self.server is None:
- return
- uuids = []
- for guestlist in mapping.values():
- for uuid in guestlist:
- # Get rid of dashes from UUID
- uuids.append(str(uuid).replace("-", ""))
- uuids.sort()
-
- self.logger.debug("Sending flattened list of uuids: %s" % uuids)
-
- plan = self._assemble_plan(uuids)
- self.logger.debug("Sending plan: %s" % plan)
- # Send the mapping
- try:
- res = self.server.registration.virt_notify(self.systemid, plan)
- except Exception, e:
- self.logger.exception("Unable to send host/guest assocaition to the
satellite:")
- raise SatelliteError("Unable to send host/guest assocaition to the
satellite: % " % str(e))
+ def hypervisorCheckIn(self, owner, env, mapping, type=None):
+
+ for hypervisor_uuid in mapping:
+ self.logger.debug("Loading systemid for %s" % hypervisor_uuid)
+ hypervisor_systemid = self._load_hypervisor(hypervisor_uuid, type=type)
+
+ self.logger.debug("Building plan for hypervisor %s: %s" %
(hypervisor_uuid, mapping[hypervisor_uuid]))
+ plan = self._assemble_plan(mapping[hypervisor_uuid], hypervisor_uuid, type =
type)
+
+ try:
+ self.logger.debug("Sending plan: %s" % plan)
+
self.server.registration.virt_notify(hypervisor_systemid["system_id"], plan)
+ except Exception, e:
+ self.logger.exception("Unable to send host/guest assocaition to the
satellite:")
+ raise SatelliteError("Unable to send host/guest assocaition to the
satellite: % " % str(e))
# TODO: figure out what to populate here
result = {}
@@ -169,31 +154,9 @@ class Satellite(object):
return result
def uuid(self):
- """ Satellite expects a zeroed-out hypervisor UUID
"""
+ """ not implemented """
return '0000000000000000'
def getFacts(self):
""" Not implemented """
pass
-
-if __name__ == '__main__':
- from optparse import OptionParser
- import logging
- parser = OptionParser(usage="virt-who-register-satellite [-n name] [-o
operating_system] [-v version] [-a arch] server username password",
- description="Register hypervisor to the satellite
server")
- parser.add_option("-n", "--name", action="store",
dest="profile_name", default=None, help="Name of the hypervisor")
- parser.add_option("-o", "--operating-system",
action="store", dest="os_release_name", default=None,
help="Operating system of the hypervisor")
- parser.add_option("-v", "--version", action="store",
dest="version", default=None, help="Operating system version")
- parser.add_option("-a", "--arch", action="store",
dest="arch", default=None, help="Hypervisor architecture")
- (options, args) = parser.parse_args()
- if len(args) < 3:
- parser.print_usage()
- sys.exit(1)
-
- logger = logging.getLogger()
- logger.addHandler(logging.StreamHandler())
- satellite = Satellite(logger)
- try:
- satellite.connect(args[0], args[1], args[2], force_register=True,
options=options)
- except Exception:
- logger.exception("Unable to connect to Satellite:")
diff --git a/subscriptionmanager.py b/subscriptionmanager.py
index 6dc2482..51345d9 100644
--- a/subscriptionmanager.py
+++ b/subscriptionmanager.py
@@ -83,7 +83,7 @@ class SubscriptionManager:
# Send list of guest uuids to the server
self.connection.updateConsumer(self.uuid(), guest_uuids=uuids)
- def hypervisorCheckIn(self, owner, env, mapping):
+ def hypervisorCheckIn(self, owner, env, mapping, type=None):
""" Send hosts to guests mapping to subscription manager.
"""
self.logger.debug("Sending update in hosts-to-guests mapping: %s" %
mapping)
diff --git a/virt-who.py b/virt-who.py
index 53051ef..36c2f90 100644
--- a/virt-who.py
+++ b/virt-who.py
@@ -204,7 +204,7 @@ class VirtWho(object):
if self.options.virtType not in ["esx", "rhevm",
"hyperv"]:
self.subscriptionManager.sendVirtGuests(virtualGuests)
else:
- result = self.subscriptionManager.hypervisorCheckIn(self.options.owner,
self.options.env, virtualGuests)
+ result = self.subscriptionManager.hypervisorCheckIn(self.options.owner,
self.options.env, virtualGuests, type=self.options.virtType)
# Show the result of hypervisorCheckIn
for fail in result['failedUpdate']:
diff --git a/virt-who.spec b/virt-who.spec
index cd37072..1dc936d 100644
--- a/virt-who.spec
+++ b/virt-who.spec
@@ -64,7 +64,6 @@ fi
%files
%doc README LICENSE
%{_bindir}/virt-who
-%{_bindir}/virt-who-register-satellite
%{_datadir}/virt-who/
%{_sysconfdir}/rc.d/init.d/virt-who
%config(noreplace) %{_sysconfdir}/sysconfig/virt-who