Exemple #1
0
 def __init__(self, data_loc):
     self.base_dir = data_loc
     if os.path.exists(os.path.join(self.base_dir, 'AI.db')):
         self.AISQL = AIdb.DB(os.path.join(self.base_dir, 'AI.db'))
     else:
         raise SystemExit(_("Error:\tNo AI.db database"))
     self.AISQL.verifyDBStructure()
Exemple #2
0
    def __init__(self, sname):
        '''
        Opens database for given service and sets database request queue
        '''
        self.name = sname
        try:
            self.service = AIService(sname)

        except VersionError as err:
            warn_version(err)
            raise

        path = self.service.database_path

        if os.path.exists(path):
            try:
                maisql = AIdb.DB(path)
                maisql.verifyDBStructure()
                self.aiqueue = maisql.getQueue()

            except StandardError as err:
                sys.stderr.write(
                    _('Error: AI database access error\n%s\n') % err)
                raise
        else:
            sys.stderr.write(
                _('Error: unable to locate AI database for "%s" '
                  'on server\n') % sname)
            # I can't read from service database and I should raise an error
            # for this condition.
            raise StandardError
Exemple #3
0
def do_delete_profile(cmd_options=None):
    ''' external entry point for installadm
    Arg: cmd_options - command line options
    Effect: delete profiles per command line
    '''
    # check for authorization and euid
    try:
        check_auth_and_euid(PROFILE_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    options = parse_options(cmd_options)

    # get AI service directory, database name
    service = AIService(options.service_name)
    dbname = service.database_path

    # Open the database
    aisql = AIdb.DB(dbname, commit=True)
    aisql.verifyDBStructure()

    # delete profiles per command line
    errs = delete_profiles(options.profile_name, aisql, AIdb.PROFILES_TABLE)
    if errs:
        sys.exit(1)
Exemple #4
0
def validate_internal(profile_list, database, table, image_dir):
    ''' given a list of profile files and the profile database and table,
        validate the list of profiles
    Args:
        profile_list - list of profile path names
        database - name of database
        table - name of database table
        image_dir - path of service image, used to locate service_bundle
    Returns True if all profiles are valid, return False if any are invalid
    '''
    # Open the database
    dbn = AIdb.DB(database, commit=True)
    dbn.verifyDBStructure()
    isvalid = True
    queue = dbn.getQueue()
    if not profile_list:
        profile_list = [None]
    for profile in profile_list:
        qstr = "SELECT name, file FROM %s WHERE name = %s" % \
                (table, AIdb.format_value('name', profile))
        query = AIdb.DBrequest(qstr, commit=True)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:  # database error
            return False  # give up
        if len(query.getResponse()) == 0:
            print >> sys.stderr, \
                    _('No profiles in database with basename ') + profile
            isvalid = False
            continue  # to the next profile
        for response in query.getResponse():
            if not df.validate_file(response[0], response[1], image_dir):
                isvalid = False
    return isvalid
Exemple #5
0
def do_delete_manifest(cmd_options=None):
    '''
    Delete a manifest from an install service.

    '''
    # check for authorization and euid
    try:
        check_auth_and_euid(MANIFEST_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    options = parse_options(cmd_options)

    if not os.path.exists(os.path.join(options.svcdir_path, "AI.db")):
        raise SystemExit(_("Error: Need a valid AI service directory"))

    aisql = AIdb.DB(os.path.join(options.svcdir_path, 'AI.db'), commit=True)
    aisql.verifyDBStructure()
    try:
        delete_manifest_from_db(aisql,
                                (options.manifest_name, options.instance),
                                options.service_name,
                                options.svcdir_path)
    except ValueError as error:
        raise SystemExit(error)
Exemple #6
0
def send_needed_criteria(port):
    '''Replies to the old client with the needed criteria

    Args
        port - the originating port for the old client

    Returns
        None

    Raises
        None
    
    '''
    # Establish the service SQL database based upon the
    # port number for the service
    path = os.path.join(com.AI_SERVICE_DIR_PATH, str(port), 'AI.db')
    if os.path.exists(path):
        try:
            aisql = AIdb.DB(path)
            aisql.verifyDBStructure()
        except StandardError as err:
            # internal error, record the error in the server error_log
            sys.stderr.write(_('error:AI database access error\n%s\n') % err)
            # report the error to the requesting client
            print "Content-Type: text/html"  # HTML is following
            print  # blank line, end of headers
            sys.stdout.write(_("error:AI database access error\n%s\n") % err)
            sys.exit(1)
    else:
        # not an internal error, report to the requesting client only
        print "Content-Type: text/html"  # HTML is following
        print  # blank line, end of headers
        print _("Error:unable to determine criteria "
                "for service associated with port"), port
        return

    # build the required criteria list
    xml = lxml.etree.Element("CriteriaList")
    # old version number
    version_value = lxml.etree.Element("Version")
    version_value.attrib["Number"] = COMPATIBILITY_VERSION
    xml.append(version_value)
    # pull the required criteria from the SQL database
    for crit in AIdb.getCriteria(aisql.getQueue(), strip=True):
        tag = lxml.etree.Element("Criteria")
        tag.attrib["Name"] = crit
        xml.append(tag)
    xmlstr = lxml.etree.tostring(xml, pretty_print=True)

    # report the results
    print "Content-Length:", len(xmlstr)  # Length of XML reply
    print "Content-Type: text/xml"  # XML is following
    print  # blank line, end of headers
    print xmlstr
Exemple #7
0
def do_export_profile(options):
    '''
    Export a profile.
    '''
    save_errno = 0

    # Open the database
    aisql = AIdb.DB(options.service.database_path, commit=True)
    aisql.verifyDBStructure()

    queue = aisql.getQueue()
    for pname in options.pnames:
        # sanitize and format for SELECT
        fmtname = AIdb.format_value('name', pname)
        q_str = "SELECT file FROM  " + AIdb.PROFILES_TABLE + \
                " WHERE name=" + fmtname
        query = AIdb.DBrequest(q_str)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:
            continue
        if len(query.getResponse()) == 0:
            print >> sys.stderr, _("Profile %s not found.") % fmtname
            continue
        for row in query.getResponse():
            profpath = row['file']

            if options.output_isdir:
                output_name = "/".join([options.output_name, pname])
            else:
                output_name = options.output_name

            if output_name == SCREEN and options.file_count > 1:
                display_file_header(_("profile: ") + pname)

            try:
                shutil.copyfile(profpath, output_name)
            except IOError as err:
                print >> sys.stderr, _(
                    "Error exporting profile: "
                    "%(error)s: %(file)s") % ({
                        "error": err.strerror,
                        "file": err.filename
                    })
                save_errno = err.errno
            print
    return save_errno
Exemple #8
0
 def open_database(self, db_file):
     """
     Sets self._db (opens database object) and errors if already set or file
     does not yet exist
     Args: A file path to an SQLite3 database
     Raises: SystemExit if path does not exist,
             AssertionError if self._db is already set
     Returns: Nothing
     """
     if not os.path.exists(db_file):
         raise SystemExit(_("Error:\tFile %s is not a valid database "
                            "file") % db_file)
     elif self._db is None:
         self._db = AIdb.DB(db_file, commit=True)
     else:
         raise AssertionError('Opening database when already open!')
def do_delete_profile(cmd_options=None):
    ''' external entry point for installadm
    Arg: cmd_options - command line options
    Effect: delete profiles per command line
    '''
    options = parse_options(cmd_options)

    # get AI service directory, database name
    service = AIService(options.service_name)
    dbname = service.database_path

    # Open the database
    aisql = AIdb.DB(dbname, commit=True)
    aisql.verifyDBStructure()

    # delete profiles per command line
    errs = delete_profiles(options.profile_name, aisql, AIdb.PROFILES_TABLE)
    if errs:
        sys.exit(1)
Exemple #10
0
    def setUpClass(cls):
        '''unit test set up'''
        dbname = tempfile.NamedTemporaryFile(dir="/tmp", delete=False)
        cls.dbname = dbname.name
        cls.db = sqlite3.connect(dbname.name, isolation_level=None)

        # create db
        cls.db.execute("CREATE TABLE manifests("
                       "name TEXT, instance INTEGER, arch TEXT,"
                       "MINmac INTEGER, MAXmac INTEGER, MINipv4 INTEGER,"
                       "MAXipv4 INTEGER, cpu TEXT, platform TEXT, "
                       "MINnetwork INTEGER, MAXnetwork INTEGER,"
                       "MINmem INTEGER, MAXmem INTEGER)")

        #  add manifests to db
        cls.db.execute(
            "INSERT INTO manifests VALUES"
            "('mac_ipv4_man',0,NULL,x'AABBCCDDEEFF',x'AABBCCDDEEFF',"
            "020000000025,020000000025,NULL,NULL,NULL,NULL,NULL,NULL)")
        cls.db.execute(
            "INSERT INTO manifests VALUES"
            "('mac_min_unbound',0,NULL,x'AABBCCDDEEFF',x'AABBCCDDEEFF',"
            "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('ipv4_max_unbound',0,NULL,NULL,NULL,"
                       "020000000025,NULL,NULL,NULL,NULL,NULL,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('platform_man',0,NULL,NULL,NULL,"
                       "NULL,NULL,NULL,'myplatform',NULL,NULL,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('arch_man',0,'i86pc',NULL,NULL,"
                       "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('cpu_man',0,NULL,NULL,NULL,"
                       "NULL,NULL,'i386',NULL,NULL,NULL,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('network_man',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,"
                       "010000002000,010000002000,NULL,NULL)")
        cls.db.execute("INSERT INTO manifests VALUES"
                       "('mem_min_unbound',0,NULL,NULL,NULL,"
                       "NULL,NULL,NULL,NULL,NULL,NULL,NULL,2048)")
        cls.aidb = AIdb.DB(cls.dbname, commit=True)
def do_delete_manifest(cmd_options=None):
    '''
    Delete a manifest from an install service.

    '''
    # check that we are root
    if os.geteuid() != 0:
        raise SystemExit(_("Error: Root privileges are required for "
                           "this command."))

    options = parse_options(cmd_options)

    if not os.path.exists(os.path.join(options.svcdir_path, "AI.db")):
        raise SystemExit(_("Error: Need a valid AI service directory"))

    aisql = AIdb.DB(os.path.join(options.svcdir_path, 'AI.db'), commit=True)
    aisql.verifyDBStructure()
    try:
        delete_manifest_from_db(aisql,
                                (options.manifest_name, options.instance),
                                options.service_name,
                                options.svcdir_path)
    except ValueError as error:
        raise SystemExit(error)
def get_manifest_or_profile_names(services, dbtable):
    """
    Iterate through the services retrieving
    all the stored manifest or profile names.

    Args
        services = dictionary of service properties
        dbtable = database table, distinguishing manifests from profiles

    Returns
        a dictionary of service manifests or profiles within a list:

            {
                servicename1:
                    [
                        [name, has_criteria (boolean), {crit:value, ... }],
                        ... 
                    ],
                ...
            }

        the width of the longest service name (swidth)

        the width of the longest manifest name (mwidth)

        the width of the longest criteria (cwidth)

    Raises
        None
    """
    swidth = 0
    mwidth = 0
    cwidth = 0
    sdict = dict()
    for sname in sorted(services.keys()):
        try:
            service = AIService(sname)
        except VersionError as err:
            warn_version(err)
            continue

        path = service.database_path

        if os.path.exists(path):
            try:
                maisql = AIdb.DB(path)
                maisql.verifyDBStructure()
                aiqueue = maisql.getQueue()
                swidth = max(len(sname), swidth)
                if not AIdb.tableExists(aiqueue, dbtable):
                    continue
                for name in AIdb.getNames(aiqueue, dbtable):
                    mwidth = max(len(name), mwidth)
                    tdict = dict()
                    if dbtable == 'manifests':
                        instances = AIdb.numInstances(name, aiqueue)
                        for instance in range(0, instances):
                            criteria = AIdb.getTableCriteria(name,
                                                             instance,
                                                             aiqueue,
                                                             dbtable,
                                                             humanOutput=False,
                                                             onlyUsed=True)
                            has_criteria = False
                            if criteria is not None:
                                for key in criteria.keys():
                                    if criteria[key] is not None:
                                        has_criteria = True
                                        break
                                if has_criteria:
                                    # We need criteria in human readable form
                                    hrcrit = AIdb.getTableCriteria(
                                        name,
                                        instance,
                                        aiqueue,
                                        dbtable,
                                        humanOutput=True,
                                        onlyUsed=True)
                                    tdict, twidth = get_criteria_info(hrcrit)
                                    cwidth = max(twidth, cwidth)
                    else:
                        criteria = AIdb.getTableCriteria(name,
                                                         None,
                                                         aiqueue,
                                                         dbtable,
                                                         humanOutput=False,
                                                         onlyUsed=True)
                        has_criteria = False
                        if criteria is not None:
                            for key in criteria.keys():
                                if criteria[key] is not None:
                                    has_criteria = True
                                    break
                    if sname in sdict:
                        slist = sdict[sname]
                        slist.append([name, has_criteria, tdict])
                        sdict[sname] = slist
                    else:
                        sdict[sname] = [[name, has_criteria, tdict]]
            except StandardError as err:
                sys.stderr.write(
                    _('Error: AI database access error\n%s\n') % err)
                continue
        else:
            sys.stderr.write(
                _('Error: unable to locate AI database for "%s" '
                  'on server\n') % sname)
            continue

    return sdict, swidth, mwidth, cwidth
Exemple #13
0
def do_update_profile(cmd_options=None):
    ''' Updates exisiting profile
    Arg: cmd_options - command line options
    Effect: update existing profile 
    Raises SystemExit if condition cannot be handled
    '''
    # check for authorization and euid
    try:
        check_auth_and_euid(PROFILE_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    options = parse_options(DO_UPDATE, cmd_options)

    # verify the file
    profile_file = options.profile_file[0]
    if not os.path.exists(profile_file):
        raise SystemExit(_("Error:\tFile does not exist: %s\n") % profile_file)

    # get profile name
    if not options.profile_name:
        profile_name = os.path.basename(profile_file)
    else:
        profile_name = options.profile_name

    # get AI service image path and database name
    service = AIService(options.service_name)
    dbname = service.database_path
    image_dir = service.image.path

    # open database
    dbn = AIdb.DB(dbname, commit=True)
    dbn.verifyDBStructure()
    queue = dbn.getQueue()

    # Handle old DB versions which did not store a profile.
    if not AIdb.tableExists(queue, AIdb.PROFILES_TABLE):
        raise SystemExit(
            _("Error:\tService %s does not support profiles") %
            options.service_name)

    # check for the existence of profile
    missing_profile_error = _("Error:\tService {service} has no profile "
                              "named {profile}.")
    if not sc.is_name_in_table(profile_name, queue, AIdb.PROFILES_TABLE):
        raise SystemExit(
            missing_profile_error.format(service=options.service_name,
                                         profile=profile_name))

    # validates the profile and report the errors if found
    raw_profile = df.validate_file(profile_name,
                                   profile_file,
                                   image_dir,
                                   verbose=False)
    if not raw_profile:
        raise SystemExit(1)

    # create file from string and report failures
    tmp_profile_path = copy_profile_internally(raw_profile)
    if not tmp_profile_path:
        raise SystemExit(1)

    # get the path of profile in db
    q_str = "SELECT file FROM " + AIdb.PROFILES_TABLE + " WHERE name=" \
                + AIdb.format_value('name', profile_name)
    query = AIdb.DBrequest(q_str)
    queue.put(query)
    query.waitAns()
    response = query.getResponse()
    # database error
    if response is None:
        raise SystemExit(
            missing_profile_error.format(service=options.service_name,
                                         profile=profile_name))

    db_profile_path = response[0][0]

    # replace the file
    try:
        shutil.copyfile(tmp_profile_path, db_profile_path)
    except IOError as err:
        raise SystemExit(
            _("Error writing profile %(profile)s: %(err)s") % {
                'profile': profile_name,
                'err': err
            })
    finally:
        os.unlink(tmp_profile_path)

    print >> sys.stderr, _("Profile updated successfully.")
Exemple #14
0
def do_create_profile(cmd_options=None):
    ''' external entry point for installadm
    Arg: cmd_options - command line options
    Effect: add profiles to database per command line
    Raises SystemExit if condition cannot be handled
    '''
    # check for authorization and euid
    try:
        check_auth_and_euid(PROFILE_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    options = parse_options(DO_CREATE, cmd_options)

    # get AI service image path and database name
    service = AIService(options.service_name)
    image_dir = service.image.path
    dbname = service.database_path

    # open database
    dbn = AIdb.DB(dbname, commit=True)
    dbn.verifyDBStructure()
    queue = dbn.getQueue()
    root = None
    criteria_dict = dict()

    # Handle old DB versions which did not store a profile.
    if not AIdb.tableExists(queue, AIdb.PROFILES_TABLE):
        raise SystemExit(
            _("Error:\tService %s does not support profiles") %
            options.service_name)
    try:
        if options.criteria_file:  # extract criteria from file
            root = df.verifyCriteria(df.DataFiles.criteriaSchema,
                                     options.criteria_file, dbn,
                                     AIdb.PROFILES_TABLE)
        elif options.criteria_c:
            # if we have criteria from cmd line, convert into dictionary
            criteria_dict = pub_man.criteria_to_dict(options.criteria_c)
            root = df.verifyCriteriaDict(df.DataFiles.criteriaSchema,
                                         criteria_dict, dbn,
                                         AIdb.PROFILES_TABLE)
    except ValueError as err:
        raise SystemExit(_("Error:\tcriteria error: %s") % err)
    # Instantiate a Criteria object with the XML DOM of the criteria.
    criteria = df.Criteria(root)
    sc.validate_criteria_from_user(criteria, dbn, AIdb.PROFILES_TABLE)
    # track exit status for all profiles, assuming no errors
    has_errors = False

    # loop through each profile on command line
    for profile_file in options.profile_file:
        # take option name either from command line or from basename of profile
        if options.profile_name:
            profile_name = options.profile_name
        else:
            profile_name = os.path.basename(profile_file)
        # check for any scope violations
        if sc.is_name_in_table(profile_name, queue, AIdb.PROFILES_TABLE):
            print >> sys.stderr, \
                    _("Error:  A profile named %(name)s is already in the "
                      "database for service %(service)s.") % \
                      {'name': profile_name, 'service': options.service_name}
            has_errors = True
            continue
        # open profile file specified by user on command line
        if not os.path.exists(profile_file):
            print >> sys.stderr, _("File %s does not exist") % profile_file
            has_errors = True
            continue

        # validates the profile and report errors if found
        raw_profile = df.validate_file(profile_name,
                                       profile_file,
                                       image_dir,
                                       verbose=False)
        if not raw_profile:
            has_errors = True
            continue

        # create file from profile string and report failures
        full_profile_path = copy_profile_internally(raw_profile)
        if not full_profile_path:
            has_errors = True
            continue

        # add new profile to database
        if not add_profile(criteria, profile_name, full_profile_path, queue,
                           AIdb.PROFILES_TABLE):
            os.unlink(full_profile_path)  # failure, back out internal profile
            has_errors = True
    # exit with status if any errors in any profiles
    if has_errors:
        sys.exit(1)
Exemple #15
0
    def get_service_manifests(sname, linst):
        """
        Iterate through all the manifests for the named service (sname)
        pointed to by the SCF service. 

        Args
            sname = service name
            inst = smf.AISCF()

        Returns
            a dictionary of the criteria for the named service within a list:

                {
                    servicename1:[
                                 { 'arch':arch1, 'mem':memory1, 'ipv4':ipaddress1,
                                   'mac':macaddr1, 'platform':platform1, 'network':network1
                                   'cpu':cpu1 },
                                 ...
                                ]
                }
            
            * Note1: platform, network and cpu are currently not-implemented upstream.
            * Note2: could simply use a list of dictionaries but implemented as a 
                     dictionary of a list of dictionary which will allow for multiple 
                     services to be listed at the same time.

            width of longest manifest name

	    width of longest criteria

        Raises
            None
        """
        sdict = {}
        width = 0
        cwidth = 0
        # ensure the named service is in our service dictionary.
        lservices = linst.services.keys()
        if sname in lservices:
            serv = smf.AIservice(linst, sname)
            if not has_key(serv, 'txt_record'):
                sys.stderr.write(_('%s: error: SMF service key '
                                   'property does not exist\n') % \
                                os.path.basename(sys.argv[0]))
                sys.exit(1)

            port = serv['txt_record'].split(':')[-1]
            path = os.path.join('/var/ai', str(port), 'AI.db')
            if os.path.exists(path):
                try:
                    maisql = AIdb.DB(path)
                    maisql.verifyDBStructure()
                    aiqueue = maisql.getQueue()
                    for name in AIdb.getManNames(aiqueue):
                        sdict[name] = []
                        instances = AIdb.numInstances(name, aiqueue)
                        for instance in range(0, instances):
                            criteria = AIdb.getManifestCriteria(name, 
                                            instance, aiqueue, 
                                            humanOutput = True, 
                                            onlyUsed = True)
    
                            width = max(len(name), width)
                            tdict, twidth = get_criteria_info(criteria)
                            cwidth = max(twidth, cwidth)

                            sdict[name].extend([tdict])

                except Exception, err:
                    sys.stderr.write(_('%s: error: AI database access '
                                       'error\n%s\n') % \
                                (os.path.basename(sys.argv[0]), err))
                    sys.exit(1)
            else: 
                sys.stderr.write(_('%s: error: unable to locate '
                                   'AI database on server for %s\n') % \
                                (os.path.basename(sys.argv[0]), sname))
                sys.exit(1)
Exemple #16
0
    def get_manifest_names(linst):
        """
        Iterate through the services from smf.AISCF() retrieving
        all the stored manifest names.

        Args
            inst = smf.AISCF()

        Returns
            a dictionary of service manifests within a list:

                {
                    servicename1:[ manifest1, manifest2, ...],
                    ...
                }

            the width of the longest service name

        Raises
            None
        """
        width = 0
        sdict = {}
        lservices = linst.services.keys()
        lservices.sort()
        for akey in lservices:
            serv = smf.AIservice(linst, akey)
            # ensure that the current service has the keys we need.
            # if not then continue with the next service.
            if not (has_key(serv, 'service_name') and
                    has_key(serv, 'txt_record')):
                sys.stderr.write(_('%s: error: SMF service key '
                                   'property does not exist\n') %
                                os.path.basename(sys.argv[0]))
                sys.exit(1)

            sname = serv['service_name']
            port = serv['txt_record'].split(':')[-1]
            path = os.path.join('/var/ai', str(port), 'AI.db')
            if os.path.exists(path):
                try:
                    maisql = AIdb.DB(path)
                    maisql.verifyDBStructure()
                    for name in AIdb.getManNames(maisql.getQueue()):
                        width = max(len(sname), width)
                        if sdict.has_key(sname):
                            slist = sdict[sname]
                            slist.extend([name])
                            sdict[sname] = slist
                        else:
                            sdict[sname] = [name]
                except Exception, err:
                    sys.stderr.write(_('%s: error: AI database '
                                       'access error\n%s\n') % \
                                (os.path.basename(sys.argv[0]), err))
                    sys.exit(1)
            else:
                sys.stderr.write(_('%s: error: unable to locate '
                                   'AI database on server\n') % \
                                os.path.basename(sys.argv[0]))
                sys.exit(1)
Exemple #17
0
def do_set_criteria(cmd_options=None):
    '''
    Modify the criteria associated with a manifest.

    '''
    # check that we are root
    if os.geteuid() != 0:
        raise SystemExit(
            _("Error: Root privileges are required for "
              "this command."))

    options = parse_options(cmd_options)

    # Get the install service's properties.
    if not config.is_service(options.service_name):
        raise SystemExit(_("Failed to find service %s") % options.service_name)

    service = AIService(options.service_name)
    database = service.database_path

    # Open the database
    dbn = AIdb.DB(database, commit=True)

    # Check to make sure that the manifest whose criteria we're
    # updating exists in the install service.
    if (options.manifest_name and
            not check_published_manifest(service, dbn, options.manifest_name)):
        raise SystemExit(1)

    # Process and validate criteria from -a, -c, or -C, and store
    # store the criteria in a Criteria object.
    try:
        if options.criteria_file:
            root = df.verifyCriteria(df.DataFiles.criteriaSchema,
                                     options.criteria_file, dbn,
                                     AIdb.MANIFESTS_TABLE)
        elif options.criteria_a:
            criteria_dict = pub_man.criteria_to_dict(options.criteria_a)
            root = df.verifyCriteriaDict(df.DataFiles.criteriaSchema,
                                         criteria_dict, dbn,
                                         AIdb.MANIFESTS_TABLE)
        elif options.criteria_c:
            criteria_dict = pub_man.criteria_to_dict(options.criteria_c)
            root = df.verifyCriteriaDict(df.DataFiles.criteriaSchema,
                                         criteria_dict, dbn,
                                         AIdb.MANIFESTS_TABLE)
        else:
            raise SystemExit("Error: Missing required criteria.")

    except (AssertionError, IOError, ValueError) as err:
        raise SystemExit(err)
    except (lxml.etree.LxmlError) as err:
        raise SystemExit(_("Error:\tmanifest error: %s") % err)

    # Instantiate a Criteria object with the XML DOM of the criteria.
    criteria = df.Criteria(root)

    if options.manifest_name:
        # Ensure the criteria we're adding/setting for this manifest doesn't
        # cause a criteria collision in the DB.
        colliding_criteria = pub_man.find_colliding_criteria(
            criteria, dbn, exclude_manifests=[options.manifest_name])
        # If we're appending criteria pass the manifest name
        if options.criteria_a:
            pub_man.find_colliding_manifests(
                criteria,
                dbn,
                colliding_criteria,
                append_manifest=options.manifest_name)
        else:
            pub_man.find_colliding_manifests(criteria,
                                             dbn,
                                             colliding_criteria,
                                             append_manifest=None)
    # validate criteria for profile
    for pname in options.profile_name:
        if not sc.is_name_in_table(pname, dbn.getQueue(), AIdb.PROFILES_TABLE):
            raise SystemExit(
                _("Error:\tservice has no profile named %s." % pname))
        # Validate profile criteria
        sc.validate_criteria_from_user(criteria, dbn, AIdb.PROFILES_TABLE)

    # all validation complete - update database

    # indicate whether criteria are added or replaced
    if options.criteria_a:
        append = True  # add new criteria
    else:
        append = False  # replace any existing criteria with new
    if options.manifest_name:
        # Update the criteria for manifest
        set_criteria(criteria, options.manifest_name, dbn,
                     AIdb.MANIFESTS_TABLE, append)
        print >> sys.stderr, _("Criteria updated for manifest %s.") % \
                options.manifest_name
    for pname in options.profile_name:
        # Update the criteria for profile
        set_criteria(criteria, pname, dbn, AIdb.PROFILES_TABLE, append)
        print >> sys.stderr, _("Criteria updated for profile %s.") % pname
Exemple #18
0
def send_manifest(form_data,
                  port=0,
                  servicename=None,
                  protocolversion=COMPATIBILITY_VERSION,
                  no_default=False):
    '''Replies to the client with matching service for a service.
    
    Args
        form_data   - the postData passed in from the client request
        port        - the port of the old client
        servicename - the name of the service being used
        protocolversion - the version of the AI service RE: handshake
        no_default  - boolean flag to signify whether or not we should hand
                      back the default manifest and profiles if one cannot
                      be matched based on the client criteria.

    Returns
        None
    
    Raises
        None
    
    '''
    # figure out the appropriate path for the AI database,
    # and get service name if necessary.
    # currently service information is stored in a port directory.
    # When the cherrypy webserver new service directories should be
    # separated via service-name only.  Old services will still use
    # port numbers as the separation mechanism.
    path = None
    found_servicename = None
    service = None
    port = str(port)

    if servicename:
        service = AIService(servicename)
        path = service.database_path
    else:
        for name in config.get_all_service_names():
            if config.get_service_port(name) == port:
                found_servicename = name
                service = AIService(name)
                path = service.database_path
                break

    # Check to insure that a valid path was found
    if not path or not os.path.exists(path):
        print 'Content-Type: text/html'  # HTML is following
        print  # blank line, end of headers
        if servicename:
            print '<pre><b>Error</b>:unable to find<i>', servicename + '</i>.'
        else:
            print '<pre><b>Error</b>:unable to find<i>', port + '</i>.'
        print 'Available services are:<p><ol><i>'
        hostname = socket.gethostname()
        for name in config.get_all_service_names():
            port = config.get_service_port(name)
            sys.stdout.write(
                '<a href="http://%s:%d/cgi-bin/'
                'cgi_get_manifest.py?version=%s&service=%s">%s</a><br>\n' %
                (hostname, port, VERSION, name, name))
        print '</i></ol>Please select a service from the above list.'
        return

    if found_servicename:
        servicename = found_servicename

    # load to the AI database
    aisql = AIdb.DB(path)
    aisql.verifyDBStructure()

    # convert the form data into a criteria dictionary
    criteria = dict()
    orig_data = form_data
    while form_data:
        try:
            [key_value, form_data] = form_data.split(';', 1)
        except (ValueError, NameError, TypeError, KeyError):
            key_value = form_data
            form_data = ''
        try:
            [key, value] = key_value.split('=')
            criteria[key] = value
        except (ValueError, NameError, TypeError, KeyError):
            criteria = dict()

    # Generate templating dictionary from criteria
    template_dict = dict()
    for crit in criteria:
        template_dict["AI_" + crit.upper()] = \
                AIdb.formatValue(crit, criteria[crit], units=False)

    # find the appropriate manifest
    try:
        manifest = AIdb.findManifest(criteria, aisql)
    except StandardError as err:
        print 'Content-Type: text/html'  # HTML is following
        print  # blank line, end of headers
        print '<pre><b>Error</b>:findManifest criteria<br>'
        print err, '<br>'
        print '<ol>servicename =', servicename
        print 'port        =', port
        print 'path        =', path
        print 'form_data   =', orig_data
        print 'criteria    =', criteria
        print 'servicename found by port =', found_servicename, '</ol>'
        print '</pre>'
        return

    # check if findManifest() returned a number equal to 0
    # (means we got no manifests back -- thus we serve the default if desired)
    if manifest is None and not no_default:
        manifest = service.get_default_manifest()

    # if we have a manifest to return, prepare its return
    if manifest is not None:
        try:
            # construct the fully qualified filename
            filename = os.path.abspath(
                os.path.join(service.manifest_dir, manifest))
            # open and read the manifest
            with open(filename, 'rb') as mfp:
                manifest_str = mfp.read()
            # maintain compability with older AI client
            if servicename is None or \
                    float(protocolversion) < float(PROFILES_VERSION):
                content_type = mimetypes.types_map.get('.xml', 'text/plain')
                print 'Content-Length:', len(
                    manifest_str)  # Length of the file
                print 'Content-Type:', content_type  # XML is following
                print  # blank line, end of headers
                print manifest_str
                logging.info('Manifest sent from %s.' % filename)
                return

        except OSError as err:
            print 'Content-Type: text/html'  # HTML is following
            print  # blank line, end of headers
            print '<pre>'
            # report the internal error to error_log and requesting client
            sys.stderr.write(_('error:manifest (%s) %s\n') % \
                            (str(manifest), err))
            sys.stdout.write(_('error:manifest (%s) %s\n') % \
                            (str(manifest), err))
            print '</pre>'
            return

    # get AI service image path
    service = AIService(servicename)
    image_dir = service.image.path
    # construct object to contain MIME multipart message
    outermime = MIMEMultipart()
    client_msg = list()  # accumulate message output for AI client

    # If we have a manifest, attach it to the return message
    if manifest is not None:
        # add manifest as attachment
        msg = MIMEText(manifest_str, 'xml')
        # indicate manifest using special name
        msg.add_header('Content-Disposition',
                       'attachment',
                       filename=sc.AI_MANIFEST_ATTACHMENT_NAME)
        outermime.attach(msg)  # add manifest as an attachment

    # search for any profiles matching client criteria
    # formulate database query to profiles table
    q_str = "SELECT DISTINCT name, file FROM " + \
        AIdb.PROFILES_TABLE + " WHERE "
    nvpairs = list()  # accumulate criteria values from post-data
    # for all AI client criteria
    for crit in AIdb.getCriteria(aisql.getQueue(),
                                 table=AIdb.PROFILES_TABLE,
                                 onlyUsed=False):
        if crit not in criteria:
            msgtxt = _("Warning: client criteria \"%s\" not provided in "
                       "request.  Setting value to NULL for profile lookup.") \
                       % crit
            client_msg += [msgtxt]
            logging.warn(msgtxt)
            # fetch only global profiles destined for all clients
            if AIdb.isRangeCriteria(aisql.getQueue(), crit,
                                    AIdb.PROFILES_TABLE):
                nvpairs += ["MIN" + crit + " IS NULL"]
                nvpairs += ["MAX" + crit + " IS NULL"]
            else:
                nvpairs += [crit + " IS NULL"]
            continue

        # prepare criteria value to add to query
        envval = AIdb.sanitizeSQL(criteria[crit])
        if AIdb.isRangeCriteria(aisql.getQueue(), crit, AIdb.PROFILES_TABLE):
            # If no default profiles are requested, then we mustn't allow
            # this criteria to be NULL.  It must match the client's given
            # value for this criteria.
            if no_default:
                if crit == "mac":
                    nvpairs += ["(HEX(MIN" + crit + ")<=HEX(X'" + envval + \
                        "'))"]

                    nvpairs += ["(HEX(MAX" + crit + ")>=HEX(X'" + envval + \
                        "'))"]
                else:
                    nvpairs += ["(MIN" + crit + "<='" + envval + "')"]
                    nvpairs += ["(MAX" + crit + ">='" + envval + "')"]
            else:
                if crit == "mac":
                    nvpairs += [
                        "(MIN" + crit + " IS NULL OR "
                        "HEX(MIN" + crit + ")<=HEX(X'" + envval + "'))"
                    ]
                    nvpairs += [
                        "(MAX" + crit + " IS NULL OR HEX(MAX" + crit +
                        ")>=HEX(X'" + envval + "'))"
                    ]
                else:
                    nvpairs += [
                        "(MIN" + crit + " IS NULL OR MIN" + crit + "<='" +
                        envval + "')"
                    ]
                    nvpairs += [
                        "(MAX" + crit + " IS NULL OR MAX" + crit + ">='" +
                        envval + "')"
                    ]
        else:
            # If no default profiles are requested, then we mustn't allow
            # this criteria to be NULL.  It must match the client's given
            # value for this criteria.
            #
            # Also, since this is a non-range criteria, the value stored
            # in the DB may be a whitespace separated list of single
            # values.  We use a special user-defined function in the
            # determine if the given criteria is in that textual list.
            if no_default:
                nvpairs += ["(is_in_list('" + crit + "', '" + envval + \
                    "', " + crit + ", 'None') == 1)"]
            else:
                nvpairs += ["(" + crit + " IS NULL OR is_in_list('" + crit + \
                    "', '" + envval + "', " + crit + ", 'None') == 1)"]

    if len(nvpairs) > 0:
        q_str += " AND ".join(nvpairs)

        # issue database query
        logging.info("Profile query: " + q_str)
        query = AIdb.DBrequest(q_str)
        aisql.getQueue().put(query)
        query.waitAns()
        if query.getResponse() is None or len(query.getResponse()) == 0:
            msgtxt = _("No profiles found.")
            client_msg += [msgtxt]
            logging.info(msgtxt)
        else:
            for row in query.getResponse():
                profpath = row['file']
                profname = row['name']
                if profname is None:  # should not happen
                    profname = 'unnamed'
                try:
                    if profpath is None:
                        msgtxt = "Database record error - profile path is " \
                            "empty."
                        client_msg += [msgtxt]
                        logging.error(msgtxt)
                        continue
                    msgtxt = _('Processing profile %s') % profname
                    client_msg += [msgtxt]
                    logging.info(msgtxt)
                    with open(profpath, 'r') as pfp:
                        raw_profile = pfp.read()
                    # do any template variable replacement {{AI_xxx}}
                    tmpl_profile = sc.perform_templating(
                        raw_profile, template_dict)
                    # precautionary validation of profile, logging only
                    sc.validate_profile_string(tmpl_profile,
                                               image_dir,
                                               dtd_validation=True,
                                               warn_if_dtd_missing=True)
                except IOError as err:
                    msgtxt = _("Error:  I/O error: ") + str(err)
                    client_msg += [msgtxt]
                    logging.error(msgtxt)
                    continue
                except OSError:
                    msgtxt = _("Error:  OS error on profile ") + profpath
                    client_msg += [msgtxt]
                    logging.error(msgtxt)
                    continue
                except KeyError:
                    msgtxt = _('Error:  could not find criteria to substitute '
                               'in template: ') + profpath
                    client_msg += [msgtxt]
                    logging.error(msgtxt)
                    logging.error('Profile with template substitution error:' +
                                  raw_profile)
                    continue
                except lxml.etree.XMLSyntaxError as err:
                    # log validation error and proceed
                    msgtxt = _(
                            'Warning:  syntax error found in profile: ') \
                            + profpath
                    client_msg += [msgtxt]
                    logging.error(msgtxt)
                    for error in err.error_log:
                        msgtxt = _('Error:  ') + error.message
                        client_msg += [msgtxt]
                        logging.error(msgtxt)
                    logging.info([
                        _('Profile failing validation:  ') +
                        lxml.etree.tostring(root)
                    ])
                # build MIME message and attach to outer MIME message
                msg = MIMEText(tmpl_profile, 'xml')
                # indicate in header that this is an attachment
                msg.add_header('Content-Disposition',
                               'attachment',
                               filename=profname)
                # attach this profile to the manifest and any other profiles
                outermime.attach(msg)
                msgtxt = _('Parsed and loaded profile: ') + profname
                client_msg += [msgtxt]
                logging.info(msgtxt)

    # any profiles and AI manifest have been attached to MIME message
    # specially format list of messages for display on AI client console
    if client_msg:
        outtxt = ''
        for msgtxt in client_msg:
            msgtxt = _('SC profile locator:') + msgtxt
            outtxt += str(msgtxt) + '\n'
        # add AI client console messages as single plain text attachment
        msg = MIMEText(outtxt, 'plain')  # create MIME message
        outermime.attach(msg)  # attach MIME message to response

    print outermime.as_string()  # send MIME-formatted message
Exemple #19
0
def list_manifests(service):
    '''Replies to the client with criteria list for a service.
       The output should be similar to installadm list.

    Args
        service - the name of the service being listed

    Returns
        None

    Raises
        None
    '''
    print 'Content-Type: text/html'  # HTML is following
    print  # blank line, end of headers
    print '<html>'
    print '<head>'
    sys.stdout.write('<title>%s %s</title>' %
                     (_('Manifest list for'), service))
    print '</head><body>'

    port = 0
    try:
        smf.AISCF(FMRI="system/install/server")
    except KeyError:
        # report the internal error to error_log and requesting client
        sys.stderr.write(
            _("error:The system does not have the "
              "system/install/server SMF service."))
        sys.stdout.write(
            _("error:The system does not have the "
              "system/install/server SMF service."))
        return
    services = config.get_all_service_names()
    if not services:
        # report the error to the requesting client only
        sys.stdout.write(_('error:no services on this server.\n'))
        return

    found = False
    if config.is_service(service):
        service_ctrl = AIService(service)
        found = True

        # assume new service setup
        path = service_ctrl.database_path
        if os.path.exists(path):
            try:
                aisql = AIdb.DB(path)
                aisql.verifyDBStructure()
            except StandardError as err:
                # report the internal error to error_log and
                # requesting client
                sys.stderr.write(
                    _('error:AI database access '
                      'error\n%s\n') % err)
                sys.stdout.write(
                    _('error:AI database access '
                      'error\n%s\n') % err)
                return

            # generate the list of criteria for the criteria table header
            criteria_header = E.TR()
            for crit in AIdb.getCriteria(aisql.getQueue(), strip=False):
                criteria_header.append(E.TH(crit))

            # generate the manifest rows for the criteria table body
            names = AIdb.getManNames(aisql.getQueue())
            table_body = E.TR()
            allcrit = AIdb.getCriteria(aisql.getQueue(), strip=False)
            colspan = str(max(len(list(allcrit)), 1))
            for manifest in names:

                # iterate through each manifest (and instance)
                for instance in range(
                        0, AIdb.numInstances(manifest, aisql.getQueue())):

                    table_body.append(E.TR())
                    # print the manifest name only once (from instance 0)
                    if instance == 0:
                        href = '../' + service + '/' + manifest
                        row = str(AIdb.numInstances(manifest,
                                                    aisql.getQueue()))
                        table_body.append(
                            E.TD(E.A(manifest, href=href, rowspan=row)))
                    else:
                        table_body.append(E.TD())

                    crit_pairs = AIdb.getManifestCriteria(manifest,
                                                          instance,
                                                          aisql.getQueue(),
                                                          onlyUsed=True,
                                                          humanOutput=True)

                    # crit_pairs is an SQLite3 row object which doesn't
                    # support iteritems(), etc.
                    for crit in crit_pairs.keys():
                        formatted_val = AIdb.formatValue(
                            crit, crit_pairs[crit])
                        # if we do not get back a valid value ensure a
                        # hyphen is printed (prevents "" from printing)
                        if formatted_val and crit_pairs[crit]:
                            table_body.append(
                                E.TD(formatted_val, align="center"))
                        else:
                            table_body.append(
                                E.TD(lxml.etree.Entity("nbsp"),
                                     align="center"))

            # print the default manifest at the end of the table,
            # which has the same colspan as the Criteria List label
            else:
                href = '../' + service + '/default.xml'
                table_body.append(
                    E.TR(
                        E.TD(E.A("Default", href=href)),
                        E.TD(lxml.etree.Entity("nbsp"),
                             colspan=colspan,
                             align="center")))
            web_page = E.HTML(
                E.HEAD(E.TITLE(_("OmniOS Automated "
                                 "Installation Webserver"))),
                E.BODY(
                    E.H1(
                        _("Welcome to the OmniOS "
                          "Automated Installation webserver!")),
                    E.P(
                        _("Service '%s' has the following "
                          "manifests available, served to clients "
                          "matching required criteria.") % service),
                    E.TABLE(E.TR(E.TH(_("Manifest"), rowspan="2"),
                                 E.TH(_("Criteria List"), colspan=colspan)),
                            criteria_header,
                            table_body,
                            border="1",
                            align="center"),
                ))
            print lxml.etree.tostring(web_page, pretty_print=True)

    # service is not found, provide available services on host
    if not found:
        sys.stdout.write(_('Service <i>%s</i> not found.  ') % service)
        sys.stdout.write(_('Available services are:<p><ol><i>'))
        host = socket.gethostname()
        for service_name in config.get_all_service_names():
            # assume new service setup
            port = config.get_service_port(service_name)
            sys.stdout.write(
                '<a href="http://%s:%d/cgi-bin/'
                'cgi_get_manifest.py?version=%s&service=%s">%s</a><br>\n' %
                (host, port, VERSION, service_name, service_name))
        sys.stdout.write('</i></ol>%s' % _('Please select a service '
                                           'from the above list.'))

    print '</body></html>'
def get_mfest_or_profile_criteria(sname, services, dbtable):
    """
    Iterate through all the manifests or profiles for the named service (sname)
    pointed to by the SCF service.

    Args
        sname = service name
        services = config.get_all_service_props()
        dbtable = database table, distinguishing manifests from profiles
            Assumed to be one of AIdb.MANIFESTS_TABLE or AIdb.PROFILES_TABLE

    Returns
        a dictionary of the criteria for the named service within a list:

            {
                servicename1:[
                             { 'arch':arch1, 'mem':memory1, 'ipv4':ipaddress1,
                               'mac':macaddr1, 'platform':platform1,
                               'network':network1, 'cpu':cpu1, 'zonename':z1 },
                             ...
                            ]
            }

        * Note1: platform, network and cpu are currently not-implemented
                 upstream.
        * Note2: could simply use a list of dictionaries but implemented as a
                 dictionary of a list of dictionary which will allow for
                 multiple services to be listed at the same time.

        width of longest manifest or profile name

        width of longest criteria

    Raises
        None
    """
    sdict = dict()
    width = 0
    cwidth = 0
    # ensure the named service is in our service dictionary.
    lservices = services.keys()
    if sname in lservices:
        try:
            path = AIService(sname).database_path
        except VersionError as version_err:
            warn_version(version_err)
            return sdict, width, cwidth

        if os.path.exists(path):
            try:
                maisql = AIdb.DB(path)
                maisql.verifyDBStructure()
                aiqueue = maisql.getQueue()
                if dbtable == AIdb.MANIFESTS_TABLE:
                    for name in AIdb.getNames(aiqueue, dbtable):
                        sdict[name] = list()
                        instances = AIdb.numInstances(name, aiqueue)
                        for instance in range(0, instances):
                            width = max(len(name), width)
                            criteria = AIdb.getManifestCriteria(
                                name,
                                instance,
                                aiqueue,
                                humanOutput=True,
                                onlyUsed=True)
                            if criteria:
                                tdict, twidth = get_criteria_info(criteria)
                                cwidth = max(twidth, cwidth)
                                sdict[name].append(tdict)
                elif dbtable == AIdb.PROFILES_TABLE:
                    for name in AIdb.getNames(aiqueue, dbtable):
                        sdict[name] = list()
                        criteria = AIdb.getProfileCriteria(name,
                                                           aiqueue,
                                                           humanOutput=True,
                                                           onlyUsed=True)
                        width = max(len(name), width)
                        tdict, twidth = get_criteria_info(criteria)
                        cwidth = max(twidth, cwidth)

                        sdict[name].append(tdict)
                else:
                    raise ValueError("Invalid value for dbtable: %s" % dbtable)

            except StandardError as err:
                sys.stderr.write(
                    _('Error: AI database access error\n%s\n') % err)
                sys.exit(1)
        else:
            sys.stderr.write(
                _('Error: unable to locate AI database on server '
                  'for %s\n') % sname)
            sys.exit(1)

    return sdict, width, cwidth
            # now decrement the instance number
            query = "UPDATE manifests SET instance = '%i' WHERE name = '%s' " %\
                   (num-1, AIdb.sanitizeSQL(man_name))
            query += "AND instance = '%i'" % num
            query = AIdb.DBrequest(query, commit=True)
            DB.getQueue().put(query)
            query.waitAns()
            # run getResponse to handle and errors
            query.getResponse()

        # remove file if manifest is no longer in database
        if man_name not in AIdb.getManNames(DB.getQueue()):
            try:
                os.remove(os.path.join(dataLoc, 'AI_data',man_name))
            except:
                print >> sys.stderr, _("Warning:\tUnable to find file %s for " +
                                       "removal!") % man_name


if __name__ == '__main__':
    gettext.install("ai", "/usr/lib/locale")
    # check that we are root
    if os.geteuid() != 0:
        raise SystemExit(_("Error:\tNeed root privileges to execute"))
    (DATA_LOC, options) = parse_options()
    if not os.path.exists(os.path.join(DATA_LOC, "AI.db")):
        raise SystemExit(_("Error:\tNeed a valid A/I service directory"))
    AISQL = AIdb.DB(os.path.join(DATA_LOC, 'AI.db'), commit=True)
    AISQL.verifyDBStructure()
    delete_manifest_from_DB(AISQL, options, DATA_LOC)
Exemple #22
0
    # Get the install service's data directory and database path
    try:
        port = svc['txt_record'].rsplit(':')[-1]
    except KeyError:
        raise SystemExit(
            _("SMF data for service %s is corrupt.\n") % options.service_name)
    service_dir = os.path.abspath("/var/ai/" + port)
    database = os.path.join(service_dir, "AI.db")

    # Check that the service directory and database exist
    if not (os.path.isdir(service_dir) and os.path.exists(database)):
        raise SystemExit("Error: Invalid AI service directory: %s" %
                         service_dir)

    # Open the database
    db = AIdb.DB(database, commit=True)

    # Check to make sure that the manifest whose criteria we're
    # updating exists in the install service.
    if not check_published_manifest(service_dir, db, options.manifest_name):
        raise SystemExit(1)

    # Process and validate criteria from -a, -c, or -C, and store
    # store the criteria in a Criteria object.
    try:
        if options.criteria_file:
            root = pub_man.verifyCriteria(pub_man.DataFiles.criteriaSchema,
                                          options.criteria_file, db)
        elif options.criteria_a:
            criteria_dict = pub_man.criteria_to_dict(options.criteria_a)
            root = pub_man.verifyCriteriaDict(pub_man.DataFiles.criteriaSchema,