def _initialize_options(self): from ZeekControl import execute # Set defaults for options we get passed in. self.init_option("zeekbase", self.basedir) self.init_option("zeekscriptdir", self.zeekscriptdir) self.init_option("version", VERSION) # Initialize options that are not already set. for opt in options.options: if opt.dontinit: continue if opt.legacy_name: old_key = opt.legacy_name.lower() if old_key in self.config: self.ui.warn("option '%s' is deprecated, please use '%s' instead" % (opt.legacy_name, opt.name)) self.init_option(opt.name, self.config[old_key]) del self.config[old_key] continue self.init_option(opt.name, opt.default) # Set defaults for options we derive dynamically. self.init_option("mailto", "%s" % os.getenv("USER")) self.init_option("mailfrom", "Zeek <zeek@%s>" % socket.gethostname()) self.init_option("mailalarmsto", self.config["mailto"]) # Determine operating system. success, output = execute.run_localcmd("uname") if not success or not output: raise RuntimeEnvironmentError("failed to run uname: %s" % output) self.init_option("os", output.strip()) # Determine the CPU pinning command. pin_cmd = "" if self.config["os"] == "Linux": pin_cmd = "taskset -c" elif self.config["os"] == "FreeBSD": pin_cmd = "cpuset -l" self.init_option("pin_command", pin_cmd) # Find the time command (should be a GNU time for best results). time_cmd = "" success, output = execute.run_localcmd("which time") if success and output: # On redhat-based systems, path to cmd is prefixed with '\t' on 2nd # line when alias is defined. time_cmd = output.splitlines()[-1].strip() self.init_option("time", time_cmd) # Calculate the log expire interval (in minutes). minutes = self._get_interval_minutes("logexpireinterval") self.init_option("logexpireminutes", minutes)
def _break_lock(cmdout): from ZeekControl import execute try: # Check whether lock is stale. with open(config.Config.lockfile, "r") as f: pid = f.readline().strip() except (OSError, IOError) as err: cmdout.error("failed to read lock file: %s" % err) return -1 success, output = execute.run_localcmd( "%s %s" % (os.path.join(config.Config.helperdir, "check-pid"), pid)) if success and output.strip() == "running": # Process still exists. try: return int(pid) except ValueError: return -1 cmdout.info("removing stale lock") try: # Break lock. os.unlink(config.Config.lockfile) except (OSError, IOError) as err: cmdout.error("failed to remove lock file: %s" % err) return -1 return 0
def run_cron_cmd(self): # Run external command if we have one. if self.config.croncmd: success, output = execute.run_localcmd(self.config.croncmd) if not success: self.ui.error("failure running croncmd: %s" % self.config.croncmd)
def _get_zeek_version(self): from ZeekControl import execute zeek = self.config["zeek"] if not os.path.lexists(zeek): raise ConfigurationError("cannot find Zeek binary: %s" % zeek) version = "" success, output = execute.run_localcmd("%s -v" % zeek) if success and output: version = output.splitlines()[-1] else: msg = " with no output" if output: msg = " with output:\n%s" % output raise RuntimeEnvironmentError('running "zeek -v" failed%s' % msg) match = re.search(".* version ([^ ]*).*$", version) if not match: raise RuntimeEnvironmentError( 'cannot determine Zeek version ("zeek -v" output: %s)' % version.strip()) version = match.group(1) # If zeek is built with the "--enable-debug" configure option, then it # appends "-debug" to the version string. if version.endswith("-debug"): version = version[:-6] return version
def process(self, trace, zeek_options, zeek_scripts): results = cmdresult.CmdResult() if not os.path.isfile(trace): self.ui.error("trace file not found: %s" % trace) results.ok = False return results if self.config.standalone: node = self.config.nodes()[0] else: node = self.config.workers()[0] cwd = os.path.join(self.config.tmpdir, "testing") if os.path.isdir(cwd): try: shutil.rmtree(cwd) except OSError as err: self.ui.error("cannot remove directory: %s" % err) results.ok = False return results try: os.makedirs(cwd) except OSError as err: self.ui.error("cannot create directory: %s" % err) results.ok = False return results env = _make_env_params(node) zeek_args = " ".join(zeek_options + _make_zeek_params(node, False)) zeek_args += " zeekctl/process-trace" if zeek_scripts: zeek_args += " " + " ".join(zeek_scripts) cmd = os.path.join(self.config.scriptsdir, "run-zeek-on-trace") + " %s %s %s %s" % (0, cwd, trace, zeek_args) self.ui.info(cmd) success, output = execute.run_localcmd(cmd, env=env) if not success: results.ok = False self.ui.info(output) self.ui.info("### Zeek output in %s" % cwd) return results
def expire_logs(self): if self.config.logexpireminutes == 0 and self.config.statslogexpireinterval == 0: return if self.config.standalone: success, output = execute.run_localcmd(os.path.join(self.config.scriptsdir, "expire-logs")) if not success: self.ui.error("expire-logs failed\n%s" % output) else: nodes = self.config.hosts(tag=node_mod.logger_group()) if not nodes: nodes = self.config.hosts(tag=node_mod.manager_group()) expirelogs = os.path.join(self.config.scriptsdir, "expire-logs") cmds = [(node, expirelogs, []) for node in nodes] for (node, success, output) in self.executor.run_cmds(cmds): if not success: self.ui.error("expire-logs failed for node %s\n" % node) if output: self.ui.error(output)
def update_http_stats(self): if not self.config.statslogenable: return # Create meta file. if not os.path.exists(self.config.statsdir): try: os.makedirs(self.config.statsdir) except OSError as err: self.ui.error("failure creating directory in zeekctl option statsdir: %s" % err) return self.ui.info("creating directory for stats file: %s" % self.config.statsdir) metadat = os.path.join(self.config.statsdir, "meta.dat") try: with open(metadat, "w") as meta: for node in self.config.hosts(): meta.write("node %s %s %s\n" % (node, node.type, node.host)) meta.write("time %s\n" % time.asctime()) meta.write("version %s\n" % self.config.version) success, output = execute.run_localcmd("uname -a") if success and output: # Note: "output" already has a '\n' meta.write("os %s" % output) else: meta.write("os <error>\n") success, output = execute.run_localcmd("hostname") if success and output: # Note: "output" already has a '\n' meta.write("host %s" % output) else: meta.write("host <error>\n") except IOError as err: self.ui.error("failure creating file: %s" % err) return wwwdir = os.path.join(self.config.statsdir, "www") if not os.path.isdir(wwwdir): try: os.makedirs(wwwdir) except OSError as err: self.ui.error("failed to create directory: %s" % err) return # Update the WWW data statstocsv = os.path.join(self.config.scriptsdir, "stats-to-csv") success, output = execute.run_localcmd("%s %s %s %s" % (statstocsv, self.config.statslog, metadat, wwwdir)) if success: shutil.copy(metadat, wwwdir) else: self.ui.error("error reported by stats-to-csv\n%s" % output) # Append the current stats.log in spool to the one in ${statsdir} dst = os.path.join(self.config.statsdir, os.path.basename(self.config.statslog)) try: with open(self.config.statslog, "r") as fsrc: with open(dst, "a") as fdst: shutil.copyfileobj(fsrc, fdst) except IOError as err: self.ui.error("failed to append file: %s" % err) return os.unlink(self.config.statslog)
def _sendmail(self, subject, body): if not self.config.sendmail: return True, "" cmd = "%s '%s'" % (os.path.join(self.config.scriptsdir, "send-mail"), subject) return execute.run_localcmd(cmd, inputtext=body)