Exemplo n.º 1
0
Arquivo: limits.py Projeto: Byron/bit
    def generate_fix_script(self, report, writer):
        """Generate a script with progress and zfs destroy commands
        @note will only generate commands for one host"""
        mss = self._config.min_snapshot_size or 0
        if mss:
            mss = size_to_int(mss)
        # end handle type conversion
        fss = self._config.min_filesystem_size or 0
        if fss:
            fss = size_to_int(fss)
        # end handle type conversion
        sotd = self._config.snapshots_older_than_days
        date = datetime_days_ago(time(), sotd)

        def predicate(rec):
            tn = rec[3]
            ctime = rec[4] # creation delta time
            size = rec[6]

            # We don't know what's part of the Report, and why those values are there.
            # This is why we have to re-evaluate the inverse logic to prevent us from 
            # generating code that would mean something different
            return (tn == self.TYPE_SNAPSHOT   and (size < mss or ctime <= date)) or (tn == self.TYPE_FILESYSTEM and size < fss)
        # end predicate

        header_line = "SETTING UP ZFS DESTROY COMMANDS FOR SELECTED DATASETS ON HOST %s\n" % ', '.join(self._config.hosts)
        return self._create_zfs_destroy_script(predicate, header_line, report, writer)
Exemplo n.º 2
0
Arquivo: limits.py Projeto: Byron/bit
    def generate(self):
        """See class description and schema for more information"""
        rep = self.ReportType()
        rep.columns.extend(self.report_schema)

        max_pool_cap,\
        fs_cap,\
        min_snapshot_size,\
        min_filesystem_size,\
        snapshots_older_than_days,\
        filesystems_older_than_days,\
        name_like,\
        hosts                       = ( self._config.max_pool_cap, 
                                        self._config.max_filesystem_cap,
                                        self._config.min_snapshot_size,
                                        self._config.min_filesystem_size,
                                        self._config.snapshots_older_than_days,
                                        self._config.filesystems_older_than_days,
                                        self._config.name_like,
                                        self._config.hosts)
        assert name_like, "Name matching must be at least '%%', got nothing"
        rappend = rep.records.append
        now = datetime.now()
        nows = time()
        percent_comment = '%s.cap > %.0f%%'

        # POOL CAPACITIES
        ###################
        if max_pool_cap <= 100.0:
            fill_capage = (ZPool.size - ZPool.free) / (ZPool.size * 1.0)
            percent_condition = fill_capage >= max_pool_cap / 100.0
            comment = percent_comment % (self.TYPE_POOL, max_pool_cap)
            for pool in host_filter(hosts, ZPool.host, self._session.query(ZPool).\
                                            filter(percent_condition).\
                                            filter(ZPool.name.like(name_like)).\
                                            order_by(fill_capage.desc())): 
                rec = [now - pool.updated_at, pool.host, pool.name, self.TYPE_POOL,'NA', 'NA', pool.size, pool.free, 
                        ((pool.size - pool.free) / float(pool.size)) * 100, comment]
                rappend(rec)
            # end for each that matches
        # end check enabled

        # FILESYSTEM CAPACITIES
        ########################
        if fs_cap <= 100.0:
            filesystem = ZDataset.avail != None
            fill_capage = 1.0 - (ZDataset.avail / (ZDataset.avail + ZDataset.used) * 1.0)
            percent_condition = fill_capage >= fs_cap / 100.0
            comment = percent_comment % (self.TYPE_FILESYSTEM, fs_cap)
            for fs in host_filter(hosts, ZDataset.host, self._session.query(ZDataset).\
                                                filter(filesystem).\
                                                filter(ZDataset.name.like(name_like)).\
                                                filter(percent_condition).\
                                                order_by(fill_capage.desc())):
                rec = [ now - fs.updated_at, fs.host, fs.name, self.TYPE_FILESYSTEM, fs.creation, now - fs.creation, fs.used, fs.avail, 
                        (1.0 - (fs.avail / float((fs.avail + fs.used)))) * 100.0, comment]
                rappend(rec)
            # end for each record
        # end check enabled

        # DATASETS TOO SMALL
        #####################
        # TODO: implement protection against deleting the last snapshot ! In case it's on, we must assure
        # the latest snapshot of a filesystem is not deleted. Could be a complex group + join
        def make_records(type_condition, condition, type_name, comment):
            for ds in host_filter(hosts, ZDataset.host, self._session.query(ZDataset).\
                                        filter(type_condition).\
                                        filter(ZDataset.name.like(name_like)).\
                                        filter(condition).\
                                        order_by(ZDataset.host)):
                rec = [now - ds.updated_at, ds.host, ds.name, type_name, ds.creation, now - ds.creation, 
                        ds.used, ds.avail or 0,
                        ds.avail and ((ds.used / float(ds.used + ds.avail)) * 100.0) or 100.0, comment]
                rappend(rec)
            # end for each snapshot
        # end make records utility

        min_size_fmt = '%s.size < %s'
        if min_snapshot_size:
            condition = ZDataset.used < size_to_int(min_snapshot_size)
            make_records(ZDataset.avail == None, condition, self.TYPE_SNAPSHOT, 
                            min_size_fmt % (self.TYPE_SNAPSHOT, min_snapshot_size))
        if min_filesystem_size:
            condition = ZDataset.used < size_to_int(min_filesystem_size)
            make_records(ZDataset.avail != None, condition, self.TYPE_FILESYSTEM, 
                            min_size_fmt % (self.TYPE_FILESYSTEM, min_filesystem_size))
        # end handle item sizes


        # DATASET AGE
        ##############
        if snapshots_older_than_days:
            condition = ZDataset.creation <= datetime_days_ago(nows, snapshots_older_than_days)
            make_records(ZDataset.avail == None, condition, self.TYPE_SNAPSHOT, 
                            '%s.creation older %id' % (self.TYPE_SNAPSHOT, snapshots_older_than_days))

        if filesystems_older_than_days:
            condition = ZDataset.creation <= datetime_days_ago(nows, filesystems_older_than_days)
            make_records(ZDataset.avail != None, condition, self.TYPE_FILESYSTEM, 
                            '%s.creation older %id' % (self.TYPE_FILESYSTEM, filesystems_older_than_days))
        # end ignore age if time is 0, which is essentially just no


        # FILESYSTEM FREE SPACE
        ########################
        min_filesystem_avail_size = size_to_int(self._config.min_filesystem_avail_size)
        if min_filesystem_avail_size:
            condition = ZDataset.avail >= min_filesystem_avail_size
            make_records(ZDataset.avail != None, condition, self.TYPE_FILESYSTEM, 
                            '%s.avail >= %s' % (self.TYPE_FILESYSTEM, self._config.min_filesystem_avail_size))
        # end ignore this value if zero
        

        # AGGREGATE
        #############
        self._aggregate_records(rep.records, now)
        return rep