Exemple #1
0
    def fetch_callback(self, cluster: int, item: int, inst: int):
        """PMDA fetch callback"""
        if cluster == Consts.Control.Cluster:
            if item == Consts.Control.Register:
                json_val = ScriptEncoder(dump_state_data=False).encode(
                    self.get_ctx_state(pmdaGetContext(), 'register', default={}, delete=True))
                return [json_val, 1]
            elif item == Consts.Control.Deregister:
                json_val = json.dumps(self.get_ctx_state(pmdaGetContext(), 'deregister', default={}, delete=True))
                return [json_val, 1]
            elif item == Consts.Control.Start:
                json_val = json.dumps(self.get_ctx_state(pmdaGetContext(), 'start', default={}, delete=True))
                return [json_val, 1]
            elif item == Consts.Control.Stop:
                json_val = json.dumps(self.get_ctx_state(pmdaGetContext(), 'stop', default={}, delete=True))
                return [json_val, 1]
        elif cluster == Consts.Info.Cluster:
            if item == Consts.Info.Scripts:
                id_or_name = self.script_indom.inst_name_lookup(inst)
                if id_or_name is None:
                    return [c_api.PM_ERR_INST, 0]

                cluster = self.find_cluster_by_name(id_or_name)
                if cluster:
                    return [cluster.script.code, 1]
                return [c_api.PM_ERR_INST, 0]
            elif item == Consts.Info.ScriptsJson:
                scripts = [cluster.script for cluster in self.clusters.values()]
                return [ScriptEncoder(dump_state_data=False).encode(scripts), 1]
            elif item == Consts.Info.Tracepoints:
                return [self.tracepoints_csv, 1]
        elif cluster in self.clusters:
            return self.clusters[cluster].fetch_callback(item, inst)
        return [c_api.PM_ERR_PMID, 0]
Exemple #2
0
 def set_ctx_state(self, key: str, value: Any, ctx=None):
     """set per-context state"""
     if ctx is None:
         ctx = pmdaGetContext()
     if ctx not in self.ctxtab:
         self.ctxtab[ctx] = {}
     self.ctxtab[ctx][key] = value
Exemple #3
0
    def store_callback(self, cluster: int, item: int, inst: int, val: str):
        """PMDA store callback"""
        if cluster == Consts.Control.Cluster:
            if not self.config.dynamic_scripts.enabled:
                self.logger.error("dynamic scripts are disabled in configuration")
                return c_api.PM_ERR_PERMISSION

            if self.config.dynamic_scripts.auth_enabled:
                username = self.get_ctx_state(pmdaGetContext(), 'username')
                if username is None:
                    self.logger.info("permission denied for unauthenticated user")
                    return c_api.PM_ERR_PERMISSION
                elif username not in self.config.dynamic_scripts.allowed_users:
                    self.logger.info(f"permission denied for user {username}")
                    return c_api.PM_ERR_PERMISSION

            if item == Consts.Control.Register:
                script = Script(val)
                script.username = self.get_ctx_state(pmdaGetContext(), 'username')
                return self.register_script(script)
            elif item == Consts.Control.Deregister:
                success = True
                for script_id in val.split(','):
                    if not self.deregister_script(script_id):
                        success = False

                if success:
                    self.set_ctx_state(pmdaGetContext(), 'deregister', {"success": "true"})
                    return 0
                else:
                    self.set_ctx_state(pmdaGetContext(), 'deregister', {"error": "one or more scripts were not found"})
                    return c_api.PM_ERR_BADSTORE
            elif item == Consts.Control.Start:
                cluster = self.find_cluster_by_name(val)
                if not cluster:
                    self.set_ctx_state(pmdaGetContext(), 'start', {"error": "script not found"})
                    return c_api.PM_ERR_BADSTORE

                self.bpftrace_service.start_script(cluster.script.script_id)
                self.set_ctx_state(pmdaGetContext(), 'start', {"success": "true"})
                return 0
            elif item == Consts.Control.Stop:
                cluster = self.find_cluster_by_name(val)
                if not cluster:
                    self.set_ctx_state(pmdaGetContext(), 'stop', {"error": "script not found"})
                    return c_api.PM_ERR_BADSTORE

                self.bpftrace_service.stop_script(cluster.script.script_id)
                self.set_ctx_state(pmdaGetContext(), 'stop', {"success": "true"})
                return 0
        return c_api.PM_ERR_PMID
Exemple #4
0
    def register_script(self, script: Script, update_ctx=True):
        """register a new bpftrace script"""
        script = self.bpftrace_service.register_script(script)
        if update_ctx:
            self.set_ctx_state(pmdaGetContext(), 'register', script)
        if script.state.status == Status.Error:
            return c_api.PM_ERR_BADSTORE

        cluster = BPFtraceCluster(self, self.logger, self.bpftrace_service, script)
        cluster.register_metrics()
        self.clusters[cluster.cluster_id] = cluster
        self.refresh_script_indom()
        return 0
Exemple #5
0
    def get_ctx_state(self,
                      key: str,
                      ctx=None,
                      default=None,
                      delete=False) -> Any:
        """get per-context state"""
        if ctx is None:
            ctx = pmdaGetContext()
        if ctx not in self.ctxtab or key not in self.ctxtab[ctx]:
            return default

        value = self.ctxtab[ctx].get(key, default)
        if delete:
            del self.ctxtab[ctx][key]
        return value