Exemple #1
0
 def report_candidates(cls, source_fs):
     """@return a report with all possible destinations to which source_fs could be send to"""
     rep = Report(cls.report_schema)
     now = datetime.now()
     for url, fs in cls._find_destination_fs_candidates(source_fs):
         info = cls._dest_info(source_fs, url, dest_fs = fs)
         cls._append_info_record(rep, now, source_fs, info)
     # end for each candidate
     # The less we have to send the better
     rep.records = sorted(rep.records, key=lambda r: r[8])
     return rep
Exemple #2
0
    def _handle_list(self, args, session):
        """Implement list subcommand"""
        SQLType, schema, filter_attr = self.SQL_TYPE_MAP.get(args.type)
        assert SQLType, "Unkown type encountered, updated SQL_TYPE_MAP"

        report = Report(columns=schema)
        query = session.query(SQLType)

        # Handle filtering
        ###################
        filter_name = getattr(args, filter_attr)
        if filter_name != self.FILTER_ANY:
            sql_filter = self.SQL_FILTER_MAP.get(filter_name)
            assert sql_filter is not None, "Unknown sql filter, update SQL_FILTER_MAP with '%s'" % filter_name
            query = query.filter(sql_filter)
        # end handle pre-packaged filter

        # sort it
        query = query.order_by(getattr(SQLType.id, args.order == self.ORDER_DESC and 'desc' or 'asc')())

        limit = args.limit is None and self.LIMIT_DEFAULT or args.limit
        if limit > 0:
            query = query.limit(limit)
        # end finally, set limit

        # Convert data to report
        ########################
        record = report.records.append
        count = -1
        for count, item in enumerate(query):
            record(tuple(getattr(item, vals[0]) for vals in schema))
        # end for each item

        # And output it
        report.serialize(args.output_mode, sys.stdout.write, column_names=not args.no_header)

        if count == -1:
            sys.stderr.write("No '%s' record found\n" % args.type)
        if count + 1 == limit:
            sys.stderr.write("WARNING: Output was limited to %i - see the --limit flag\n" % args.limit)
        # end handle warnings and errors

        return self.SUCCESS
Exemple #3
0
    def _handle_transactions(self, args, session):
        """Implement transaction subcommand"""
        if args.action in self.query_actions:
            if args.reason:
                self.log().warn("--reason has no effect in query actions like %s", ', '.join(self.query_actions))
            # end handle reason
        else:
            if not args.reason:
                self.log().error("Please specify a reason for performing the '%s' action, use the --reason argument", args.action)
                return self.ERROR
            # end need reason
        # end assure reason is set

        try:
            for tid in getattr(args, self.ARG_TRANSACTION_IDS):
                trans = session.query(SQLPackageTransaction).filter(SQLPackageTransaction.id == tid)[:]
                if not trans:
                    raise ValueError("No transaction found with id %i" % tid)
                # end fail on missing transactions
                trans = trans[0]
                if args.action == self.ACTION_APPROVE:
                    if trans.finished_at is not None or trans.started_at is not None:
                        raise ValueError("Transaction %i is already done and cannot be approved after the fact" % tid)
                    # end handle finished transactions
                    trans.approved_by_login = login_name()
                    self.log().info("Approved %i" % tid)
                elif args.action == self.ACTION_REJECT:
                    trans.reject_approval()
                    self.log().info("Rejected %i" % tid)
                elif args.action == self.ACTION_CANCEL:
                    trans.cancel()
                    self.log().info("Canceled %i" % tid)
                elif args.action == self.ACTION_LIST_FILES:
                    print "Files for transaction %i" % tid
                    report = Report(columns=self.report_schema_files)
                    record = report.records.append
                    for f in trans.files:
                        try:
                            uid = getpwuid(f.uid).pw_name
                        except KeyError:
                            uid = f.uid
                        # end remap uid if possible
                        record((f.path, f.size, uid, f.gid, f.mode))
                    # end for each file
                    report.serialize(Report.SERIALIZE_TTY, sys.stdout.write)
                else:
                    raise NotImplemented("unknown action: %s" % args.action)
                # end handle action

                # Always keep the reason around
                if args.action not in self.query_actions:
                    assert args.reason
                    trans.reason = args.reason
                # end assure reason is set only in edit mode
            # end for each tid
            session.commit()
        except Exception, err:
            self.log().error(str(err))
            if args.action not in self.query_actions:
                session.rollback()
                self.log().error("Failed to set transaction - all progress rolled back")
            # end don't warn if we are read-only
            return self.ERROR
Exemple #4
0
    def execute(self, args, remaining_args):
        config = self.settings_value()
        session = ZSession.new()
        zcls = args.type == ZReportGenerator.TYPE_POOL and ZPool or ZDataset
        query = session.query(zcls)
        table = zcls.__table__
        columns = table.columns.keys()
        hosts_attribute = zcls.host
        name_attribute = zcls.name
        columns_important = getattr(config.columns, args.type)

        if args.type == ZReportGenerator.TYPE_SNAPSHOT:
            query = query.filter(ZDataset.avail == None)
            columns_important = config.columns.snapshot
        elif args.type == ZReportGenerator.TYPE_FILESYSTEM:
            query = query.filter(ZDataset.avail != None).filter(ZDataset.type == ZReportGenerator.TYPE_FILESYSTEM)
            columns_important = config.columns.filesystem

        # COLUMNS FILTER
        #################
        if args.columns:
            has_user_columns = True
            if len(args.columns) == 1 and args.columns[0] in (self.COLUMN_ALL, self.COLUMN_IMPORTANT):
                if args.columns[0] == self.COLUMN_IMPORTANT:
                    args.columns = columns_important
                else:
                    has_user_columns = False
                # end handle 'all'
            # end handle presets

            if has_user_columns:
                columns = self.verify_columns(table.columns, args.columns)
                if not columns:
                    return self.ERROR
                # end early abort
            # end handle special case: all
        # end check provided columns

        # Always use the updated_at column
        columns.insert(0, 'updated_at')

        # HOSTS FILTER
        ##############
        if args.host:
            query = query.filter(hosts_attribute == args.host)
        # end

        # Name filter
        ##############
        if args.name:
            name = '%%%s%%' % args.name
            query = query.filter(name_attribute.like(name))
        # end handle name filter

        # ORDER
        #########
        # NOTE: if there is no order, order by creation ascending !
        if not args.order_by_asc and not args.order_by_desc:
            args.order_by_asc = ['host', 'creation']
        # end auto-order

        for attr, order in (('order_by_asc', 'asc'), ('order_by_desc', 'desc')):
            order_cols = getattr(args, attr)
            if not order_cols:
                continue
            # end handle order_cols
            order_cols = self.columns_by_names(table.columns, order_cols)
            if order_cols:
                query = query.order_by(*(getattr(col, order)() for col in order_cols))
        # end for each attr, order
        
        rep = Report()
        rep.columns = self.table_schema_from_colums(table.columns, columns)
        now = datetime.now()

        # FILL RECORDS
        ##############
        col_to_attr = zcls.__mapper__.get_property_by_column
        name_to_col = table.columns.__getitem__
        for inst in query:
            rec = list()

            if isinstance(inst, ZDataset) and args.leaf and not inst.is_snapshot() and list(inst.children()):
                continue
            # end skip non-leaf datasets

            for cid, name in enumerate(columns):
                if name == self.COLUMN_URL:
                    val = str(ZFSURL.new_from_dataset(inst.host, inst.name))
                else:
                    val = getattr(inst, col_to_attr(name_to_col(name)).key)
                    if isinstance(val, datetime):
                        val = now - val
                    # end handle conversions
                # end handle special case
                rec.append(val)
            # end for each colum
            rep.records.append(rec)
        # end for each row

        # AGGREGATION
        ##################
        if len(rep.records) > 1:
            agr = rep.aggregate_record()
            agr[0] = now - now
            rep.records.append(agr)

            if args.aggregate_only:
                rep.records = rep.records[-1:]
            # end remove all records but aggregate
        # end aggregate only if there is something

        # Finally, make sure updated_at becomes seen - we now have the values and no one cares about the schema
        # names anymore
        for col in rep.columns:
            if col[0] == 'updated_at':
                col[0] = 'seen'
        # end rename updated_at

        rep.serialize(Report.SERIALIZE_TTY, sys.stdout.write)
        return self.SUCCESS