Example #1
0
 def refresh_slice_vinit(self):
     code=self.initscript
     sliver_initscript="/vservers/%s/etc/rc.d/init.d/vinit.slice"%self.name
     if tools.replace_file_with_string(sliver_initscript,code,remove_if_empty=True,chmod=0755):
         if code:
             logger.log("vsliver_vs: %s: Installed new initscript in %s"%(self.name,sliver_initscript))
             if self.is_running():
                 # Only need to rerun the initscript if the vserver is
                 # already running. If the vserver isn't running, then the
                 # initscript will automatically be started by
                 # /etc/rc.d/vinit when the vserver is started.
                 self.rerun_slice_vinit()
         else:
             logger.log("vsliver_vs: %s: Removed obsolete initscript %s"%(self.name,sliver_initscript))
Example #2
0
 def refresh_slice_vinit(self):
     code=self.initscript
     sliver_initscript="/vservers/%s/etc/rc.d/init.d/vinit.slice"%self.name
     if tools.replace_file_with_string(sliver_initscript,code,remove_if_empty=True,chmod=0755):
         if code:
             logger.log("vsliver_vs: %s: Installed new initscript in %s"%(self.name,sliver_initscript))
             if self.is_running():
                 # Only need to rerun the initscript if the vserver is
                 # already running. If the vserver isn't running, then the
                 # initscript will automatically be started by
                 # /etc/rc.d/vinit when the vserver is started.
                 self.rerun_slice_vinit()
         else:
             logger.log("vsliver_vs: %s: Removed obsolete initscript %s"%(self.name,sliver_initscript))
Example #3
0
 def install_and_enable_vinit (self):
     vinit_source="/usr/share/NodeManager/sliver-initscripts/vinit"
     vinit_script="/vservers/%s/etc/rc.d/init.d/vinit"%self.name
     rc3_link="/vservers/%s/etc/rc.d/rc3.d/S99vinit"%self.name
     rc3_target="../init.d/vinit"
     # install in sliver
     code=file(vinit_source).read()
     if tools.replace_file_with_string(vinit_script,code,chmod=0755):
         logger.log("vsliver_vs: %s: installed generic vinit rc script"%self.name)
     # create symlink for runlevel 3
     if not os.path.islink(rc3_link):
         try:
             logger.log("vsliver_vs: %s: creating runlevel3 symlink %s"%(self.name,rc3_link))
             os.symlink(rc3_target,rc3_link)
         except:
             logger.log_exc("vsliver_vs: %s: failed to create runlevel3 symlink %s"%rc3_link)
def manage_hmac(plc, sliver):
    hmac = find_tag(sliver, 'hmac')

    if not hmac:
        # let python do its thing
        random.seed()
        d = [random.choice(string.letters) for x in xrange(32)]
        hmac = "".join(d)
        SetSliverTag(plc, sliver['name'], 'hmac', hmac)
        logger.log("sliverauth: %s: setting hmac" % sliver['name'])

    path = '/vservers/%s/etc/planetlab' % sliver['name']
    if os.path.exists(path):
        keyfile = '%s/key' % path
        if (tools.replace_file_with_string(keyfile, hmac, chmod=0400)):
            logger.log("sliverauth: (over)wrote hmac into %s " % keyfile)
Example #5
0
 def install_and_enable_vinit (self):
     vinit_source="/usr/share/NodeManager/sliver-initscripts/vinit"
     vinit_script="/vservers/%s/etc/rc.d/init.d/vinit"%self.name
     rc3_link="/vservers/%s/etc/rc.d/rc3.d/S99vinit"%self.name
     rc3_target="../init.d/vinit"
     # install in sliver
     code=file(vinit_source).read()
     if tools.replace_file_with_string(vinit_script,code,chmod=0755):
         logger.log("vsliver_vs: %s: installed generic vinit rc script"%self.name)
     # create symlink for runlevel 3
     if not os.path.islink(rc3_link):
         try:
             logger.log("vsliver_vs: %s: creating runlevel3 symlink %s"%(self.name,rc3_link))
             os.symlink(rc3_target,rc3_link)
         except:
             logger.log_exc("vsliver_vs: %s: failed to create runlevel3 symlink %s"%rc3_link)
Example #6
0
def manage_hmac (plc, sliver):
    hmac = find_tag (sliver, 'hmac')

    if not hmac:
        # let python do its thing 
        random.seed()
        d = [random.choice(string.letters) for x in xrange(32)]
        hmac = "".join(d)
        SetSliverTag(plc,sliver['name'],'hmac',hmac)
        logger.log("sliverauth: %s: setting hmac" % sliver['name'])

    path = '/vservers/%s/etc/planetlab' % sliver['name']
    if os.path.exists(path):
        keyfile = '%s/key' % path
        if (tools.replace_file_with_string(keyfile,hmac,chmod=0400)):
            logger.log ("sliverauth: (over)wrote hmac into %s " % keyfile)
 def install_and_enable_vinit_for_init(self):
     """
     suitable for init-based VMs
     """
     vinit_source = "/usr/share/NodeManager/sliver-initscripts/vinit"
     vinit_script = "/vservers/%s/etc/rc.d/init.d/vinit" % self.name
     enable_link = "/vservers/%s/etc/rc.d/rc3.d/S99vinit" % self.name
     enable_target = "../init.d/vinit"
     # install in sliver
     with open(vinit_source) as f:
         code = f.read()
     if tools.replace_file_with_string(vinit_script, code, chmod=0o755):
         logger.log("Initscript: %s: installed generic vinit rc script" % self.name)
     # create symlink for runlevel 3
     if not os.path.islink(enable_link):
         try:
             logger.log("Initscript: %s: creating runlevel3 symlink %s" % (self.name, enable_link))
             os.symlink(enable_target, enable_link)
         except:
             logger.log_exc("Initscript failed to create runlevel3 symlink %s" % enable_link, name=self.name)
 def configure(self, rec):
     # install or remove the slice inistscript, as instructed by the initscript tag
     new_initscript = rec['initscript']
     if new_initscript == self.initscript:
         return
     logger.log("initscript.configure {}".format(self.name))
     self.initscript = new_initscript
     code = self.initscript
     sliver_initscript = "/vservers/%s/etc/rc.d/init.d/vinit.slice" % self.name
     if tools.replace_file_with_string(sliver_initscript, code, remove_if_empty=True, chmod=0o755):
         if code:
             logger.log("Initscript: %s: Installed new initscript in %s" % (self.name, sliver_initscript))
             if self.is_running():
                 # Only need to rerun the initscript if the vserver is
                 # already running. If the vserver isn't running, then the
                 # initscript will automatically be started by
                 # /etc/rc.d/vinit when the vserver is started.
                 self.rerun_slice_vinit()
         else:
             logger.log("Initscript: %s: Removed obsolete initscript %s" % (self.name, sliver_initscript))
    def install_and_enable_vinit_for_systemd(self):
        """
        suitable for systemd-based VMs
        """

        ##########
        ########## initscripts : current status - march 2015
        ##########
        #
        # the initscripts business worked smoothly up to f18 inclusive
        # with f20 and the apparition of machinectl, things started to
        # behave really weird
        #
        # so starting with f20, after having tried pretty hard to get this right,
        # but to no success obviously, and in order to stay on the safe side
        # of the force, I am turning off the initscript machinery completely
        # that is to say: the vinit.service does not get installed at all
        # 
        if os.path.isfile('/usr/bin/machinectl'):
            logger.log("WARNING: initscripts are not supported anymore in nodes that have machinectl")
            return

        vinit_source = "/usr/share/NodeManager/sliver-systemd/vinit.service"
        vinit_unit_file = "/vservers/%s/usr/lib/systemd/system/vinit.service" % self.name
        enable_link = "/vservers/%s/etc/systemd/system/multi-user.target.wants/vinit.service" % self.name
        enable_target = "/usr/lib/systemd/system/vinit.service"
        # install in sliver
        with open(vinit_source) as f:
            code = f.read()
        if tools.replace_file_with_string(vinit_unit_file, code, chmod=0o755):
            logger.log("Initscript: %s: installed vinit.service unit file" % self.name)
        # create symlink for enabling this unit
        if not os.path.islink(enable_link):
            try:
                logger.log("Initscript: %s: creating enabling symlink %s" % (self.name, enable_link))
                os.symlink(enable_target, enable_link)
            except:
                logger.log_exc("Initscript failed to create enabling symlink %s" % enable_link, name=name)
Example #10
0
def GetSlivers(data, conf=None, plc=None):
    if 'accounts' not in data:
        logger.log_missing_data("specialaccounts.GetSlivers", 'accounts')
        return

    for account in data['accounts']:
        name = account['name']
        new_keys = account['keys']

        logger.log('specialaccounts: dealing with account %s' % name)

        # look up account name, which must exist
        pw_info = pwd.getpwnam(name)
        uid = pw_info[2]
        gid = pw_info[3]
        pw_dir = pw_info[5]

        # populate account's .ssh/authorized_keys file
        dot_ssh = os.path.join(pw_dir, '.ssh')  #~/.ssh
        if not os.access(dot_ssh, os.F_OK): os.mkdir(dot_ssh)  #mkdir ~/.ssh
        auth_keys = os.path.join(dot_ssh,
                                 'authorized_keys')  #=~/.ssh/authorized_keys

        # catenate all keys in string, add newlines just in case (looks like keys already have this, but)
        auth_keys_contents = '\n'.join(new_keys) + '\n'

        changes = tools.replace_file_with_string(auth_keys, auth_keys_contents)
        if changes:
            logger.log("specialaccounts: keys file changed: %s" % auth_keys)

        # always set permissions properly
        os.chmod(dot_ssh, 0700)
        os.chown(dot_ssh, uid, gid)
        os.chmod(auth_keys, 0600)
        os.chown(auth_keys, uid, gid)

        logger.log('specialaccounts: installed ssh keys for %s' % name)
Example #11
0
def GetSlivers(data, conf = None, plc = None):
    if 'accounts' not in data:
        logger.log_missing_data("specialaccounts.GetSlivers",'accounts')
        return

    for account in data['accounts']:
        name = account['name']
        new_keys = account['keys']

        logger.log('specialaccounts: dealing with account %s'%name)

        # look up account name, which must exist
        pw_info = pwd.getpwnam(name)
        uid = pw_info[2]
        gid = pw_info[3]
        pw_dir = pw_info[5]

        # populate account's .ssh/authorized_keys file
        dot_ssh = os.path.join(pw_dir,'.ssh')
        if not os.access(dot_ssh, os.F_OK): os.mkdir(dot_ssh)
        auth_keys = os.path.join(dot_ssh,'authorized_keys')

        # catenate all keys in string, add newlines just in case (looks like keys already have this, but)
        auth_keys_contents = '\n'.join(new_keys)+'\n'

        changes = tools.replace_file_with_string(auth_keys,auth_keys_contents)
        if changes:
            logger.log("specialaccounts: keys file changed: %s" % auth_keys)

        # always set permissions properly
        os.chmod(dot_ssh, 0700)
        os.chown(dot_ssh, uid,gid)
        os.chmod(auth_keys, 0600)
        os.chown(auth_keys, uid,gid)

        logger.log('specialaccounts: installed ssh keys for %s' % name)
def GetSlivers(data, conf=None, plc=None):
    logger.log("omf_resctl.GetSlivers")
    if 'accounts' not in data:
        logger.log_missing_data("omf_resctl.GetSlivers", 'accounts')
        return

    try:
        xmpp_server = data['xmpp']['server']
        if not xmpp_server:
            # we have the key but no value, just as bad
            raise Exception
    except:
        # disabled feature - bailing out
        logger.log(
            "omf_resctl: PLC_OMF config unsufficient (not enabled, or no server set), -- plugin exiting"
        )
        return

    hostname = data['hostname']

    def is_omf_friendly(sliver):
        for chunk in sliver['attributes']:
            if chunk['tagname'] == 'omf_control': return True

    for sliver in data['slivers']:
        # skip non OMF-friendly slices
        if not is_omf_friendly(sliver): continue
        slicename = sliver['name']
        expires = str(sliver['expires'])
        yaml_template = config_ple_template
        yaml_contents = yaml_template\
            .replace('_xmpp_server_',xmpp_server)\
            .replace('_slicename_',slicename)\
            .replace('_hostname_',hostname)\
            .replace('_expires_',expires)
        yaml_full_path = "/vservers/%s/%s" % (slicename, yaml_slice_path)
        yaml_full_dir = os.path.dirname(yaml_full_path)
        if not os.path.isdir(yaml_full_dir):
            try:
                os.makedirs(yaml_full_dir)
            except OSError:
                pass

        config_changes = tools.replace_file_with_string(
            yaml_full_path, yaml_contents)
        logger.log("yaml_contents length=%d, config_changes=%r" %
                   (len(yaml_contents), config_changes))
        # would make sense to also check for changes to authorized_keys
        # would require saving a copy of that some place for comparison
        # xxx todo
        keys_changes = False
        if config_changes or keys_changes:
            # instead of restarting the service we call a companion script
            try:
                fetch_trigger_script_if_missing(slicename)
                # the trigger script actually needs to be run in the slice context of course
                # in addition there is a requirement to pretend we run as a login shell
                # hence sudo -i
                slice_command = ["sudo", "-i", omf_rc_trigger_script]
                to_run = tools.command_in_slice(slicename, slice_command)
                log_filename = "/vservers/%s/%s" % (slicename,
                                                    omf_rc_trigger_log)
                logger.log("omf_resctl: starting %s" % to_run)
                logger.log("redirected into %s" % log_filename)
                logger.log("*not* waiting for completion..")
                with open(log_filename, "a") as log_file:
                    subprocess.Popen(to_run,
                                     stdout=log_file,
                                     stderr=subprocess.STDOUT)
                # a first version tried to 'communicate' on that subprocess instance
                # but that tended to create deadlocks in some cases
                # causing nodemanager to stall...
                # we're only losing the child's retcod, no big deal
            except:
                import traceback
                traceback.print_exc()
                logger.log_exc("omf_resctl: WARNING: Could not call trigger script %s"%\
                                   omf_rc_trigger_script, name=slicename)
        else:
            logger.log("omf_resctl: %s: omf_control'ed sliver has no change" %
                       slicename)
def GetSlivers(data, conf = None, plc = None):
    logger.log("omf_resctl.GetSlivers")
    if 'accounts' not in data:
        logger.log_missing_data("omf_resctl.GetSlivers", 'accounts')
        return

    try:
        xmpp_server=data['xmpp']['server']
        if not xmpp_server: 
            # we have the key but no value, just as bad
            raise Exception
    except:
        # disabled feature - bailing out
        logger.log("omf_resctl: PLC_OMF config unsufficient (not enabled, or no server set), -- plugin exiting")
        return

    hostname = data['hostname']

    def is_omf_friendly (sliver):
        for chunk in sliver['attributes']:
            if chunk['tagname']=='omf_control': return True

    for sliver in data['slivers']:
        # skip non OMF-friendly slices
        if not is_omf_friendly (sliver): continue
        slicename=sliver['name']
        expires=str(sliver['expires'])
        yaml_template = config_ple_template
        yaml_contents = yaml_template\
            .replace('_xmpp_server_', xmpp_server)\
            .replace('_slicename_', slicename)\
            .replace('_hostname_', hostname)\
            .replace('_expires_', expires)
        yaml_full_path="/vservers/%s/%s"%(slicename, yaml_slice_path)
        yaml_full_dir=os.path.dirname(yaml_full_path)
        if not os.path.isdir(yaml_full_dir):
            try: os.makedirs(yaml_full_dir)
            except OSError: pass

        config_changes=tools.replace_file_with_string(yaml_full_path, yaml_contents)
        logger.log("yaml_contents length=%d, config_changes=%r"%(len(yaml_contents), config_changes))
        # would make sense to also check for changes to authorized_keys 
        # would require saving a copy of that some place for comparison
        # xxx todo
        keys_changes = False
        if config_changes or keys_changes:
            # instead of restarting the service we call a companion script
            try:
                fetch_trigger_script_if_missing (slicename)
                # the trigger script actually needs to be run in the slice context of course
                # in addition there is a requirement to pretend we run as a login shell
                # hence sudo -i
                slice_command = [ "sudo", "-i",  omf_rc_trigger_script ]
                to_run = tools.command_in_slice (slicename, slice_command)
                log_filename = "/vservers/%s/%s"%(slicename, omf_rc_trigger_log)
                logger.log("omf_resctl: starting %s"%to_run)
                logger.log("redirected into %s"%log_filename)
                logger.log("*not* waiting for completion..")
                with open(log_filename, "a") as log_file:
                    subprocess.Popen(to_run, stdout=log_file, stderr=subprocess.STDOUT)
                # a first version tried to 'communicate' on that subprocess instance
                # but that tended to create deadlocks in some cases
                # causing nodemanager to stall...
                # we're only losing the child's retcod, no big deal
            except:
                import traceback
                traceback.print_exc()
                logger.log_exc("omf_resctl: WARNING: Could not call trigger script %s"%\
                                   omf_rc_trigger_script, name=slicename)
        else:
            logger.log("omf_resctl: %s: omf_control'ed sliver has no change" % slicename)
Example #14
0
def GetSlivers(data, conf=None, plc=None):
    if "accounts" not in data:
        logger.log_missing_data("omf_resctl.GetSlivers", "accounts")
        return

    try:
        xmpp_server = data["xmpp"]["server"]
        if not xmpp_server:
            # we have the key but no value, just as bad
            raise Exception
    except:
        # disabled feature - bailing out
        # xxx might need to clean up more deeply..
        logger.log(
            "PLC config unsufficient (not enabled, or no server set), see the PLC_OMF category -- plugin exiting"
        )
        return

    # as hrn is set only at AddNode-time, upgraded myplcs might still miss this
    # clue: just overwrite the hostname of all nodes
    # for node in GetNodes(): UpdateNode(node['node_id'],{'hostname':node['hostname']})
    try:
        node_hrn = data["hrn"]
        if not node_hrn:
            raise Exception
    except:
        logger.log("Failed to read hrn from GetSlivers, using 'default' - *please upgrade PLCAPI*")
        node_hrn = "default   # Failed to read hrn from GetSlivers, please upgrade PLCAPI"

    for sliver in data["slivers"]:
        name = sliver["name"]
        sliver_pub_key_dir = os.path.join("/home", name, ".ssh/")
        sliver_private_key = os.path.join(sliver_pub_key_dir, "id_rsa")
        for chunk in sliver["attributes"]:
            if chunk["tagname"] == "omf_control":
                # scan all versions of omf-resctl
                etc_path = "/vservers/%s/etc/" % name
                pattern = etc_path + "omf-resctl-*/omf-resctl.yaml.in"
                templates = glob.glob(pattern)
                if not templates:
                    logger.log(
                        "WARNING: omf_resctl plugin, no template found for slice %s using pattern %s" % (name, pattern)
                    )
                    continue
                for template in templates:
                    # remove the .in extension
                    yaml = template[:-3]
                    # figure service name as subdir under etc/
                    service_name = os.path.split(template.replace(etc_path, ""))[0]
                    # read template and replace
                    template_contents = file(template).read()
                    yaml_contents = (
                        template_contents.replace("@XMPP_SERVER@", xmpp_server)
                        .replace("@NODE_HRN@", node_hrn)
                        .replace("@SLICE_NAME@", name)
                        .replace("@SLIVER_PRIVATE_KEY@", sliver_private_key)
                        .replace("@SLIVER_PUB_KEY_DIR@", sliver_pub_key_dir)
                    )
                    changes = tools.replace_file_with_string(yaml, yaml_contents)
                    logger.log("yaml_contents length=%d, changes=%r" % (len(yaml_contents), changes))
                    if changes:
                        sp = subprocess.Popen(
                            ["vserver", name, "exec", "service", service_name, "restart"],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                        )
                        (output, retcod) = sp.communicate()
                        logger.log("omf_resctl: %s: restarted resource controller (retcod=%r)" % (name, retcod))
                        logger.log("omf_resctl: got output\n%s" % output)
                    else:
                        logger.log("omf_resctl: %s: omf_control'ed sliver has no change" % name)