Beispiel #1
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.")
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
Beispiel #3
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)
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