#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
#
""" A thin wrapper around the SMF support provided by rad """
from __future__ import absolute_import
import rad.client as client
import rad.util as util
import threading
import smf.fmri
import os
_RAD_TYPE_MASTER = ("type", "Master")
_RAD_TYPE_INSTANCE = ("type", "Instance")
_RAD_TYPE_SERVICE = ("type", "Service")
_RAD_SMF_DOMAIN = "com.oracle.solaris.rad.smf"
_RAD_SMF_MODULE = "/usr/lib/rad/module/mod_smf.so"
_RAD_SMF_MASTER = client.Name(_RAD_SMF_DOMAIN, [_RAD_TYPE_MASTER])
class PropChange:
def __init__(self, name, type, values):
self.name = name
self.type = type
self.values = values
class Repository:
""" Represents a connection to the SCF repository """
def __init__(self, conn = None):
if conn is None:
self._rc = util.connect_unix()
else:
self._rc = conn
self._lock = threading.Lock()
self._aggr = None
@staticmethod
def connect_private(doorpath = None):
"""
Create a connection to a private (piped) minimalist (SMF module
only) RAD instance.
Arguments:
doorpath (string): if not None, the door path to use to
connect to a custom SMF repo (default: None)
Returns:
rad.client.RadConnection: the private connection
"""
if doorpath is not None:
env = os.environ.copy()
env["LIBSCF_DOORPATH"] = doorpath
else:
env = None
return util.connect_private([ _RAD_SMF_MODULE ], env = env)
@staticmethod
def parts_to_name(service, instance = None, scope = None):
""" Convert service and/or instance to a rad.client.Name """
svc = ("service", service)
if instance is not None:
kvs = [_RAD_TYPE_INSTANCE, svc, ("instance", instance)]
else:
kvs = [_RAD_TYPE_SERVICE, svc]
if scope is not None:
kvs.append(("scope", scope))
return client.Name(_RAD_SMF_DOMAIN, kvs)
@staticmethod
def fmri_to_name(fmri):
""" Convert an FMRI object to a rad.client.Name """
return Repository.parts_to_name(fmri.get_service(),
fmri.get_instance(), fmri.get_scope())
def lookup_byname(self, name):
""" Look up a service/instance object by rad.client.Name """
return self._rc.get_object(name)
def lookup(self, fmri):
""" Look up a service/instance object by FMRI object """
return self.lookup_byname(Repository.fmri_to_name(fmri))
def lookup_byfmri(self, fmri):
""" Look up a service/instance object by svc: FMRI string """
return self.lookup(smf.fmri.FMRI.parse(fmri))
def lookup_byparts(self, service, instance = None, scope = None):
""" Look up a service/instance object by svc and/or inst """
return self.lookup_byname(Repository.parts_to_name(
service, instance, scope))
def get_master(self):
""" Return the SMF master object """
with self._lock:
if self._aggr is None:
self._aggr = self.lookup_byname(_RAD_SMF_MASTER)
return self._aggr
def close(self):
""" Close the connection to the RAD server """
self._rc.close()