[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Organize examples into their own directory
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346688 ) Change subject: Organize examples into their own directory .. Organize examples into their own directory Change-Id: I4635c1a1aa1b6ea6bba9e70b335319a874b1d9d4 --- R examples/job.example.yaml R examples/process-control.example.yaml 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/88/346688/1 diff --git a/job.example.yaml b/examples/job.example.yaml similarity index 91% rename from job.example.yaml rename to examples/job.example.yaml index 523bcd4..233a01d 100644 --- a/job.example.yaml +++ b/examples/job.example.yaml @@ -1,5 +1,5 @@ -# Copy this job to your configured `job_directory` and give it a name, like -# `purge_binge.yaml`. +# Copy this job to /var/lib/process-control/ or your configured `job_directory` +# and give name it according to the job, like `purge_binge.yaml`. # # Verbose job name. The short, machine name is taken from the base file name. diff --git a/process-control.example.yaml b/examples/process-control.example.yaml similarity index 100% rename from process-control.example.yaml rename to examples/process-control.example.yaml -- To view, visit https://gerrit.wikimedia.org/r/346688 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4635c1a1aa1b6ea6bba9e70b335319a874b1d9d4 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Rename test to match new class name
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346686 ) Change subject: Rename test to match new class name .. Rename test to match new class name Change-Id: I80f29574c96d94e92290066422f33378752d05d0 --- R tests/test_runner.py 1 file changed, 0 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/86/346686/1 diff --git a/tests/test_job_runner.py b/tests/test_runner.py similarity index 100% rename from tests/test_job_runner.py rename to tests/test_runner.py -- To view, visit https://gerrit.wikimedia.org/r/346686 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I80f29574c96d94e92290066422f33378752d05d0 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: make logfile path statically
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346680 ) Change subject: make logfile path statically .. make logfile path statically This would be useful for reuse. Change-Id: Ic096594a7d90cf64ed9dae35ac73cb8ef4c222c0 --- M processcontrol/output_streamer.py 1 file changed, 17 insertions(+), 17 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/80/346680/1 diff --git a/processcontrol/output_streamer.py b/processcontrol/output_streamer.py index ba77ede..4735580 100644 --- a/processcontrol/output_streamer.py +++ b/processcontrol/output_streamer.py @@ -7,6 +7,22 @@ from . import config +def make_logfile_path(slug, start_time): +""" +Makes the output file path and creates parent directory if needed +""" +output_directory = config.GlobalConfiguration().get("output_directory") +assert os.access(output_directory, os.W_OK) + +# per-job directory +job_log_directory = output_directory + "/" + slug +if not os.path.exists(job_log_directory): +os.makedirs(job_log_directory) + +timestamp = start_time.strftime("%Y%m%d-%H%M%S") +return "{logdir}/{name}-{timestamp}.log".format(logdir=job_log_directory, name=slug, timestamp=timestamp) + + class OutputStreamer(object): def __init__(self, process, slug, start_time): @@ -14,8 +30,7 @@ self.err_stream = process.stderr self.pid = process.pid self.slug = slug -self.start_time = start_time -self.filename = self.make_logfile_path() +self.filename = make_logfile_path(slug, start_time) self.logger = None self.threads = {} self.log_handlers = [] @@ -46,21 +61,6 @@ self.logger.error(line) else: self.logger.info(line) - -def make_logfile_path(self): -""" -Makes the output file path and creates parent directory if needed -""" -output_directory = config.GlobalConfiguration().get("output_directory") -assert os.access(output_directory, os.W_OK) - -# per-job directory -job_directory = output_directory + "/" + self.slug -if not os.path.exists(job_directory): -os.makedirs(job_directory) - -timestamp = self.start_time.strftime("%Y%m%d-%H%M%S") -return "{logdir}/{name}-{timestamp}.log".format(logdir=job_directory, name=self.slug, timestamp=timestamp) def init_logger(self): if self.logger is not None: -- To view, visit https://gerrit.wikimedia.org/r/346680 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic096594a7d90cf64ed9dae35ac73cb8ef4c222c0 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Call a slug what it is
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346679 ) Change subject: Call a slug what it is .. Call a slug what it is Change-Id: Ibe004d848462e58b0fabc974de9474ecf9dd29de --- M bin/run-job 1 file changed, 10 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/79/346679/1 diff --git a/bin/run-job b/bin/run-job index eec5f9f..7df6344 100755 --- a/bin/run-job +++ b/bin/run-job @@ -10,10 +10,12 @@ def list_jobs(): - for job_name in job_spec.list(): + for job_slug in job_spec.list(): try: - job = job_spec.load(job_name) - message = "{job} - {human_name}".format(job=job_name, human_name=job.name) + # FIXME: Nicer if this inner loop moved to Job rather than having + # status come from an ephemeral runner. + job = job_spec.load(job_slug) + message = "{job} - {name}".format(job=job_slug, name=job.name) status = runner.JobRunner(job).status() if status is not None: message += "" + yaml.dump(status).strip() @@ -22,14 +24,17 @@ if job.description is not None: message += "\n" + job.description except AssertionError: - message = "{job} ***Invalid configuration***".format(job=job_name) + message = "{job} ***Invalid configuration***".format(job=job_slug) print(message) if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Run and maintain process-control jobs.") + # TODO: Change the function name or move responsibilities beyond "run" to a + # new script. + parser = argparse.ArgumentParser(description="Run or query `process-control` jobs.") parser.add_argument("-j", "--job", help="Run a given job.", type=str) parser.add_argument("-l", "--list-jobs", help="Print a summary of available jobs.", action='store_true') + # TODO: --kill-job, --disable-group, --enable-group args = parser.parse_args() if args.job: -- To view, visit https://gerrit.wikimedia.org/r/346679 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibe004d848462e58b0fabc974de9474ecf9dd29de Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Log actual commandline rather than redundant parent job slug.
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346681 ) Change subject: Log actual commandline rather than redundant parent job slug. .. Log actual commandline rather than redundant parent job slug. Change-Id: I2e57112fa528037a0db16f9389bc4320eaf528f9 --- M processcontrol/output_streamer.py M processcontrol/runner.py 2 files changed, 12 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/81/346681/1 diff --git a/processcontrol/output_streamer.py b/processcontrol/output_streamer.py index 4735580..39e767b 100644 --- a/processcontrol/output_streamer.py +++ b/processcontrol/output_streamer.py @@ -25,11 +25,12 @@ class OutputStreamer(object): -def __init__(self, process, slug, start_time): +def __init__(self, process, slug, cmdline, start_time): self.out_stream = process.stdout self.err_stream = process.stderr self.pid = process.pid self.slug = slug +self.cmdline = cmdline self.filename = make_logfile_path(slug, start_time) self.logger = None self.threads = {} @@ -37,8 +38,17 @@ def start(self): self.init_logger() + +self.log_header() + self.start_reading(self.out_stream, "stdout") self.start_reading(self.err_stream, "stderr", is_error_stream=True) + +def log_header(self): +# TODO: maybe expose the header as a configurable template. +self.logger.info("===") +self.logger.info("{cmdline} ({pid})".format(cmdline=self.cmdline, pid=self.pid)) +self.logger.info("---") def start_reading(self, stream, stream_name, is_error_stream=False): thread = threading.Thread( @@ -81,12 +91,6 @@ console_handler = logging.StreamHandler(sys.stdout) self.log_handlers.append(console_handler) self.logger.addHandler(console_handler) - -# FIXME: gets written for each subprocess, so the name=slug is not -# quite right. Should be the commandline? -self.logger.info("===") -self.logger.info("{name} ({pid})".format(name=self.slug, pid=self.pid)) -self.logger.info("---") def stop(self): for thread in self.threads.values(): diff --git a/processcontrol/runner.py b/processcontrol/runner.py index 3aef5ae..5ee090a 100644 --- a/processcontrol/runner.py +++ b/processcontrol/runner.py @@ -66,7 +66,7 @@ command = shlex.split(command_string) self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.job.environment) -streamer = output_streamer.OutputStreamer(self.process, self.job.slug, self.start_time) +streamer = output_streamer.OutputStreamer(self.process, self.job.slug, command_string, self.start_time) self.logfile = streamer.filename streamer.start() -- To view, visit https://gerrit.wikimedia.org/r/346681 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2e57112fa528037a0db16f9389bc4320eaf528f9 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: [WIP] Implement "description" field
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346670 ) Change subject: [WIP] Implement "description" field .. [WIP] Implement "description" field Change-Id: I16be5ff71a292c77143bff0c0f2c24f2f478f327 --- M bin/run-job M job.example.yaml 2 files changed, 8 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/70/346670/1 diff --git a/bin/run-job b/bin/run-job index 4c1a005..733efa9 100755 --- a/bin/run-job +++ b/bin/run-job @@ -17,6 +17,7 @@ status = runner.JobRunner(job).status() if status is not None: message += "" + yaml.dump(status).strip() + if job.description is not None except AssertionError: message = "{job} ***Invalid configuration***".format(job=job_name) print(message) diff --git a/job.example.yaml b/job.example.yaml index 523fbeb..523bcd4 100644 --- a/job.example.yaml +++ b/job.example.yaml @@ -6,6 +6,13 @@ # name: Take This Job and Shove It +# +# Optional text explaining the job. +# +description: > +Create TPS report in the basement, execute in triplicate and shoot it down +the pneumatic tube. Wait three weeks for delivery. + # The commandline that will be run. This is executed from Python and not from # a shell, so globbing, redirecting, and other trickery will not work. Please # give the full path to executables as in a crontab. -- To view, visit https://gerrit.wikimedia.org/r/346670 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I16be5ff71a292c77143bff0c0f2c24f2f478f327 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Handle commandline param like other fields.
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346667 ) Change subject: Handle commandline param like other fields. .. Handle commandline param like other fields. Change-Id: Iab17d09434914b4fde7a0dc06b8c3ff32e1df54f --- M processcontrol/job_wrapper.py 1 file changed, 10 insertions(+), 9 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/67/346667/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 7d9817a..25f958c 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -66,6 +66,14 @@ str_env = {k: str(v) for k, v in self.config.get("environment").items()} self.environment.update(str_env) +command = self.config.get("command") +if hasattr(command, "encode"): +# Is stringlike, so cast to a list and handle along with the plural +# case below. +command = [command] + +self.commands = command + def run(self): # Check that we are the service user. service_user = str(self.global_config.get("user")) @@ -86,16 +94,9 @@ timer = threading.Timer(timeout_seconds, self.fail_timeout) timer.start() -command = self.config.get("command") - -if hasattr(command, "encode"): -# Is stringlike, so cast to a list and handle along with the plural -# case below. -command = [command] - try: -for line in command: -self.run_command(line) +for command_line in self.commands: +self.run_command(command_line) finally: lock.end() if self.timeout > 0: -- To view, visit https://gerrit.wikimedia.org/r/346667 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iab17d09434914b4fde7a0dc06b8c3ff32e1df54f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Document a bit
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346664 ) Change subject: Document a bit .. Document a bit Change-Id: I879936947ff4af826b173059e742637f9aeefaed --- M README.md A job.example.yaml M process-control.example.yaml 3 files changed, 90 insertions(+), 42 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/64/346664/1 diff --git a/README.md b/README.md index 60b662e..e59c26c 100644 --- a/README.md +++ b/README.md @@ -8,59 +8,47 @@ Configuration === -Global configuration must be created before you can run jobs (FIXME: works out -of the box). Copy the file /usr/share/doc/process-control/process-control.example.yaml -to /etc/fundraising/process-control.yaml +Global configuration must be created before you can run jobs (FIXME: Make this +work out-of-the-box). Copy the file +/usr/share/doc/process-control/process-control.example.yaml +to /etc/fundraising/process-control.yaml and customize it for your machine. + +You'll need to pick a service user, and make /var/log/process-control writable +by that user. Job descriptions === -A job description file has the following format, - -```yaml -name: Take This Job and Shove It - -# The commandline that will be run. This is executed from Python and not from -# a shell, so globbing and other trickery will not work. Please give a full -# path to the executable. -# -# Alternatively, a job can be configured as a list of several commands. These -# are executed in sequence, and execution stops at the first failure. -# -#command: -## Run sub-jobs, each with their own lock and logfiles. -#- /usr/bin/run-job prepare_meal -#- /usr/bin/run-job mangia -#- /usr/bin/run-job clean_up_from_meal -# -command: /usr/local/bin/timecard --start 9:00 --end 5:30 - -# Optional schedule, in Vixie cron format: -# minute hour day-of-month month day-of-week -schedule: "*/5 * * * *" - -# Optional flag to prevent scheduled job execution. The job -# can still be run as a single-shot. -disabled: true - -# Optional timeout in minutes, after which your job will be -# aborted. Defaults to no timeout. -timeout: 30 - -# Optional environment variables. -environment: - PYTHONPATH: /usr/share/invisible/pie -``` +Each job is described in a YAML file under the /var/lib/process-control +directory (by default). See `job.example.yaml` for the available keys and +their meaninings. Running === + Jobs can be run by name, run-job job-a-thon which will look for a job configuration in `/var/lib/process-control/job-a-thon.yaml`. -Some actions are shoehorned in, and can be accessed like: +Other actions on jobs can be accessed like: run-job --list-jobs - run-job --kill-job job-a-thon + +Scheduled Jobs +== + +Any job that includes a `schedule` key and does not have `disabled: true` can +be automatically scheduled. The schedule value is given as a five-term Vixie +crontab (man 5 crontab), but aliases like `@daily` are not allowed. + +A script `cron-generate` will read all scheduled jobs and write entries to +/etc/cron.d/process-control, or the configured `output_crontab`. For example, +a job `yak` with the schedule `30 12 * * *` will be written + +Cron-generate takes no arguments, its configuration is read from /etc. + +cron-generate + +All cron jobs Failure detection == @@ -74,11 +62,23 @@ * Non-zero subprocess exit code. * Timeout. +Security +== + +This tool was written for a typical environment where software developers and +operations engineers have different permissions. The design is supposed to +make it reasonably safe for a group of developers to make auditable changes to +job configuration without help from operations engineers, and it should not be +possible for users to escalate privileges to anything but running processes as +the service user. + +It should also not be possible to run arbitrary job descriptions from a user's +home directory. We recommend deploying the `job_directory` in a way that all +changes can be audited. TODO -* Syslog actions, at least when tweezing new crontabs. * Log invocations. * Prevent future job runs when unrecoverable failure conditions are detected. * Fine-tuning of failure detection. diff --git a/job.example.yaml b/job.example.yaml new file mode 100644 index 000..8115936 --- /dev/null +++ b/job.example.yaml @@ -0,0 +1,42 @@ +# Copy this job to your configured `job_directory` and give it a name, like +# `purge_binge.yaml`. + +# Verbose job name. The short, machine name is taken from the base file name. +name: Take This Job and Shove It + +# The commandline that will be run. This is executed from Python and not from +# a shell, so globbing, redirecting, and other trickery will not work. Please +# give the full path to executables as in a crontab. +# +# Alternatively, a job can be configured
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Remove debian metadata from the main repo
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346643 ) Change subject: Remove debian metadata from the main repo .. Remove debian metadata from the main repo Change-Id: I21fa529ac5a9ee3ae145dfb21d2af39185567062 --- D debian/changelog D debian/compat D debian/control D debian/copyright D debian/docs D debian/rules D debian/source/format D debian/upstream/metadata 8 files changed, 0 insertions(+), 44 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/43/346643/1 diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 3d5dac1..000 --- a/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -process-control (0.0.1~rc1-1) UNRELEASED; urgency=low - - * Initial release. - - -- Adam Roses WightThu, 16 Mar 2017 00:12:17 -0700 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec63514..000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index bfd362a..000 --- a/debian/control +++ /dev/null @@ -1,16 +0,0 @@ -Source: process-control -Maintainer: Adam Roses Wight -Section: admin -Priority: optional -Build-Depends: debhelper (>= 9), dh-python, python-all, python-setuptools -Standards-Version: 3.9.8 -Homepage: https://github.com/adamwight/process-control -Vcs-Browser: https://github.com/adamwight/process-control -Vcs-Git: git://github.com/adamwight/process-control.git -X-Python-Version: >= 2.7 - -Package: process-control -Architecture: all -Depends: ${python:Depends}, python-argparse, python-yaml -Description: Tools for Wikimedia Foundation Fundraising job management - Control and schedule jobs using configuration files. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index cb75346..000 --- a/debian/copyright +++ /dev/null @@ -1,7 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Source: https://github.com/adamwight/process-control - -Files: * -Copyright: 2017, Adam Roses Wight -License: GPL-2 - /usr/share/common-licenses/GPL-2 diff --git a/debian/docs b/debian/docs deleted file mode 100644 index 22c7238..000 --- a/debian/docs +++ /dev/null @@ -1,2 +0,0 @@ -README.md -process-control.example.yaml diff --git a/debian/rules b/debian/rules deleted file mode 100755 index e8722a2..000 --- a/debian/rules +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/make -f - -#export DH_VERBOSE=1 -export PYBUILD_NAME=process-control - -%: - dh $@ --with=python2 --buildsystem=pybuild diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8..000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debian/upstream/metadata b/debian/upstream/metadata deleted file mode 100644 index 2922586..000 --- a/debian/upstream/metadata +++ /dev/null @@ -1,5 +0,0 @@ -Bug-Database: https://github.com/adamwight/process-control/issues -Bug-Submit: https://github.com/adamwight/process-control/issues/new -Contact: Adam Roses Wight -Repository: git://github.com/adamwight/process-control.git -Repository-Browse: https://github.com/adamwight/process-control -- To view, visit https://gerrit.wikimedia.org/r/346643 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I21fa529ac5a9ee3ae145dfb21d2af39185567062 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: add license file
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346641 ) Change subject: add license file .. add license file Change-Id: I3a8b5cf08749b96b5a784193017efa85e5d59144 --- A LICENSE.md 1 file changed, 361 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/41/346641/1 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000..af5153d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,361 @@ +### GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +### Preamble + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the +original, so that any problems introduced by others will not reflect +on the original authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at +all. + +The precise terms and conditions for copying, distribution and +modification follow. + +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +**0.** This License applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work +based on the Program" means either the Program or any derivative work +under copyright law: that is to say, a work containing the Program or +a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is +included without limitation in the term "modification".) Each licensee +is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +**1.** You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: [WIP] Fix double-failmail after timeout.
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346640 ) Change subject: [WIP] Fix double-failmail after timeout. .. [WIP] Fix double-failmail after timeout. Change-Id: Ie0cd58e9a890ecf9100f022cffec0743b9327504 --- M processcontrol/runner.py 1 file changed, 5 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/40/346640/1 diff --git a/processcontrol/runner.py b/processcontrol/runner.py index 82fa6fc..c2cbd13 100644 --- a/processcontrol/runner.py +++ b/processcontrol/runner.py @@ -17,6 +17,7 @@ self.job = job self.mailer = mailer.Mailer(self.job, self) self.logfile = None +self.killer_was_me = False def run(self): # Check that we are the service user. @@ -78,6 +79,9 @@ self.process = None def fail_exitcode(self, return_code): +if self.killer_was_me and return_code == -9: +# We already mailed and stuff. +return message = "{name} failed with code {code}".format(name=self.job.name, code=return_code) config.log.error(message) # TODO: Prevent future jobs according to config. @@ -93,12 +97,12 @@ raise JobFailure(message) def fail_timeout(self): +self.timed_out = True self.process.kill() message = "{name} timed out after {timeout} minutes".format(name=self.job.name, timeout=self.job.timeout) config.log.error(message) self.mailer.fail_mail(message) # FIXME: Job will return SIGKILL now, fail_exitcode should ignore that signal now? -raise JobFailure(message) def status(self): """Check for any running instances of this job, in this process or another. -- To view, visit https://gerrit.wikimedia.org/r/346640 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie0cd58e9a890ecf9100f022cffec0743b9327504 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Mirror child process output to console
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346586 ) Change subject: Mirror child process output to console .. Mirror child process output to console Bug: T162294 Change-Id: I79184671e345253c165d87cc5732d0b57a4b5896 --- M processcontrol/output_streamer.py 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/86/346586/1 diff --git a/processcontrol/output_streamer.py b/processcontrol/output_streamer.py index ce89d00..0728f68 100644 --- a/processcontrol/output_streamer.py +++ b/processcontrol/output_streamer.py @@ -1,5 +1,7 @@ +import logging import logging.config import os +import sys import threading from . import config @@ -72,6 +74,10 @@ self.logger.addHandler(self.log_file_handler) +if sys.stdout.isatty(): +# Mirror to the console if run interactively. +self.logger.addHandler(logging.StreamHandler(sys.stdout)) + # FIXME: gets written for each subprocess, so the name=slug is not # quite right. Should be the commandline? self.logger.info("===") -- To view, visit https://gerrit.wikimedia.org/r/346586 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I79184671e345253c165d87cc5732d0b57a4b5896 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Strip extra newline after job status
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346585 ) Change subject: Strip extra newline after job status .. Strip extra newline after job status Change-Id: Ifc95c860d8a2b84f0de03c1d6b3871531e29e0a3 --- M bin/run-job 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/85/346585/1 diff --git a/bin/run-job b/bin/run-job index 40a7bbd..1c070fe 100755 --- a/bin/run-job +++ b/bin/run-job @@ -16,7 +16,7 @@ message = "{job} - {human_name}".format(job=job_name, human_name=job.name) status = runner.JobRunner(job).status() if status is not None: - message += "" + yaml.dump(status) + message += "" + yaml.dump(status).strip() except AssertionError: message = "{job} ***Invalid configuration***".format(job=job_name) print(message) -- To view, visit https://gerrit.wikimedia.org/r/346585 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifc95c860d8a2b84f0de03c1d6b3871531e29e0a3 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Include logfile path in failmails
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346583 ) Change subject: Include logfile path in failmails .. Include logfile path in failmails Change-Id: I919594c5c1c0f5316038d6ae63267806092c433e --- M processcontrol/mailer.py M processcontrol/runner.py M tests/test_job_runner.py 3 files changed, 16 insertions(+), 11 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/83/346583/1 diff --git a/processcontrol/mailer.py b/processcontrol/mailer.py index 2d74472..8311b4e 100644 --- a/processcontrol/mailer.py +++ b/processcontrol/mailer.py @@ -4,15 +4,18 @@ class Mailer(object): -def __init__(self, config): -self.from_address = config.get("failmail/from_address") -self.to_address = config.get("failmail/to_address") +def __init__(self, job, runner): +self.job = job +self.runner = runner +self.from_address = job.config.get("failmail/from_address") +self.to_address = job.config.get("failmail/to_address") # FIXME: this is set to ensure one failmail per instance. Should # do something more sophisticated to collect all calls and send # the mail before exiting. self.sent_fail_mail = False -def fail_mail(self, subject, body="Hope your wits are freshly sharpened!"): +def fail_mail(self, subject): +body = "See the logs for more information: {logfile}".format(logfile=self.runner.logfile) if self.sent_fail_mail: return diff --git a/processcontrol/runner.py b/processcontrol/runner.py index 81aaabb..82fa6fc 100644 --- a/processcontrol/runner.py +++ b/processcontrol/runner.py @@ -15,7 +15,8 @@ def __init__(self, job): self.global_config = config.GlobalConfiguration() self.job = job -self.mailer = mailer.Mailer(self.job.config) +self.mailer = mailer.Mailer(self.job, self) +self.logfile = None def run(self): # Check that we are the service user. @@ -61,6 +62,7 @@ self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.job.environment) streamer = output_streamer.OutputStreamer(self.process, self.job.slug, self.start_time) +self.logfile = streamer.filename streamer.start() # should be safe from deadlocks because our OutputStreamer @@ -76,14 +78,14 @@ self.process = None def fail_exitcode(self, return_code): -message = "Job {name} failed with code {code}".format(name=self.job.name, code=return_code) +message = "{name} failed with code {code}".format(name=self.job.name, code=return_code) config.log.error(message) # TODO: Prevent future jobs according to config. self.mailer.fail_mail(message) raise JobFailure(message) def fail_has_stderr(self, stderr_data): -message = "Job {name} printed things to stderr:".format(name=self.job.name) +message = "{name} printed things to stderr:".format(name=self.job.name) config.log.error(message) body = stderr_data.decode("utf-8") config.log.error(body) @@ -92,7 +94,7 @@ def fail_timeout(self): self.process.kill() -message = "Job {name} timed out after {timeout} minutes".format(name=self.job.name, timeout=self.job.timeout) +message = "{name} timed out after {timeout} minutes".format(name=self.job.name, timeout=self.job.timeout) config.log.error(message) self.mailer.fail_mail(message) # FIXME: Job will return SIGKILL now, fail_exitcode should ignore that signal now? diff --git a/tests/test_job_runner.py b/tests/test_job_runner.py index a82e808..5af7fac 100644 --- a/tests/test_job_runner.py +++ b/tests/test_job_runner.py @@ -51,7 +51,7 @@ run_job("return_code") loglines = caplog.actual() -assert ("root", "ERROR", "Job False job failed with code 1") in loglines +assert ("root", "ERROR", "False job failed with code 1") in loglines MockSmtp().sendmail.assert_called_once() @@ -65,8 +65,8 @@ run_job("timeout") loglines = caplog.actual() -assert ("root", "ERROR", "Job Timing out job timed out after 0.005 minutes") in loglines -assert ("root", "ERROR", "Job Timing out job failed with code -9") in loglines +assert ("root", "ERROR", "Timing out job timed out after 0.005 minutes") in loglines +assert ("root", "ERROR", "Timing out job failed with code -9") in loglines MockSmtp().sendmail.assert_called_once() -- To view, visit https://gerrit.wikimedia.org/r/346583 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I919594c5c1c0f5316038d6ae63267806092c433e Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch:
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Split job spec from job runner
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346574 ) Change subject: Split job spec from job runner .. Split job spec from job runner Change-Id: I44e976f46c7159e02c431c470e74e54f8ad12229 --- M bin/run-job M processcontrol/crontab.py A processcontrol/job_spec.py D processcontrol/job_wrapper.py A processcontrol/runner.py R tests/test_job_runner.py 6 files changed, 197 insertions(+), 182 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/74/346574/1 diff --git a/bin/run-job b/bin/run-job index 57f893d..40a7bbd 100755 --- a/bin/run-job +++ b/bin/run-job @@ -5,7 +5,8 @@ import sys import yaml -from processcontrol import job_wrapper +from processcontrol import runner +from processcontrol import job_spec def list_jobs(): @@ -13,7 +14,7 @@ try: job = job_wrapper.load(job_name) message = "{job} - {human_name}".format(job=job_name, human_name=job.name) - status = job.status() + status = runner.JobRunner(job).status() if status is not None: message += "" + yaml.dump(status) except AssertionError: @@ -28,8 +29,9 @@ args = parser.parse_args() if args.job: - job = job_wrapper.load(args.job) - job.run() + job = job_spec.load(args.job) + runner = runner.JobRunner(job) + runner.run() if args.list_jobs: list_jobs() diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index 9359cd0..82266ca 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -1,7 +1,7 @@ from __future__ import print_function from . import config -from . import job_wrapper +from . import job_spec def make_cron(): @@ -9,12 +9,12 @@ Read all files from the dir and output a crontab. ''' -jobs = job_wrapper.list() +jobs = job_spec.list() cron_text = "" for job_name in jobs: # FIXME just use the configuration classes, no need for job -job = job_wrapper.load(job_name) +job = job_spec.load(job_name) tab = JobCrontab(job) cron_text += str(tab) diff --git a/processcontrol/job_spec.py b/processcontrol/job_spec.py new file mode 100644 index 000..200d898 --- /dev/null +++ b/processcontrol/job_spec.py @@ -0,0 +1,59 @@ +import datetime +import glob +import os + +from . import config + + +# TODO: uh has no raison d'etre now other than to demonstrate factoryness. +def load(job_name): +return Job(slug=job_name) + + +def list(): +"""Return a tuple of all available job names.""" +job_directory = config.GlobalConfiguration().get("job_directory") +paths = sorted(glob.glob(job_directory + "/*.yaml")) +file_names = [os.path.basename(p) for p in paths] +job_names = [f.replace(".yaml", "") for f in file_names] +return job_names + + +def job_path_for_slug(slug): +global_config = config.GlobalConfiguration() +job_directory = global_config.get("job_directory") +path = "{root_dir}/{slug}.yaml".format(root_dir=job_directory, slug=slug) +return path + + +class Job(object): +def __init__(self, slug=None): +self.global_config = config.GlobalConfiguration() +self.config_path = job_path_for_slug(slug) + +# Validate that we're not allowing directory traversal. +assert os.path.dirname(os.path.realpath(self.config_path)) == os.path.abspath(self.global_config.get("job_directory")) + +self.config = config.JobConfiguration(self.global_config, self.config_path) + +self.name = self.config.get("name") +self.slug = slug +self.start_time = datetime.datetime.utcnow() +if self.config.has("timeout"): +self.timeout = self.config.get("timeout") +else: +self.timeout = 0 + +if self.config.has("disabled") and self.config.get("disabled") is True: +self.enabled = False +else: +self.enabled = True + +if not self.config.has("schedule"): +self.enabled = False + +self.environment = os.environ.copy() +if self.config.has("environment"): +# Force all values to string +str_env = {k: str(v) for k, v in self.config.get("environment").items()} +self.environment.update(str_env) diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py deleted file mode 100644 index 7d9817a..000 --- a/processcontrol/job_wrapper.py +++ /dev/null @@ -1,169 +0,0 @@ -import datetime -import glob -import os -import pwd -import shlex -import subprocess -import threading - -from . import config -from . import lock -from . import mailer -from . import output_streamer - - -#
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Don't log logging settings
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346571 ) Change subject: Don't log logging settings .. Don't log logging settings Remove a not particularly helpful message. Change-Id: I97a24bee618de2eb4a5be43bd8b97bc00984d5f5 --- M processcontrol/config.py 1 file changed, 3 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/71/346571/1 diff --git a/processcontrol/config.py b/processcontrol/config.py index 8fd719c..b9913bb 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -27,13 +27,13 @@ log_config = global_config.get("logging") logging.config.dictConfig(log_config) log = logging.getLogger("process-control") -log.info("Configured logging.") -log.debug(log_config) +log.debug("Configured logging.") else: # Set to the root logger. log = logging.getLogger() if sys.stdout.isatty(): +# Also log to the console when running interactively. log.addHandler(logging.StreamHandler(sys.stdout)) @@ -59,7 +59,7 @@ return current def has(self, path): -"""Test for existance of a property. +"""Test for existence of a property. As with get(), use forward slashes to represent nested properties. """ try: -- To view, visit https://gerrit.wikimedia.org/r/346571 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I97a24bee618de2eb4a5be43bd8b97bc00984d5f5 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Syslogs point at syslogd
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346480 ) Change subject: Syslogs point at syslogd .. Syslogs point at syslogd Change-Id: I3a9e64b7c0500edb57d2c7565b507770046494fc --- M process-control.example.yaml 1 file changed, 2 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/80/346480/1 diff --git a/process-control.example.yaml b/process-control.example.yaml index d1ad3cb..7f8a8c0 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -36,6 +36,8 @@ handlers: syslog: +# Give the file or network socket where your syslogd is listening. +address: /dev/log class: logging.handlers.SysLogHandler level: DEBUG facility: daemon -- To view, visit https://gerrit.wikimedia.org/r/346480 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3a9e64b7c0500edb57d2c7565b507770046494fc Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Timeout should be given in minutes
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346344 ) Change subject: Timeout should be given in minutes .. Timeout should be given in minutes Change-Id: I61aa8d4d5ec8a5956d3bd67a59d95483290b2b60 --- M README.md M processcontrol/job_wrapper.py 2 files changed, 5 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/44/346344/1 diff --git a/README.md b/README.md index f530113..60b662e 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ # can still be run as a single-shot. disabled: true -# Optional timeout in seconds, after which your job will be -# aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT +# Optional timeout in minutes, after which your job will be +# aborted. Defaults to no timeout. timeout: 30 # Optional environment variables. diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 4f9ff6c..6f19f70 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -81,7 +81,9 @@ # Spawn timeout monitor thread. if self.timeout > 0: -timer = threading.Timer(self.timeout, self.fail_timeout) +# Convert minutes to seconds. +timeout_seconds = self.timeout * 60 +timer = threading.Timer(timeout_seconds, self.fail_timeout) timer.start() command = self.config.get("command") -- To view, visit https://gerrit.wikimedia.org/r/346344 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I61aa8d4d5ec8a5956d3bd67a59d95483290b2b60 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Cast environment variables to string
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346317 ) Change subject: Cast environment variables to string .. Cast environment variables to string execve can't handle numeric types, etc. Change-Id: Id61436f1fbbd550816912a0caaac51ebc753d5a4 --- M processcontrol/job_wrapper.py M tests/data/env.yaml M tests/test_job_wrapper.py 3 files changed, 7 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/17/346317/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index b09bda1..44b1ccf 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -58,7 +58,9 @@ self.environment = os.environ.copy() if self.config.has("environment"): -self.environment.update(self.config.get("environment")) +# Force all values to string +str_env = {k: str(v) for k, v in self.config.get("environment").items()} +self.environment.update(str_env) def run(self): # Check that we are the service user. diff --git a/tests/data/env.yaml b/tests/data/env.yaml index bdc5ef3..062bdfb 100644 --- a/tests/data/env.yaml +++ b/tests/data/env.yaml @@ -3,3 +3,5 @@ environment: foo1: bar foo2: rebar +foo3: 123 +foo4: true diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index ea6062e..66aba0d 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -102,4 +102,6 @@ assert "INFO\tfoo1=bar" in lines assert "INFO\tfoo2=rebar" in lines +assert "INFO\tfoo3=123" in lines +assert "INFO\tfoo4=True" in lines assert "INFO\tMYENV=pre-existing" in lines -- To view, visit https://gerrit.wikimedia.org/r/346317 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id61436f1fbbd550816912a0caaac51ebc753d5a4 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Fix CLI syntax for run-job in the generated crontab
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346314 ) Change subject: Fix CLI syntax for run-job in the generated crontab .. Fix CLI syntax for run-job in the generated crontab Change-Id: Ifc9d94e279167de3bdeeedd91b18f1cb002e8f1b --- M processcontrol/crontab.py 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/14/346314/1 diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index 57e4abe..9359cd0 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -42,7 +42,7 @@ if not self.enabled: return "# Skipping disabled job {name}\n".format(name=self.job.slug) -command = "{runner} {name}".format( +command = "{runner} --job {name}".format( runner=self.job.global_config.get("runner_path"), name=self.job.slug) -- To view, visit https://gerrit.wikimedia.org/r/346314 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifc9d94e279167de3bdeeedd91b18f1cb002e8f1b Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Copy logging to stdout when run interactively
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346230 ) Change subject: Copy logging to stdout when run interactively .. Copy logging to stdout when run interactively Change-Id: I69cdf23df9e5e04384c2f306d8c3a1e69c56f805 --- M processcontrol/config.py 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/30/346230/1 diff --git a/processcontrol/config.py b/processcontrol/config.py index c7771a4..8fd719c 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -2,6 +2,7 @@ import logging import logging.config import os +import sys import yaml @@ -32,6 +33,9 @@ # Set to the root logger. log = logging.getLogger() +if sys.stdout.isatty(): +log.addHandler(logging.StreamHandler(sys.stdout)) + class Configuration(): -- To view, visit https://gerrit.wikimedia.org/r/346230 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I69cdf23df9e5e04384c2f306d8c3a1e69c56f805 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Protect against symlinks and ".." directory transversal
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346229 ) Change subject: Protect against symlinks and ".." directory transversal .. Protect against symlinks and ".." directory transversal Change-Id: I3010eb948e51c09ed7b18e94246b951aa4140634 --- M processcontrol/job_wrapper.py 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/29/346229/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 3ec58bf..f3c9ca2 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -37,6 +37,10 @@ def __init__(self, slug=None): self.global_config = config.GlobalConfiguration() self.config_path = job_path_for_slug(slug) + +# Validate that we're not allowing directory traversal. +assert os.path.dirname(os.path.realpath(self.config_path)) == os.path.abspath(self.global_config.get("job_directory")) + self.config = config.JobConfiguration(self.global_config, self.config_path) self.name = self.config.get("name") -- To view, visit https://gerrit.wikimedia.org/r/346229 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3010eb948e51c09ed7b18e94246b951aa4140634 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Assert stderr goes to the output file
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346207 ) Change subject: Assert stderr goes to the output file .. Assert stderr goes to the output file Change-Id: Iaddb2bbae18a4e733842998995b6b84982b507af --- M tests/test_job_wrapper.py 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/07/346207/1 diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index e02d3af..73cf23d 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -78,6 +78,9 @@ assert ("errors", "ERROR", "grep: Invalid regular expression") in loglines # TODO: Should we go out of our way to log the non-zero return code as well? +lines = get_output_lines("errors") +assert "ERROR\tgrep: Invalid regular expression" in lines + MockSmtp().sendmail.assert_called_once() -- To view, visit https://gerrit.wikimedia.org/r/346207 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaddb2bbae18a4e733842998995b6b84982b507af Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Only run jobs as the service user
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/346202 ) Change subject: Only run jobs as the service user .. Only run jobs as the service user Change-Id: Ia12f06f07a1b4d77b6fa3f69fc121ab1c1b10419 --- M process-control.example.yaml M processcontrol/job_wrapper.py M tests/data/global_config/global_defaults.yaml M tests/override_config.py 4 files changed, 13 insertions(+), 6 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/02/346202/1 diff --git a/process-control.example.yaml b/process-control.example.yaml index 2891458..0cbe639 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -6,8 +6,8 @@ # Absolute path to the job harness. runner_path: /usr/bin/run-job -# Cron will setuid to this user before running the command. Only use service -# accounts, never privileged ones. +# Enforce that jobs are run as this service user. +# FIXME: new service user for this package. user: jenkins # Default values used when the job description doesn't have these keys. See diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 5d83afb..3ec58bf 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -1,6 +1,7 @@ import datetime import glob import os +import pwd import shlex import subprocess import threading @@ -61,6 +62,14 @@ self.environment = {} def run(self): +# Check that we are the service user. +service_user = str(self.global_config.get("user")) +if service_user.isdigit(): +passwd_entry = pwd.getpwuid(int(service_user)) +else: +passwd_entry = pwd.getpwnam(service_user) +assert passwd_entry.pw_uid == os.getuid() + lock.begin(job_tag=self.slug) config.log.info("Running job {name} ({slug})".format(name=self.name, slug=self.slug)) diff --git a/tests/data/global_config/global_defaults.yaml b/tests/data/global_config/global_defaults.yaml index e2ac795..daca679 100644 --- a/tests/data/global_config/global_defaults.yaml +++ b/tests/data/global_config/global_defaults.yaml @@ -6,10 +6,6 @@ # Absolute path to the job harness. runner_path: /usr/bin/run-job -# Cron will setuid to this user before running the command. Only use service -# accounts, never privileged ones. -user: jenkins - # Default values used when the job description doesn't have these keys. See # the README for a discussion of how to configure jobs. default_job_config: diff --git a/tests/override_config.py b/tests/override_config.py index 973813e..b1ef2ed 100644 --- a/tests/override_config.py +++ b/tests/override_config.py @@ -21,6 +21,8 @@ elif "job_directory" not in extra: extra["job_directory"] = data_dir +extra["user"] = os.getuid() + OverrideConfiguration.extra = extra global patcher -- To view, visit https://gerrit.wikimedia.org/r/346202 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia12f06f07a1b4d77b6fa3f69fc121ab1c1b10419 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Relax a test until we can fix the potential double-failmail.
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345781 ) Change subject: Relax a test until we can fix the potential double-failmail. .. Relax a test until we can fix the potential double-failmail. Change-Id: If5c1a2eb516b30704bdae599236aa6512c5deca2 --- M tests/test_job_wrapper.py 1 file changed, 2 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/81/345781/1 diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index 13b009b..798ac1d 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -65,7 +65,8 @@ assert ("root", "ERROR", "Job Timing out job timed out after 0.1 seconds") in loglines assert ("root", "ERROR", "Job Timing out job failed with code -9") in loglines -MockSmtp().sendmail.assert_called_once() +# FIXME: Sometimes called twice, once with each error! Relaxing the test for now. +MockSmtp().sendmail.assert_called() @mock.patch("smtplib.SMTP") -- To view, visit https://gerrit.wikimedia.org/r/345781 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If5c1a2eb516b30704bdae599236aa6512c5deca2 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Wrap yaml load in file context managers
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345660 ) Change subject: Wrap yaml load in file context managers .. Wrap yaml load in file context managers Change-Id: I8b424749ceb6dd55b8c0b729a0546ec654cdd650 --- M processcontrol/config.py 1 file changed, 6 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/60/345660/1 diff --git a/processcontrol/config.py b/processcontrol/config.py index 2828293..c7771a4 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -85,7 +85,8 @@ Later entries override earlier entries. """ if os.access(CONFIG_PATH, os.R_OK): -config = yaml.safe_load(open(CONFIG_PATH, "r")) +with open(CONFIG_PATH, "r") as f: +config = yaml.safe_load(f) self.values.update(config) self.validate_global_config() @@ -107,7 +108,10 @@ else: defaults = {} Configuration.__init__(self, defaults) -self.values.update(yaml.safe_load(open(config_path, "r"))) + +with open(config_path, "r") as f: +self.values.update(yaml.safe_load(f)) + # TODO: Catch and interpret errors. self.validate_job_config() -- To view, visit https://gerrit.wikimedia.org/r/345660 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8b424749ceb6dd55b8c0b729a0546ec654cdd650 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Document hardcoded /etc path
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345654 ) Change subject: Document hardcoded /etc path .. Document hardcoded /etc path Change-Id: Id89f919f80724e6955f8480a33801bd672be9c10 --- M process-control.example.yaml 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/54/345654/1 diff --git a/process-control.example.yaml b/process-control.example.yaml index 2891458..132b158 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -1,3 +1,6 @@ +# Example configuration with reasonable defaults. +# Please copy to /etc/process-control.yaml and customize. + # This is how each of your jobs will be formatted by cron-generate. cron_template: | # Generated from {source} -- To view, visit https://gerrit.wikimedia.org/r/345654 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id89f919f80724e6955f8480a33801bd672be9c10 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: "make clean" target
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345482 ) Change subject: "make clean" target .. "make clean" target Change-Id: I9f164531afdd765321dd466372ba7c4be9cd1173 --- M Makefile 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/82/345482/1 diff --git a/Makefile b/Makefile index fb7bc49..a8e6b7b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ .PHONY: \ + clean \ coverage \ deb @@ -8,6 +9,11 @@ noop: @echo Nothing to do! +clean: + rm -rf debian/process-control* + rm -f debian/files + rm -f debian/debhelper-build-stamp + coverage: nosetests --with-coverage --cover-package=processcontrol --cover-html @echo Results are in cover/index.html -- To view, visit https://gerrit.wikimedia.org/r/345482 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9f164531afdd765321dd466372ba7c4be9cd1173 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Remove unnecessary build dependency
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345483 ) Change subject: Remove unnecessary build dependency .. Remove unnecessary build dependency Note that the deb packaging for precise still requires this. Change-Id: I508f6c9cb8a92f65e50208490abbcf13606d70d7 --- M debian/control 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/83/345483/1 diff --git a/debian/control b/debian/control index bfd362a..db3446a 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Maintainer: Adam Roses WightSection: admin Priority: optional -Build-Depends: debhelper (>= 9), dh-python, python-all, python-setuptools +Build-Depends: debhelper (>= 9), python-all, python-setuptools Standards-Version: 3.9.8 Homepage: https://github.com/adamwight/process-control Vcs-Browser: https://github.com/adamwight/process-control -- To view, visit https://gerrit.wikimedia.org/r/345483 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I508f6c9cb8a92f65e50208490abbcf13606d70d7 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Short -l flag for --list-jobs
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345480 ) Change subject: Short -l flag for --list-jobs .. Short -l flag for --list-jobs Change-Id: I9dfa92e0bcad0bb8b5d3206e753261f2aa120a93 --- M bin/run-job 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/80/345480/1 diff --git a/bin/run-job b/bin/run-job index fe97a25..57f893d 100755 --- a/bin/run-job +++ b/bin/run-job @@ -24,7 +24,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Run and maintain process-control jobs.") parser.add_argument("-j", "--job", help="Run a given job.", type=str) - parser.add_argument("--list-jobs", help="Print a summary of available jobs.", action='store_true') + parser.add_argument("-l", "--list-jobs", help="Print a summary of available jobs.", action='store_true') args = parser.parse_args() if args.job: -- To view, visit https://gerrit.wikimedia.org/r/345480 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9dfa92e0bcad0bb8b5d3206e753261f2aa120a93 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Force a pythonic build, ignoring the Makefile
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345479 ) Change subject: Force a pythonic build, ignoring the Makefile .. Force a pythonic build, ignoring the Makefile Note that the deb packaging for precise still requires" dh-python" in Build-Depends... Change-Id: I07b0eb432c4f6fc6709709eda58e0861117e49bf --- M Makefile M debian/control M debian/rules 3 files changed, 8 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/79/345479/1 diff --git a/Makefile b/Makefile index fb7bc49..a8e6b7b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ .PHONY: \ + clean \ coverage \ deb @@ -8,6 +9,11 @@ noop: @echo Nothing to do! +clean: + rm -rf debian/process-control* + rm -f debian/files + rm -f debian/debhelper-build-stamp + coverage: nosetests --with-coverage --cover-package=processcontrol --cover-html @echo Results are in cover/index.html diff --git a/debian/control b/debian/control index bfd362a..db3446a 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Maintainer: Adam Roses WightSection: admin Priority: optional -Build-Depends: debhelper (>= 9), dh-python, python-all, python-setuptools +Build-Depends: debhelper (>= 9), python-all, python-setuptools Standards-Version: 3.9.8 Homepage: https://github.com/adamwight/process-control Vcs-Browser: https://github.com/adamwight/process-control diff --git a/debian/rules b/debian/rules index 6af70d4..aa7fd0c 100755 --- a/debian/rules +++ b/debian/rules @@ -4,4 +4,4 @@ export PYBUILD_NAME=process-control %: - dh $@ --with python2 + dh $@ -Spython_distutils --with python2 -- To view, visit https://gerrit.wikimedia.org/r/345479 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I07b0eb432c4f6fc6709709eda58e0861117e49bf Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Run commands in sequence
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345429 ) Change subject: Run commands in sequence .. Run commands in sequence Bug: T161035 Change-Id: I6f4473881da4e81bab1777bf747ee87e6d1d61d1 --- M README.md M processcontrol/job_wrapper.py 2 files changed, 24 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/29/345429/1 diff --git a/README.md b/README.md index 8eed1fc..f530113 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,16 @@ # The commandline that will be run. This is executed from Python and not from # a shell, so globbing and other trickery will not work. Please give a full # path to the executable. +# +# Alternatively, a job can be configured as a list of several commands. These +# are executed in sequence, and execution stops at the first failure. +# +#command: +## Run sub-jobs, each with their own lock and logfiles. +#- /usr/bin/run-job prepare_meal +#- /usr/bin/run-job mangia +#- /usr/bin/run-job clean_up_from_meal +# command: /usr/local/bin/timecard --start 9:00 --end 5:30 # Optional schedule, in Vixie cron format: diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 321798b..319dcbd 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -61,7 +61,20 @@ config.log.info("Running job {name} ({slug})".format(name=self.name, slug=self.slug)) -command = shlex.split(self.config.get("command")) +command = self.config.get("command") + +if hasattr(command, "encode"): +# Is stringlike, wrap it in a list so we can handle along with the +# plural case below. +command = [command] + +for line in command: +self.run_command(line) + +def run_command(command_string) +config.log.info("Running command: {cmd}".format(cmd=command_string)) + +command = shlex.split(command_string) self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.environment) timer = threading.Timer(self.timeout, self.fail_timeout) -- To view, visit https://gerrit.wikimedia.org/r/345429 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6f4473881da4e81bab1777bf747ee87e6d1d61d1 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Bump version: 0.0.2
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345273 ) Change subject: Bump version: 0.0.2 .. Bump version: 0.0.2 Change-Id: I2b80ed8663fb1ea8a615da65d5b29ea5dabfbf64 --- M Makefile M debian/changelog 2 files changed, 34 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/73/345273/1 diff --git a/Makefile b/Makefile index fb7bc49..2356d89 100644 --- a/Makefile +++ b/Makefile @@ -15,5 +15,5 @@ deb: @echo Note that this is not how we build our production .deb # FIXME: fragile - cd ..; tar cjf process-control_0.0.1~rc1.orig.tar.bz2 process-control; cd process-control + cd ..; tar cjf process-control_0.0.2~rc1.orig.tar.bz2 process-control; cd process-control debuild -us -uc diff --git a/debian/changelog b/debian/changelog index 3d5dac1..e5d3780 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,36 @@ +process-control (0.0.2~rc1-1) UNRELEASED; urgency=low + + 2fa8ab3 Merge "Show jobs with invalid configuration in --list-jobs" + 4c2cb74 Configurable working files directory, run_dir + 0857d19 Merge "Fix logging.config import" + 967acc6 Fix logging.config import + fe9d83e Show jobs with invalid configuration in --list-jobs + 5c34abb --list-jobs action + 7863c2a Log notable events + 887373b Log, don't print + 9aa7a60 Initialize Python logging from global configuration + 718b71c Merge "ignore build products" + 8f03e3a Merge "Makefile for lulz" + 538cfce Makefile for lulz + e4e4e6b Scripts take no CLI arguments + 19e710c Store job slug + 560aba0 Merge "Test for environment parameter" + 5708160 Test for environment parameter + 39026aa ignore build products + 25fccb7 Fixes suggested by thcipriani + 68c4b68 Use argparse to read the CLI; cron-generate is flaggy rather than + pipey + 46680f2 Pass environment variables to the subprocess + 40e8227 Copy example configuration to docs during install + 9520fd8 More cron syntax checks + 90f61d3 Introducing output_directory, where we save a file per run + fedda2f Remove unused config inline defaults + 61e4bd5 Comments and cleanup for config + b377335 Move some things into global config + 50bca17 Config objects + + -- Adam Roses WightWed, 29 Mar 2017 00:12:17 -0700 + process-control (0.0.1~rc1-1) UNRELEASED; urgency=low * Initial release. -- To view, visit https://gerrit.wikimedia.org/r/345273 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2b80ed8663fb1ea8a615da65d5b29ea5dabfbf64 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: mini-lock login encapsulation
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345265 ) Change subject: mini-lock login encapsulation .. mini-lock login encapsulation Change-Id: I432e10c6ec653af7ec49c97aed910c9695285985 --- M processcontrol/job_wrapper.py M processcontrol/lock.py 2 files changed, 9 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/65/345265/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 83f396a..fa72eab 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -140,9 +140,8 @@ Do not use this function to gate the workflow, explicitly assert the lock instead.""" -# FIXME: DRY -run_dir = self.global_config.get("run_directory") -lock_path = "/{run_dir}/{name}.lock".format(run_dir=run_dir, name=self.slug) +# FIXME: DRY--find a good line to cut at to split out lock.read_pid. +lock_path = lock.path_for_job(self.slug) if os.path.exists(lock_path): with open(lock_path, "r") as f: pid = int(f.read().strip()) diff --git a/processcontrol/lock.py b/processcontrol/lock.py index b5142ad..004439a 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -11,10 +11,15 @@ lockfile = None +def path_for_job(job_name): +run_dir = config.GlobalConfiguration().get("run_directory") +filename = "{run_dir}/{name}.lock".format(run_dir=run_dir, name=job_name) +return filename + + # TODO: Decide whether we want to failopen? def begin(failopen=False, job_tag=None): -run_dir = config.GlobalConfiguration().get("run_directory") -filename = "{run_dir}/{name}.lock".format(run_dir=run_dir, name=job_tag) +filename = path_for_job(job_tag) if os.path.exists(filename): config.log.error("Lockfile found!") -- To view, visit https://gerrit.wikimedia.org/r/345265 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I432e10c6ec653af7ec49c97aed910c9695285985 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Nicer log capture
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345260 ) Change subject: Nicer log capture .. Nicer log capture Change-Id: I9e7d92a75823e3bff80a53694d712ab48fb63a8f --- M tests/test_job_wrapper.py 1 file changed, 18 insertions(+), 18 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/60/345260/1 diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index 3be5448..8f312eb 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -29,12 +29,12 @@ @mock.patch("smtplib.SMTP") -def test_return_code(MockSmtp): -with testfixtures.LogCapture() as caplog: -run_job("return_code") +@testfixtures.log_capture() +def test_return_code(MockSmtp, caplog): +run_job("return_code") -loglines = caplog.actual() -assert ("root", "ERROR", "Job False job failed with code 1") in loglines +loglines = caplog.actual() +assert ("root", "ERROR", "Job False job failed with code 1") in loglines MockSmtp().sendmail.assert_called_once() @@ -42,26 +42,26 @@ # Must finish in less than two seconds, i.e. must have timed out. @nose.tools.timed(2) @mock.patch("smtplib.SMTP") -def test_timeout(MockSmtp): -with testfixtures.LogCapture() as caplog: -run_job("timeout") +@testfixtures.log_capture() +def test_timeout(MockSmtp, caplog): +run_job("timeout") -loglines = caplog.actual() -assert ("root", "ERROR", "Job Timing out job timed out after 0.1 seconds") in loglines -assert ("root", "ERROR", "Job Timing out job failed with code -9") in loglines +loglines = caplog.actual() +assert ("root", "ERROR", "Job Timing out job timed out after 0.1 seconds") in loglines +assert ("root", "ERROR", "Job Timing out job failed with code -9") in loglines MockSmtp().sendmail.assert_called_once() @mock.patch("smtplib.SMTP") -def test_stderr(MockSmtp): -with testfixtures.LogCapture() as caplog: -run_job("errors") +@testfixtures.log_capture() +def test_stderr(MockSmtp, caplog): +run_job("errors") -loglines = list(caplog.actual()) -assert ("root", "ERROR", "Job Bad grep job printed things to stderr:") in loglines -assert ("root", "ERROR", "grep: Invalid regular expression\n") in loglines -assert ("root", "ERROR", "Job Bad grep job failed with code 2") in loglines +loglines = list(caplog.actual()) +assert ("root", "ERROR", "Job Bad grep job printed things to stderr:") in loglines +assert ("root", "ERROR", "grep: Invalid regular expression\n") in loglines +assert ("root", "ERROR", "Job Bad grep job failed with code 2") in loglines MockSmtp().sendmail.assert_called_once() -- To view, visit https://gerrit.wikimedia.org/r/345260 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9e7d92a75823e3bff80a53694d712ab48fb63a8f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Log notable events
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345236 ) Change subject: Log notable events .. Log notable events Change-Id: I668b70ce8701a4e1ad3de8420b7e49f17190f6dd --- M bin/cron-generate M bin/run-job M processcontrol/crontab.py M processcontrol/job_wrapper.py 4 files changed, 7 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/36/345236/1 diff --git a/bin/cron-generate b/bin/cron-generate index 6e8b04d..af5e66d 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,6 +1,5 @@ #!/usr/bin/python -from __future__ import print_function import sys from processcontrol import crontab diff --git a/bin/run-job b/bin/run-job index 974c4f2..2f45b32 100755 --- a/bin/run-job +++ b/bin/run-job @@ -5,6 +5,7 @@ import subprocess import sys +from processcontrol import config from processcontrol import job_wrapper @@ -24,10 +25,10 @@ print("Nothing to kill.") else: pid = status["pid"] - print("Killing job {name}, pid {pid}".format(name=job_name, pid=pid)) + config.log.info("Killing job {name}, pid {pid}".format(name=job_name, pid=pid)) exit_code = subprocess.call(["kill", str(pid)]) if exit_code != 0: - print("Failed to kill!", file=sys.stderr) + config.log.error("Failed to kill!", file=sys.stderr) if __name__ == "__main__": diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index b099e11..1ba7e2b 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -19,6 +19,8 @@ global_config = config.GlobalConfiguration() output_file = global_config.get("output_crontab") +config.log.info("Writing crontab to {out}".format(out=output_file)) + if output_file == 'console': print(cron_text) else: diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 61c396c..902655a 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -63,6 +63,8 @@ def run(self): lock.begin(job_tag=self.slug) +config.log.info("Running job {name} ({slug})".format(name=self.name, slug=self.slug)) + command = shlex.split(self.config.get("command")) signal.signal(signal.SIGTERM, self.handle_sigterm) signal.signal(signal.SIGINT, self.handle_sigterm) -- To view, visit https://gerrit.wikimedia.org/r/345236 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I668b70ce8701a4e1ad3de8420b7e49f17190f6dd Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Log, don't print
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345221 ) Change subject: Log, don't print .. Log, don't print Change-Id: I35f263e6bba7fe4bfa16e5bfba57e39cf436cd18 --- M processcontrol/job_wrapper.py M processcontrol/lock.py M test-requirements.txt M tests/test_job_wrapper.py 4 files changed, 38 insertions(+), 51 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/21/345221/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 4d3892e..a2b8838 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -1,10 +1,8 @@ -from __future__ import print_function import datetime import glob import os import shlex import subprocess -import sys import threading from . import config @@ -79,21 +77,21 @@ def fail_exitcode(self, return_code): message = "Job {name} failed with code {code}".format(name=self.name, code=return_code) -print(message, file=sys.stderr) +config.log.error(message) # TODO: Prevent future jobs according to config. self.mailer.fail_mail(message) def fail_has_stderr(self, stderr_data): message = "Job {name} printed things to stderr:".format(name=self.name) -print(message, file=sys.stderr) +config.log.error(message) body = stderr_data.decode("utf-8") -print(body, file=sys.stderr) +config.log.error(body) self.mailer.fail_mail(message, body) def fail_timeout(self): self.process.kill() message = "Job {name} timed out after {timeout} seconds".format(name=self.name, timeout=self.timeout) -print(message, file=sys.stderr) +config.log.error(message) self.mailer.fail_mail(message) # FIXME: Job will return SIGKILL now, fail_exitcode should ignore that signal now? @@ -114,7 +112,7 @@ "{name} ({pid}), started at {time}\n" "---\n" ).format(name=self.name, pid=self.process.pid, time=self.start_time.isoformat()) -print(header, file=out) +out.write(header) if len(stdout_data) == 0: buf = "* No output *\n" @@ -124,10 +122,10 @@ if len(stderr_data) > 0: header = ( -"---\n", -"Even worse, the job emitted errors:\n", -"---\n", +"---\n" +"Even worse, the job emitted errors:\n" +"---\n" ) -print(header, file=out) +out.write(header) out.write(stderr_data.decode("utf-8")) diff --git a/processcontrol/lock.py b/processcontrol/lock.py index 6af0bb5..24df5a2 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -3,9 +3,8 @@ Self-corrects stale locks unless "failopen" is True. ''' -from __future__ import print_function +import config import os -import sys lockfile = None @@ -15,7 +14,7 @@ filename = "/tmp/{name}.lock".format(name=job_tag) if os.path.exists(filename): -print("Lockfile found!", file=sys.stderr) +config.log.error("Lockfile found!") with open(filename, "r") as f: pid = None try: @@ -24,7 +23,7 @@ pass if not pid: -print("Invalid lockfile contents.", file=sys.stderr) +config.log.error("Invalid lockfile contents.") else: try: os.getpgid(pid) @@ -32,11 +31,12 @@ except OSError: if failopen: raise LockError("Aborting until stale lockfile is investigated: {path}".format(path=filename)) -print("Lockfile is stale.", file=sys.stderr) -print("Removing old lockfile.", file=sys.stderr) +config.log.error("Lockfile is stale.") +config.log.error("Removing old lockfile.") os.unlink(filename) with open(filename, "w") as f: +config.log.info("Writing lockfile.") f.write(str(os.getpid())) global lockfile @@ -46,6 +46,7 @@ def end(): global lockfile if lockfile and os.path.exists(lockfile): +config.log.info("Clearing lockfile.") os.unlink(lockfile) else: raise LockError("Already unlocked!") diff --git a/test-requirements.txt b/test-requirements.txt index fb6d7c7..d503db3 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,5 +1,5 @@ -iocapture mock nose -pytest nose-cov +pytest +testfixtures diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index e85500a..8490826 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -1,8 +1,8 @@ import glob -import iocapture import mock
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Initialize Python logging from global configuration
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345202 ) Change subject: Initialize Python logging from global configuration .. Initialize Python logging from global configuration Change-Id: I15a85d4b7a1ef0437519102e8e2da0c9d4c5cecd --- M process-control.example.yaml M processcontrol/config.py 2 files changed, 48 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/02/345202/1 diff --git a/process-control.example.yaml b/process-control.example.yaml index ce742db..5f8c9cf 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -21,6 +21,32 @@ job_directory: /var/lib/process-control +# Python logging config, https://docs.python.org/2/library/logging.config.html#logging-config-dictschema +logging: +version: 1 +#formatters: +#- + +#filters: +#- + +handlers: +syslog: +class: logging.handlers.SysLogHandler +level: DEBUG +facility: daemon + +loggers: +process-control: +handlers: +- syslog + +level: DEBUG + +disable_existing_loggers: false +#root: do we need this? + + # Output file path. # # Magic string "console" will send the crontab to stdout. diff --git a/processcontrol/config.py b/processcontrol/config.py index d9cc92e..a13d244 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -1,9 +1,28 @@ import copy +import logging import os import yaml CONFIG_PATH = "/etc/process-control.yaml" + +# FIXME: Offload responsibility for logging. +log = None + + +def setup_logging(): +global log + +if log is not None: +# Already initialized. +return + +if GlobalConfiguration().has("logging"): +log_config = GlobalConfiguration().get("logging") +logging.config.dictConfig(log_config) +log = logging.getLogger("process-control") +log.info("Configured logging.") +log.debug(log_config) class Configuration(): @@ -50,6 +69,9 @@ Configuration.__init__(self) self.load_global_config() +# Opportunistic place to initialize logging: +setup_logging() + def load_global_config(self): """Load configuration from global config paths. Later entries override earlier entries. -- To view, visit https://gerrit.wikimedia.org/r/345202 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I15a85d4b7a1ef0437519102e8e2da0c9d4c5cecd Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Only speak in slugs
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345094 ) Change subject: Only speak in slugs .. Only speak in slugs Don't use direct job paths, even internally. Slugs are always relative to the configured job_directory. Change-Id: I313296d4836c9cabbf9becf3051729be867190ea --- M processcontrol/job_wrapper.py M tests/override_config.py M tests/test_job_wrapper.py 3 files changed, 31 insertions(+), 20 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/94/345094/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index d84b83e..fff2cd8 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -12,10 +12,9 @@ from . import mailer +# TODO: uh has no raison d'etre now other than to demonstrate factoryness. def load(job_name): -job_directory = config.GlobalConfiguration().get("job_directory") -job_path = "{job_dir}/{job_name}.yaml".format(job_dir=job_directory, job_name=job_name) -return JobWrapper(config_path=job_path, slug=job_name) +return JobWrapper(slug=job_name) def list(): @@ -27,10 +26,17 @@ return job_names +def job_path_for_slug(slug): +global_config = config.GlobalConfiguration() +job_directory = global_config.get("job_directory") +path = "{root_dir}/{slug}.yaml".format(root_dir=job_directory, slug=slug) +return path + + class JobWrapper(object): -def __init__(self, config_path=None, slug=None): +def __init__(self, slug=None): self.global_config = config.GlobalConfiguration() -self.config_path = config_path +self.config_path = job_path_for_slug(slug) self.config = config.JobConfiguration(self.global_config, self.config_path) self.name = self.config.get("name") @@ -53,7 +59,7 @@ self.environment = {} def run(self): -lock.begin(job_tag=self.name) +lock.begin(job_tag=self.slug) command = shlex.split(self.config.get("command")) diff --git a/tests/override_config.py b/tests/override_config.py index dee4bd9..ca25179 100644 --- a/tests/override_config.py +++ b/tests/override_config.py @@ -15,11 +15,15 @@ """Start mocking GlobalConfiguration""" OverrideConfiguration.config_path = config_path +print("config_path", config_path) -if job_subdir is not None: +if job_subdir is None: +extra["job_directory"] = data_dir +else: extra["job_directory"] = data_dir + "/" + job_subdir OverrideConfiguration.extra = extra +print("extra", extra) global patcher patcher = mock.patch('processcontrol.config.GlobalConfiguration', wraps=OverrideConfiguration) @@ -27,6 +31,7 @@ def stop(): +global patcher patcher.stop() diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index 87a399a..2231b20 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -9,24 +9,24 @@ from . import override_config -data_dir = os.path.dirname(__file__) + "/data" -JOB_DIR = data_dir - - def setup_module(): override_config.start() -def run_job(filename): -path = data_dir + "/" + filename -job = job_wrapper.JobWrapper(config_path=path) +def teardown_module(): +override_config.stop() + +def run_job(job_name): +job = job_wrapper.load(job_name) job.run() def test_success(): +# TODO: Also test success with output_path=console, cos it's unique in not +# having stderr. with iocapture.capture() as captured: -run_job("successful.yaml") +run_job("successful") assert captured.stdout == "" assert captured.stderr == "" @@ -36,7 +36,7 @@ def test_return_code(MockSmtp): expected = "Job False job failed with code 1\n" with iocapture.capture() as captured: -run_job("return_code.yaml") +run_job("return_code") assert captured.stdout == "" assert captured.stderr == expected @@ -49,7 +49,7 @@ @mock.patch("smtplib.SMTP") def test_timeout(MockSmtp): with iocapture.capture() as captured: -run_job("timeout.yaml") +run_job("timeout") assert captured.stdout == "" assert captured.stderr == ( @@ -63,7 +63,7 @@ @mock.patch("smtplib.SMTP") def test_stderr(MockSmtp): with iocapture.capture() as captured: -run_job("errors.yaml") +run_job("errors") assert captured.stdout == "" assert captured.stderr == ( @@ -78,7 +78,7 @@ def test_store_output(): path_glob = "/tmp/Which job/Which job*.log" -run_job("which_out.yaml") +run_job("which_out") log_files = sorted(glob.glob(path_glob)) path = log_files[-1] @@ -94,7 +94,7 @@ def test_environment(): path_glob = "/tmp/Env dumper/Env dumper*.log" -run_job("env.yaml") +run_job("env") log_files =
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: [WIP] Tests for signal handling
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345095 ) Change subject: [WIP] Tests for signal handling .. [WIP] Tests for signal handling Change-Id: Ibf6ccd57709c6acae705b450153d067b658695d3 --- M processcontrol/lock.py A tests/data/sleep_2.yaml M tests/test_job_wrapper.py 3 files changed, 26 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/95/345095/1 diff --git a/processcontrol/lock.py b/processcontrol/lock.py index 0ea66ed..b3ed119 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -10,9 +10,9 @@ lockfile = None -def begin(filename=None, failopen=False, job_tag=None): +def begin(filename=None, failopen=False, job_slug=None): if not filename: -filename = "/tmp/{name}.lock".format(name=job_tag) +filename = "/tmp/{name}.lock".format(name=job_slug) if os.path.exists(filename): print("Lockfile found!", file=sys.stderr) diff --git a/tests/data/sleep_2.yaml b/tests/data/sleep_2.yaml new file mode 100644 index 000..55cccaa --- /dev/null +++ b/tests/data/sleep_2.yaml @@ -0,0 +1,2 @@ +name: Known lazy job +command: /bin/sleep 2 diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index 2a256f9..4ec5e8a 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -3,6 +3,8 @@ import mock import nose import os +import signal +import threading from processcontrol import job_wrapper @@ -111,3 +113,23 @@ assert expected == dumped_env os.unlink(path) + + +# Prove we've been interrupted before the sleep finishes naturally. +@nose.tools.timed(1) +def test_signal(): +def interrupt(): +# TODO: Rebase and replace with lock.status stuff. +pid = int(open("/tmp/sleep_2.lock", "r").read()) +print(pid) +os.kill(pid, signal.SIGKILL) + +print("DOIT") +timer = threading.Timer(0.5, interrupt) +timer.start() + +with iocapture.capture() as captured: +run_job("sleep_2.yaml") + +assert captured.stdout == "" +assert captured.stderr == "" -- To view, visit https://gerrit.wikimedia.org/r/345095 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibf6ccd57709c6acae705b450153d067b658695d3 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Configurable working files directory, run_dir
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345089 ) Change subject: Configurable working files directory, run_dir .. Configurable working files directory, run_dir Change-Id: Ib34b5cd3753ddf52832cd80d71dc7da0f98c298c --- M process-control.example.yaml M processcontrol/lock.py M tests/data/global_defaults.yaml 3 files changed, 18 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/89/345089/1 diff --git a/process-control.example.yaml b/process-control.example.yaml index ce742db..15b41ea 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -33,3 +33,11 @@ #/var/log/process-control/jobname/jobname-20170401-235959.log # output_directory: /var/log/process-control + +# Path for working files such as locks. +# +# TODO: The deb install should create this directory and do something about +# permissions. +#run_dir: /var/run/process-control +# +run_dir: /tmp diff --git a/processcontrol/lock.py b/processcontrol/lock.py index 0ea66ed..906c0cc 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -7,12 +7,17 @@ import os import sys + +from processcontrol import config + + lockfile = None -def begin(filename=None, failopen=False, job_tag=None): -if not filename: -filename = "/tmp/{name}.lock".format(name=job_tag) +# TODO: Decide whether we want to failopen? +def begin(failopen=False, job_tag=None): +run_dir = config.GlobalConfiguration().get("run_dir") +filename = "{run_dir}/{name}.lock".format(run_dir=run_dir, name=job_tag) if os.path.exists(filename): print("Lockfile found!", file=sys.stderr) diff --git a/tests/data/global_defaults.yaml b/tests/data/global_defaults.yaml index 4330a53..079dfae 100644 --- a/tests/data/global_defaults.yaml +++ b/tests/data/global_defaults.yaml @@ -28,3 +28,5 @@ #/var/log/process-control/jobname-20170401-235959.log # output_directory: /tmp + +run_dir: /tmp -- To view, visit https://gerrit.wikimedia.org/r/345089 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib34b5cd3753ddf52832cd80d71dc7da0f98c298c Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Store job slug
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345088 ) Change subject: Store job slug .. Store job slug Change-Id: Idd712c33f1f32a64ada876cc988425a39613005e --- M processcontrol/job_wrapper.py 1 file changed, 3 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/88/345088/1 diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index ff8f11f..4d3892e 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -15,7 +15,7 @@ def load(job_name): job_directory = config.GlobalConfiguration().get("job_directory") job_path = "{job_dir}/{job_name}.yaml".format(job_dir=job_directory, job_name=job_name) -return JobWrapper(config_path=job_path) +return JobWrapper(config_path=job_path, slug=job_name) def list(): @@ -28,12 +28,13 @@ class JobWrapper(object): -def __init__(self, config_path=None): +def __init__(self, config_path=None, slug=None): self.global_config = config.GlobalConfiguration() self.config_path = config_path self.config = config.JobConfiguration(self.global_config, self.config_path) self.name = self.config.get("name") +self.slug = slug self.start_time = datetime.datetime.utcnow() self.mailer = mailer.Mailer(self.config) self.timeout = self.config.get("timeout") -- To view, visit https://gerrit.wikimedia.org/r/345088 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idd712c33f1f32a64ada876cc988425a39613005e Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Fix crontab CLI params
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345071 ) Change subject: Fix crontab CLI params .. Fix crontab CLI params Change-Id: I06307b498a051ec3998ca43e197953358fc9edac --- M processcontrol/crontab.py M tests/test_crontab.py 2 files changed, 7 insertions(+), 7 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/71/345071/1 diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index b099e11..3e43987 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -36,11 +36,11 @@ def __str__(self): if not self.enabled: -return "# Skipping disabled job {path}\n".format(path=self.job.config_path) +return "# Skipping disabled job {name}\n".format(name=self.job.slug) -command = "{runner} {conf}".format( +command = "{runner} {name}".format( runner=self.job.global_config.get("runner_path"), -conf=self.job.config_path) +name=self.job.slug) template = self.job.global_config.get("cron_template") diff --git a/tests/test_crontab.py b/tests/test_crontab.py index 40cb3b5..6cc5b2d 100644 --- a/tests/test_crontab.py +++ b/tests/test_crontab.py @@ -36,12 +36,12 @@ tab = tab.replace(job_dir, "X") tab = tab.replace(runner_path, "Y") -expected = """# Skipping disabled job X/disabled.yaml +expected = """# Skipping disabled job disabled # Generated from X/schedule_2.yaml -*/10 * * * * jenkins Y X/schedule_2.yaml +*/10 * * * * jenkins Y schedule_2 # Generated from X/schedule_good.yaml -*/5 * * * * jenkins Y X/schedule_good.yaml -# Skipping disabled job X/unscheduled.yaml +*/5 * * * * jenkins Y schedule_good +# Skipping disabled job unscheduled """ assert expected == tab -- To view, visit https://gerrit.wikimedia.org/r/345071 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I06307b498a051ec3998ca43e197953358fc9edac Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: update README
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345063 ) Change subject: update README .. update README Change-Id: I7c41c91ae4eb644c6a34414fceca4fdbbd51877c --- M README.md 1 file changed, 7 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/63/345063/1 diff --git a/README.md b/README.md index 4ad5e7c..8eed1fc 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,13 @@ Running === -To run a job, point at its description file: -run-job job-desc.yaml +Jobs can be run by name, +run-job job-a-thon +which will look for a job configuration in `/var/lib/process-control/job-a-thon.yaml`. + +Some actions are shoehorned in, and can be accessed like: +run-job --list-jobs + run-job --kill-job job-a-thon Failure detection == @@ -66,10 +71,7 @@ * Syslog actions, at least when tweezing new crontabs. * Log invocations. * Prevent future job runs when unrecoverable failure conditions are detected. -* Should we support commandline flags? * Fine-tuning of failure detection. -* Script to kill jobs. -* Script to run a job one-off. * Job group tags. * Slow-start and monitoring. * Optional backoff. -- To view, visit https://gerrit.wikimedia.org/r/345063 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7c41c91ae4eb644c6a34414fceca4fdbbd51877c Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: --kill-job
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345062 ) Change subject: --kill-job .. --kill-job Change-Id: Ia181aa495eabf34242293cb60904594ee3766b5c --- M bin/run-job M processcontrol/job_wrapper.py M processcontrol/lock.py 3 files changed, 31 insertions(+), 7 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/62/345062/1 diff --git a/bin/run-job b/bin/run-job index 2ea0512..974c4f2 100755 --- a/bin/run-job +++ b/bin/run-job @@ -1,15 +1,40 @@ #!/usr/bin/python +from __future__ import print_function import argparse +import subprocess import sys from processcontrol import job_wrapper + + +def list_jobs(): + for job_name in job_wrapper.list(): + job = job_wrapper.load(job_name) + print("{job} - {human_name}".format(job=job_name, human_name=job.name)) + status = job.status() + if status is not None: + print(status) + + +def kill_job(job_name): + job = job_wrapper.load(job_name) + status = job.status() + if status is None: + print("Nothing to kill.") + else: + pid = status["pid"] + print("Killing job {name}, pid {pid}".format(name=job_name, pid=pid)) + exit_code = subprocess.call(["kill", str(pid)]) + if exit_code != 0: + print("Failed to kill!", file=sys.stderr) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Run and maintain process-control jobs.") parser.add_argument("-j", "--job", help="Run a given job.", type=str) parser.add_argument("--list-jobs", help="Print a summary of available jobs.", action='store_true') + parser.add_argument("--kill-job", help="Kill a job by name", type=str) args = parser.parse_args() if args.job: @@ -17,9 +42,7 @@ job.run() if args.list_jobs: - for job_name in job_wrapper.list(): - job = job_wrapper.load(job_name) - print("{job} - {human_name}".format(job=job_name, human_name=job.name)) - status = job.status() - if status is not None: - print(status) + list_jobs() + + if args.kill_job: + kill_job(args.kill_job) diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index c99fcaf..d84b83e 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -144,7 +144,7 @@ lock_path = "/tmp/{name}.lock".format(name=self.slug) if os.path.exists(lock_path): with open(lock_path, "r") as f: -pid = f.read().strip() +pid = int(f.read().strip()) # TODO: encapsulate return {"status": "running", "pid": pid} diff --git a/processcontrol/lock.py b/processcontrol/lock.py index 6c91863..bbca472 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -39,6 +39,7 @@ f = open(filename, "w") f.write(str(os.getpid())) +os.chmod(filename, 0o644) f.close() global lockfile -- To view, visit https://gerrit.wikimedia.org/r/345062 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia181aa495eabf34242293cb60904594ee3766b5c Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Show job status in --list-jobs
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345022 ) Change subject: Show job status in --list-jobs .. Show job status in --list-jobs Change-Id: Ie99758202547130b711769a24186c30b67cb9729 --- M bin/run-job M process-control.example.yaml M processcontrol/job_wrapper.py M tests/data/global_defaults.yaml 4 files changed, 34 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/22/345022/1 diff --git a/bin/run-job b/bin/run-job index 746d288..2ea0512 100755 --- a/bin/run-job +++ b/bin/run-job @@ -20,3 +20,6 @@ for job_name in job_wrapper.list(): job = job_wrapper.load(job_name) print("{job} - {human_name}".format(job=job_name, human_name=job.name)) + status = job.status() + if status is not None: + print(status) diff --git a/process-control.example.yaml b/process-control.example.yaml index ce742db..15b41ea 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -33,3 +33,11 @@ #/var/log/process-control/jobname/jobname-20170401-235959.log # output_directory: /var/log/process-control + +# Path for working files such as locks. +# +# TODO: The deb install should create this directory and do something about +# permissions. +#run_dir: /var/run/process-control +# +run_dir: /tmp diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index ff8f11f..2731bc2 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -15,7 +15,7 @@ def load(job_name): job_directory = config.GlobalConfiguration().get("job_directory") job_path = "{job_dir}/{job_name}.yaml".format(job_dir=job_directory, job_name=job_name) -return JobWrapper(config_path=job_path) +return JobWrapper(config_path=job_path, slug=job_name) def list(): @@ -28,12 +28,13 @@ class JobWrapper(object): -def __init__(self, config_path=None): +def __init__(self, config_path=None, slug=None): self.global_config = config.GlobalConfiguration() self.config_path = config_path self.config = config.JobConfiguration(self.global_config, self.config_path) self.name = self.config.get("name") +self.slug = slug self.start_time = datetime.datetime.utcnow() self.mailer = mailer.Mailer(self.config) self.timeout = self.config.get("timeout") @@ -130,3 +131,21 @@ print(header, file=out) out.write(stderr_data.decode("utf-8")) + +def status(self): +"""Check for any running instances of this job, in this process or another. + +Returns a crappy dict, or None if no process is found. + +Do not use this function to gate the workflow, explicitly assert the +lock instead.""" + +# FIXME: DRY +lock_path = "/tmp/{name}.lock".format(name=self.slug) +if os.path.exists(lock_path): +with open(lock_path, "r") as f: +pid = f.read().strip() +# TODO: encapsulate +return { "status": "running", "pid": pid } + +return None diff --git a/tests/data/global_defaults.yaml b/tests/data/global_defaults.yaml index 4330a53..079dfae 100644 --- a/tests/data/global_defaults.yaml +++ b/tests/data/global_defaults.yaml @@ -28,3 +28,5 @@ #/var/log/process-control/jobname-20170401-235959.log # output_directory: /tmp + +run_dir: /tmp -- To view, visit https://gerrit.wikimedia.org/r/345022 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie99758202547130b711769a24186c30b67cb9729 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: --list-jobs action
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345008 ) Change subject: --list-jobs action .. --list-jobs action Change-Id: I0f1b8594d6660e59c69b4cacbd38c82ffbecd018 --- M bin/run-job 1 file changed, 10 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/08/345008/1 diff --git a/bin/run-job b/bin/run-job index af768b6..746d288 100755 --- a/bin/run-job +++ b/bin/run-job @@ -8,8 +8,15 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Run and maintain process-control jobs.") - parser.add_argument("-j", "--job", help="Run a given job", type=str) + parser.add_argument("-j", "--job", help="Run a given job.", type=str) + parser.add_argument("--list-jobs", help="Print a summary of available jobs.", action='store_true') args = parser.parse_args() - wrapper = job_wrapper.load(args.job) - wrapper.run() + if args.job: + job = job_wrapper.load(args.job) + job.run() + + if args.list_jobs: + for job_name in job_wrapper.list(): + job = job_wrapper.load(job_name) + print("{job} - {human_name}".format(job=job_name, human_name=job.name)) -- To view, visit https://gerrit.wikimedia.org/r/345008 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0f1b8594d6660e59c69b4cacbd38c82ffbecd018 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Makefile for lulz
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/345006 ) Change subject: Makefile for lulz .. Makefile for lulz Change-Id: I1ef204525c452f9b2991031eeb3019d6dbf20587 --- A Makefile 1 file changed, 19 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/06/345006/1 diff --git a/Makefile b/Makefile new file mode 100644 index 000..fb7bc49 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +.PHONY: \ + coverage \ + deb + +# Note that this target is run during deb packaging. +.DEFAULT: noop + +noop: + @echo Nothing to do! + +coverage: + nosetests --with-coverage --cover-package=processcontrol --cover-html + @echo Results are in cover/index.html + +deb: + @echo Note that this is not how we build our production .deb + # FIXME: fragile + cd ..; tar cjf process-control_0.0.1~rc1.orig.tar.bz2 process-control; cd process-control + debuild -us -uc -- To view, visit https://gerrit.wikimedia.org/r/345006 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1ef204525c452f9b2991031eeb3019d6dbf20587 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: ignore build products
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344980 ) Change subject: ignore build products .. ignore build products Change-Id: Id7238108dc12600f2c7626b2a765c533e27d3198 --- M .gitignore 1 file changed, 5 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/80/344980/1 diff --git a/.gitignore b/.gitignore index d503969..da0b490 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ *.pyc +build .cache cover .coverage .tox + +debian/debhelper-build-stamp +debian/files +debian/process-control* -- To view, visit https://gerrit.wikimedia.org/r/344980 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id7238108dc12600f2c7626b2a765c533e27d3198 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: zero-argument mode from cron-generate
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344979 ) Change subject: zero-argument mode from cron-generate .. zero-argument mode from cron-generate Get all config from config. Change-Id: If4a11ce00c1091b58a37dfbad0792cb60312da53 --- M bin/cron-generate M process-control.example.yaml M processcontrol/config.py 3 files changed, 13 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/79/344979/1 diff --git a/bin/cron-generate b/bin/cron-generate index cfd6875..bdf0873 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,23 +1,22 @@ #!/usr/bin/python from __future__ import print_function -import argparse import sys from processcontrol import crontab +from processcontrol import config if __name__ == "__main__": -parser = argparse.ArgumentParser(description="Generate a crontab from a directory of schedulable jobs.") -# TODO: Get defaults from config. -parser.add_argument("-d", "--job-directory", help="Job specification directory", type=str, required=True) -parser.add_argument("-O", "--output-file", help="Crontab output path", type=str) -args = parser.parse_args() - if args.output_file and args.output_file != "-": -out = open(args.output_file, "w") else: -out = sys.stdout cron_text = crontab.make_cron(args.job_directory) + + output_file = config.GlobalConfig().get("output_crontab") + if output_file == 'console': +out = sys.stdout + else: + out = open(args.output_file, "w") + print(cron_text, file=out) diff --git a/process-control.example.yaml b/process-control.example.yaml index 323a1fd..6429a2c 100644 --- a/process-control.example.yaml +++ b/process-control.example.yaml @@ -19,6 +19,9 @@ timeout: 600 +# Output file path. +output_crontab: /etc/cron.d/process-control + # Log directory for job output and errors. A timestamped log file is written # for each run, like: #/var/log/process-control/jobname/jobname-20170401-235959.log diff --git a/processcontrol/config.py b/processcontrol/config.py index a25d1dc..c8b520c 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -43,7 +43,7 @@ class GlobalConfiguration(Configuration): -global_config_path = "/etc/fundraising/process-control.yaml" +global_config_path = "/etc/process-control.yaml" def __init__(self): Configuration.__init__(self) @@ -62,6 +62,7 @@ def validate_global_config(self): assert "cron_template" in self.values +assert "output_crontab" in self.values assert "output_directory" in self.values assert "runner_path" in self.values assert "user" in self.values -- To view, visit https://gerrit.wikimedia.org/r/344979 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If4a11ce00c1091b58a37dfbad0792cb60312da53 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...vendor[master]: [HOTFIX] Patch orphan rectifier to drop non-cc records
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344552 ) Change subject: [HOTFIX] Patch orphan rectifier to drop non-cc records .. [HOTFIX] Patch orphan rectifier to drop non-cc records NOTE: Directly patched to avoid composer churn during code freeze. Bug: T161160 Change-Id: Ia6fe7626ea21867055bb147ceef1e00c33c907bf --- M wikimedia/donation-interface/globalcollect_gateway/GlobalCollectOrphanRectifier.php 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm/vendor refs/changes/52/344552/1 diff --git a/wikimedia/donation-interface/globalcollect_gateway/GlobalCollectOrphanRectifier.php b/wikimedia/donation-interface/globalcollect_gateway/GlobalCollectOrphanRectifier.php index ac404b1..6d44465 100644 --- a/wikimedia/donation-interface/globalcollect_gateway/GlobalCollectOrphanRectifier.php +++ b/wikimedia/donation-interface/globalcollect_gateway/GlobalCollectOrphanRectifier.php @@ -160,6 +160,13 @@ * @return boolean True if the orphan has been rectified, false if not. */ protected function rectifyOrphan( $normalized ){ + if ( $normalized['payment_method'] !== 'cc' ) { + // Skip other payment methods which shouldn't be in the pending + // queue anyway. See https://phabricator.wikimedia.org/T161160 + $this->logger->info( "Skipping non-credit card pending record." ); + return false; + } + $this->logger->info( "Rectifying orphan: {$normalized['order_id']}" ); $is_rectified = false; -- To view, visit https://gerrit.wikimedia.org/r/344552 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia6fe7626ea21867055bb147ceef1e00c33c907bf Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/crm/vendor Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Patch orphan rectifier to drop non-cc records
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344545 ) Change subject: Patch orphan rectifier to drop non-cc records .. Patch orphan rectifier to drop non-cc records Bug: T161160 Change-Id: I2ff9a064d2f6c38b05441f1efa1ca8bdd781fc24 --- M globalcollect_gateway/GlobalCollectOrphanRectifier.php 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/45/344545/1 diff --git a/globalcollect_gateway/GlobalCollectOrphanRectifier.php b/globalcollect_gateway/GlobalCollectOrphanRectifier.php index ac404b1..6d44465 100644 --- a/globalcollect_gateway/GlobalCollectOrphanRectifier.php +++ b/globalcollect_gateway/GlobalCollectOrphanRectifier.php @@ -160,6 +160,13 @@ * @return boolean True if the orphan has been rectified, false if not. */ protected function rectifyOrphan( $normalized ){ + if ( $normalized['payment_method'] !== 'cc' ) { + // Skip other payment methods which shouldn't be in the pending + // queue anyway. See https://phabricator.wikimedia.org/T161160 + $this->logger->info( "Skipping non-credit card pending record." ); + return false; + } + $this->logger->info( "Rectifying orphan: {$normalized['order_id']}" ); $is_rectified = false; -- To view, visit https://gerrit.wikimedia.org/r/344545 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2ff9a064d2f6c38b05441f1efa1ca8bdd781fc24 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[deployment]: Patch orphan rectifier to drop non-cc records
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344542 ) Change subject: Patch orphan rectifier to drop non-cc records .. Patch orphan rectifier to drop non-cc records Bug: T161160 Change-Id: I2ff9a064d2f6c38b05441f1efa1ca8bdd781fc24 --- M globalcollect_gateway/GlobalCollectOrphanRectifier.php 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/42/344542/1 diff --git a/globalcollect_gateway/GlobalCollectOrphanRectifier.php b/globalcollect_gateway/GlobalCollectOrphanRectifier.php index 4de9e49..c9d7f20 100644 --- a/globalcollect_gateway/GlobalCollectOrphanRectifier.php +++ b/globalcollect_gateway/GlobalCollectOrphanRectifier.php @@ -162,6 +162,13 @@ * @return boolean True if the orphan has been rectified, false if not. */ protected function rectifyOrphan( $normalized, $query_contribution_tracking = true ){ + if ( $normalized['payment_method'] !== 'cc' ) { + // Skip other payment methods which shouldn't be in the pending + // queue anyway. See https://phabricator.wikimedia.org/T161160 + $this->logger->info( "Skipping non-credit card pending record." ); + return false; + } + $this->logger->info( "Rectifying orphan: {$normalized['order_id']}" ); $is_rectified = false; -- To view, visit https://gerrit.wikimedia.org/r/344542 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2ff9a064d2f6c38b05441f1efa1ca8bdd781fc24 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: deployment Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[deployment]: Merge master into deployment
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344541 ) Change subject: Merge master into deployment .. Merge master into deployment 9b6c8bf9912b143986e8e0a00b0aa6b0f76bdb33 Add composer.json with phplint, also fix two files with incorrect paths 9ca62c0385db88f2513fcc685ed5ac9f91c71db1 Always call antifraud hooks after get_orderstatus d1b41e773f34952c34d0c22b1e8dde3c6b7f4b7a Localisation updates from https://translatewiki.net. 6307aa34d8d7e516c0434e5d412fd7b6571cbed4 Localisation updates from https://translatewiki.net. 9c1a41c83106b92ca71eb6f62cda2fdaecb3a1fd Update composer libs 44b5248d9d186eb2c413cb235249f3d604f10ba6 Be less magical about unstaging order status things 5d5a47693fac07898bafe45324e8cae265ec5223 Don't use frontend classes from fraud filters fa7395f6ef6a3e7446c3aed7b0541a47463082cf Use SmashPig config shortcut, reset Context Change-Id: I783457e749a560d9206b37b07254d72d9f246394 --- D tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php D tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanRectifierTest.php D tests/phpunit/Adapter/GlobalCollect/GlobalCollectTest.php D tests/phpunit/DonationInterfaceTestCase.php D tests/phpunit/LintYaml.php D tests/phpunit/includes/Responses/globalcollect/DO_FINISHPAYMENT_200.testresponse D tests/phpunit/includes/Responses/globalcollect/GET_ORDERSTATUS_600_badCvv.testresponse D tests/phpunit/includes/Responses/globalcollect/SET_PAYMENT_200.testresponse 8 files changed, 0 insertions(+), 1,875 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/41/344541/1 diff --git a/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php b/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php deleted file mode 100644 index 67d1377..000 --- a/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php +++ /dev/null @@ -1,208 +0,0 @@ -<<< HEAD (8d17a0 Merge branch 'master' into deployment) -=== -setMwGlobals( array( - 'wgGlobalCollectGatewayEnabled' => true, - 'wgDonationInterfaceAllowedHtmlForms' => array( - 'cc-vmad' => array( - 'gateway' => 'globalcollect', - 'payment_methods' => array('cc' => array( 'visa', 'mc', 'amex', 'discover' )), - 'countries' => array( - '+' => array( 'US', ), - ), - ), - ), - ) ); - } - - /** -* @param $name string The name of the test case -* @param $data array Any parameters read from a dataProvider -* @param $dataName string|int The name or index of the data set -*/ - function __construct( $name = null, array $data = array(), $dataName = '' ) { - parent::__construct( $name, $data, $dataName ); - $this->testAdapterClass = 'TestingGlobalCollectOrphanAdapter'; - $this->dummy_utm_data = array ( - 'utm_source' => 'dummy_source', - 'utm_campaign' => 'dummy_campaign', - 'utm_medium' => 'dummy_medium', - 'date' => time(), - ); - } - - public function testConstructor() { - - $options = $this->getDonorTestData(); - $class = $this->testAdapterClass; - - $gateway = $this->getFreshGatewayObject(); - - $this->assertInstanceOf( $class, $gateway ); - - $this->verifyNoLogErrors(); - } - - - public function testBatchOrderID_generate() { - - //no data on construct, generate Order IDs - $gateway = $this->getFreshGatewayObject( null, array ( 'order_id_meta' => array ( 'generate' => TRUE ) ) ); - $this->assertTrue( $gateway->getOrderIDMeta( 'generate' ), 'The order_id meta generate setting override is not working properly. Order_id generation may be broken.' ); - $this->assertNotNull( $gateway->getData_Unstaged_Escaped( 'order_id' ), 'Failed asserting that an absent order id is not left as null, when generating our own' ); - - $data = array_merge( $this->getDonorTestData(), $this->dummy_utm_data ); - $data['order_id'] = '5'; - - //now, add data and check that we didn't kill the oid. Still generating. - $gateway->loadDataAndReInit( $data, $useDB = false ); - $this->assertEquals( $gateway->getData_Unstaged_Escaped( 'order_id' ), '5', 'loadDataAndReInit failed to stick OrderID' ); - - $data['order_id'] = '44'; -
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Test for environment parameter
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344501 ) Change subject: Test for environment parameter .. Test for environment parameter Change-Id: I7739f28ca9fd3b11754a5eae0c10ee59a034d384 --- A tests/data/env.yaml M tests/test_job_wrapper.py 2 files changed, 28 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/01/344501/1 diff --git a/tests/data/env.yaml b/tests/data/env.yaml new file mode 100644 index 000..bdc5ef3 --- /dev/null +++ b/tests/data/env.yaml @@ -0,0 +1,5 @@ +name: Env dumper +command: /usr/bin/env +environment: +foo1: bar +foo2: rebar diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index f95480c..ef290d5 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -79,7 +79,6 @@ run_job("which_out.yaml") log_files = sorted(glob.glob(path_glob)) -assert len(log_files) == 1 path = log_files[-1] contents = open(path, "r").read() lines = contents.split("\n") @@ -88,3 +87,26 @@ assert lines[4] == "/bin/bash" os.unlink(path) + + +def test_environment(): +path_glob = "/tmp/Env dumper/Env dumper*.log" + +run_job("env.yaml") + +log_files = sorted(glob.glob(path_glob)) +path = log_files[-1] +contents = open(path, "r").read() +lines = contents.split("\n") +print(lines) + +assert len(lines) == 7 + +dumped_env = sorted(lines[4:6]) +expected = [ +"foo1=bar", +"foo2=rebar", +] +assert expected == dumped_env + +os.unlink(path) -- To view, visit https://gerrit.wikimedia.org/r/344501 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7739f28ca9fd3b11754a5eae0c10ee59a034d384 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: run-job option flag is required now
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344499 ) Change subject: run-job option flag is required now .. run-job option flag is required now Change-Id: I0b2b2848678f113096ad8b7e90ff391907a8c372 --- M processcontrol/crontab.py 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/99/344499/1 diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index cf3b408..8a9f063 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -33,7 +33,7 @@ if not self.enabled: return "# Skipping disabled job {path}\n".format(path=self.job.config_path) -command = "{runner} {conf}".format( +command = "{runner} --job-file {conf}".format( runner=self.job.global_config.get("runner_path"), conf=self.job.config_path) -- To view, visit https://gerrit.wikimedia.org/r/344499 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0b2b2848678f113096ad8b7e90ff391907a8c372 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Pass environment variables to the subprocess
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344279 ) Change subject: Pass environment variables to the subprocess .. Pass environment variables to the subprocess Change-Id: I28e47729b3ee0d7f5566e530eaa032767347a101 TODO: Needs a test --- M README.md M processcontrol/job_wrapper.py 2 files changed, 10 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/79/344279/1 diff --git a/README.md b/README.md index e53da2c..4ad5e7c 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,10 @@ # Optional timeout in seconds, after which your job will be # aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT timeout: 30 + +# Optional environment variables. +environment: + PYTHONPATH: /usr/share/invisible/pie ``` Running diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 99fad1c..e57278e 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -30,12 +30,17 @@ if not self.config.has("schedule"): self.enabled = False +if self.config.has("environment"): +self.environment = self.config.get("environment") +else: +self.environment = {} + def run(self): lock.begin(job_tag=self.name) command = shlex.split(self.config.get("command")) -self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.environment) timer = threading.Timer(self.timeout, self.fail_timeout) timer.start() -- To view, visit https://gerrit.wikimedia.org/r/344279 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I28e47729b3ee0d7f5566e530eaa032767347a101 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Copy example configuration to docs during install
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344273 ) Change subject: Copy example configuration to docs during install .. Copy example configuration to docs during install Change-Id: I1862db40d06047864f87aefaa7d09d78754ea144 --- M debian/docs 1 file changed, 1 insertion(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/73/344273/1 diff --git a/debian/docs b/debian/docs index b43bf86..22c7238 100644 --- a/debian/docs +++ b/debian/docs @@ -1 +1,2 @@ README.md +process-control.example.yaml -- To view, visit https://gerrit.wikimedia.org/r/344273 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1862db40d06047864f87aefaa7d09d78754ea144 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Remove unused config inline defaults
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344260 ) Change subject: Remove unused config inline defaults .. Remove unused config inline defaults Change-Id: Ice7437d238de683b6dc4bf1870bd03288cf77dc5 --- M processcontrol/config.py 1 file changed, 5 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/60/344260/1 diff --git a/processcontrol/config.py b/processcontrol/config.py index 5ffddff..47ef279 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -8,22 +8,19 @@ def __init__(self, defaults={}): self.values = defaults -def get(self, path, default=None): +def get(self, path): """Get a value from configuration. You can get a nested property by using a path delimited by -forward slashes (/). -If you provide a default value, it will be used when the -desired property does not exist. If there is no default, -trying to get a missing property raises a MissingKeyException. +forward slashes (/), for example "failmail/from-address". + +Trying to get a missing property raises a MissingKeyException. """ parts = path.split("/") current = self.values for part in parts: if part not in current: -if default is None: -raise MissingKeyException(path) -return default +raise MissingKeyException(path) current = current[part] return current -- To view, visit https://gerrit.wikimedia.org/r/344260 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ice7437d238de683b6dc4bf1870bd03288cf77dc5 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: More cron syntax checks
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344189 ) Change subject: More cron syntax checks .. More cron syntax checks Change-Id: I956eae9ffea489c6a82703080ada89fe1826ddbe --- M processcontrol/config.py 1 file changed, 7 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/89/344189/1 diff --git a/processcontrol/config.py b/processcontrol/config.py index 5854176..175997d 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -74,13 +74,20 @@ def validate_job_config(self): assert "name" in self.values + assert "command" in self.values +assert "\n" not in self.values["command"] +# No incredibly stealthy line breaks. +assert "%" not in self.values["command"] + assert "stdout_destination" in self.values if "schedule" in self.values: # No tricky assignments. assert "=" not in self.values["schedule"] # Legal cron, but I don't want to deal with it. assert "@" not in self.values["schedule"] +# No line breaks +assert "\n" not in self.values["schedule"] # Be sure the schedule is valid. terms = self.values["schedule"].split() -- To view, visit https://gerrit.wikimedia.org/r/344189 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I956eae9ffea489c6a82703080ada89fe1826ddbe Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: stdout_destination is required. You'll have to say "/dev/nu...
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344181 ) Change subject: stdout_destination is required. You'll have to say "/dev/null" out loud if you want it. .. stdout_destination is required. You'll have to say "/dev/null" out loud if you want it. Change-Id: Ie82dee42f828dd3b73230ca93e4b10c3d904e556 --- M README.md M processcontrol/config.py M processcontrol/job_wrapper.py 3 files changed, 14 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/81/344181/1 diff --git a/README.md b/README.md index 42b2301..b1fdc4b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,14 @@ ```yaml name: Take This Job and Shove It +# The commandline that will be run. This is executed from Python and not from +# a shell, so globbing and other trickery will not work. Please give a full +# path to the executable. command: /usr/local/bin/timecard --start 9:00 --end 5:30 + +# Required filename for the job output. All output will be +# concatenated into this file, with a header for each job. +stdout_destination: "/tmp/jobnuts.log" # Optional schedule, in Vixie cron format: # minute hour day-of-month month day-of-week @@ -29,10 +36,6 @@ # Optional timeout in seconds, after which your job will be # aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT timeout: 30 - -# Optional filename for the job output. All output will be -# concatenated into this file, with a header for each job. -stdout_destination: "/tmp/jobnuts.log" ``` Failure detection diff --git a/processcontrol/config.py b/processcontrol/config.py index 69fa24e..5854176 100644 --- a/processcontrol/config.py +++ b/processcontrol/config.py @@ -75,6 +75,7 @@ def validate_job_config(self): assert "name" in self.values assert "command" in self.values +assert "stdout_destination" in self.values if "schedule" in self.values: # No tricky assignments. assert "=" not in self.values["schedule"] diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 6b8423e..0c2e9e3 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -82,11 +82,13 @@ # FIXME: Job will return SIGKILL now, fail_exitcode should ignore that signal now? def store_job_output(self, stdout_data): -if not self.config.has("stdout_destination"): -return - destination = self.config.get("stdout_destination") -out = open(destination, "a") +if destination == "-": +# Doubtful that this is a real use case, but for debugging let's +# allow "-" to mean stdout. +out = sys.stdout +else: +out = open(destination, "a") header = ( "===\n" -- To view, visit https://gerrit.wikimedia.org/r/344181 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie82dee42f828dd3b73230ca93e4b10c3d904e556 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Encapsulate errors
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344042 ) Change subject: [WIP] Encapsulate errors .. [WIP] Encapsulate errors TODO: * Figure out how to represent validation errors and internal errors under a polymorphic base. * Write has* and clear* accessors. * Write i18n glue. Figure out how to store messages that take params. Change-Id: I39bcc0c84609e681fb9c15db51058ee3ccd7fad8 --- A gateway_common/PaymentError.php M gateway_common/PaymentResult.php M gateway_common/PaymentTransactionResponse.php M gateway_common/gateway.adapter.php 4 files changed, 67 insertions(+), 85 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/42/344042/1 diff --git a/gateway_common/PaymentError.php b/gateway_common/PaymentError.php new file mode 100644 index 000..e1f90bc --- /dev/null +++ b/gateway_common/PaymentError.php @@ -0,0 +1,13 @@ +error_code = $error_code; + $this->debug_message = $debug_message; + $this->log_level = $log_level; + } +} diff --git a/gateway_common/PaymentResult.php b/gateway_common/PaymentResult.php index 77acb8f..ac73e9e 100644 --- a/gateway_common/PaymentResult.php +++ b/gateway_common/PaymentResult.php @@ -73,9 +73,9 @@ public static function newEmpty() { $response = new PaymentResult(); - $response->errors = array( - 'internal-' => 'Internal error: no results yet.', - ); + $response->errors = array( new PaymentError( + 'internal-', 'Internal error: no results yet.' + ) ); $response->failed = true; return $response; } diff --git a/gateway_common/PaymentTransactionResponse.php b/gateway_common/PaymentTransactionResponse.php index a116db3..f903af8 100644 --- a/gateway_common/PaymentTransactionResponse.php +++ b/gateway_common/PaymentTransactionResponse.php @@ -7,12 +7,7 @@ */ class PaymentTransactionResponse { /** -* @var array keys are error codes, values are themselves arrays of the form -* 'message' => 'for public consumption', -* 'debugInfo' => 'diagnostic information', -* 'logLevel' => LogLevel::WARNING -* If there weren't any, this should be present and empty after a -* transaction. +* @var array List of PaymentErrors */ protected $errors = array(); @@ -107,19 +102,18 @@ } /** -* @param array $errors +* @param array $errors List of PaymentError */ - public function setErrors( $errors ) { - $this->errors = $errors; + public function addErrors( $errors ) { + $this->errors += $errors; } /** * Add an error to the internal $errors array -* @param string $code identifies the error type -* @param array $error as specified in @see errors +* @param PaymentError $error */ - public function addError( $code, $error ) { - $this->errors[$code] = $error; + public function addError( $error ) { + $this->errors[] = $error; } /** diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 8eb8861..de8b23d 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -144,6 +144,8 @@ /** * $transaction_response is the member var that keeps track of the results of * the latest discrete transaction with the gateway. +* TODO: We might want to deprecate this and pass out of do_transaction +* using functional style. * @var PaymentTransactionResponse */ protected $transaction_response; @@ -153,16 +155,7 @@ */ protected $final_status; /** -* @var array Map of errors preventing this transaction from continuing. -* Structure is like: -* [ -* # An i18n key name to an error message that will display atop of -* # the screen, indicating that something general needs fixing. -* 'general' => 'warning-currency-fallback', -* # Example of a very specific error string that only the gateway -* # could calculate. -* 'address' => 'key saying: "Address is required for E-Commerce transactions."', -* ] +* @var array PaymentError[] List of errors preventing this transaction from continuing. */ protected $errors = array(); @@ -908,16 +901,13 @@ $this->session_addDonorData(); if ( !$this->validatedOK() ){ //If the data didn't validate okay, prevent all data
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Remove an unused default parameter
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343969 ) Change subject: Remove an unused default parameter .. Remove an unused default parameter Change-Id: Ic0e1de64ab407faff4cd824ceb5fe5bc43dbacfe --- M gateway_common/gateway.adapter.php 1 file changed, 1 insertion(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/69/343969/1 diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index a7b360d..8eb8861 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -588,11 +588,7 @@ * @paramarray $options * @return array|stringReturns @see GatewayAdapter::$error_map */ - public function getErrorMap( $code = null, $options = array() ) { - - if ( is_null( $code ) ) { - return $this->error_map; - } + public function getErrorMap( $code, $options = array() ) { $defaults = array( 'translate' => false, -- To view, visit https://gerrit.wikimedia.org/r/343969 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic0e1de64ab407faff4cd824ceb5fe5bc43dbacfe Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Fixes suggested by thcipriani
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343965 ) Change subject: Fixes suggested by thcipriani .. Fixes suggested by thcipriani Change-Id: I03592650c63907ffa4e14a1a136372bff3038f79 --- M processcontrol/crontab.py M processcontrol/job_wrapper.py M processcontrol/lock.py 3 files changed, 18 insertions(+), 21 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/65/343965/1 diff --git a/processcontrol/crontab.py b/processcontrol/crontab.py index 566b573..ba6b7bc 100644 --- a/processcontrol/crontab.py +++ b/processcontrol/crontab.py @@ -1,5 +1,5 @@ import glob -import os.path +import os import job_wrapper diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 4c3cae6..b50c0e2 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -86,16 +86,15 @@ return destination = self.config["stdout_destination"] -out = open(destination, "a") +with open(destination, "a") as out: +header = ( +"===\n" +"{name} ({pid}), started at {time}\n" +"---\n" +).format(name=self.name, pid=self.process.pid, time=self.start_time) +print(header, file=out) -header = ( -"===\n" -"{name} ({pid}), started at {time}\n" -"---\n" -).format(name=self.name, pid=self.process.pid, time=self.start_time) -print(header, file=out) - -out.write(stdout_data.decode("utf-8")) +out.write(stdout_data.decode("utf-8")) def validate_config(self): assert "name" in self.config diff --git a/processcontrol/lock.py b/processcontrol/lock.py index 6c91863..6af0bb5 100644 --- a/processcontrol/lock.py +++ b/processcontrol/lock.py @@ -5,7 +5,6 @@ ''' from __future__ import print_function import os -import os.path import sys lockfile = None @@ -17,13 +16,13 @@ if os.path.exists(filename): print("Lockfile found!", file=sys.stderr) -f = open(filename, "r") -pid = None -try: -pid = int(f.read()) -except ValueError: -pass -f.close() +with open(filename, "r") as f: +pid = None +try: +pid = int(f.read()) +except ValueError: +pass + if not pid: print("Invalid lockfile contents.", file=sys.stderr) else: @@ -37,9 +36,8 @@ print("Removing old lockfile.", file=sys.stderr) os.unlink(filename) -f = open(filename, "w") -f.write(str(os.getpid())) -f.close() +with open(filename, "w") as f: +f.write(str(os.getpid())) global lockfile lockfile = filename -- To view, visit https://gerrit.wikimedia.org/r/343965 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I03592650c63907ffa4e14a1a136372bff3038f79 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Use argparse to read the CLI; cron-generate is flaggy rather...
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343960 ) Change subject: Use argparse to read the CLI; cron-generate is flaggy rather than pipey .. Use argparse to read the CLI; cron-generate is flaggy rather than pipey Change-Id: Ib08b793ca9868aa824032f6d0aede9b740b0822a --- M bin/cron-generate M bin/run-job M debian/control M requirements.txt 4 files changed, 22 insertions(+), 24 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/60/343960/1 diff --git a/bin/cron-generate b/bin/cron-generate index 5a656b6..83b0f1b 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,21 +1,23 @@ #!/usr/bin/python +from __future__ import print_function +import argparse import sys -import processcontrol.crontab - - -def usage(): - print("Must give a job description directory as the only argument.") +from processcontrol import crontab if __name__ == "__main__": -# TODO: Parse CLI args. +parser = argparse.ArgumentParser(description="Run the given job specification.") +# TODO: Get defaults from config. +parser.add_argument("-d", "--job-directory", help="Job specification directory", type=str, required=True) +parser.add_argument("-O", "--output-file", help="Crontab output path", type=str) +args = parser.parse_args() - if len(sys.argv) != 2: - usage() - sys.exit(-1) +if args.output_file and args.output_file != "-": +out = open(args.output_file, "w") +else: +out = sys.stdout - config_dir = sys.argv[1] - - print(processcontrol.crontab.make_cron(config_dir)) +cron_text = crontab.make_cron(args.job_directory) +print(cron_text, file=out) diff --git a/bin/run-job b/bin/run-job index 788625b..7dc8cf0 100755 --- a/bin/run-job +++ b/bin/run-job @@ -1,22 +1,17 @@ #!/usr/bin/python +import argparse import sys -import processcontrol.job_wrapper - - -def usage(): - print("Must give a job description file as the only argument.") +from processcontrol import job_wrapper if __name__ == "__main__": # TODO: Parse CLI args and use to override the config file. - if len(sys.argv) != 2: - usage() - sys.exit(-1) + parser = argparse.ArgumentParser(description="Run the given job specification.") + parser.add_argument("-f", "--job-file", help="Job specification file", type=str, required=True) + args = parser.parse_args() - conf_file = sys.argv[1] - - wrapper = processcontrol.job_wrapper.JobWrapper(config_path=conf_file) + wrapper = job_wrapper.JobWrapper(config_path=args.job_file) wrapper.run() diff --git a/debian/control b/debian/control index 0178c6c..bfd362a 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,6 @@ Package: process-control Architecture: all -Depends: ${python:Depends}, python-yaml +Depends: ${python:Depends}, python-argparse, python-yaml Description: Tools for Wikimedia Foundation Fundraising job management Control and schedule jobs using configuration files. diff --git a/requirements.txt b/requirements.txt index c3726e8..733e8ce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ +argparse # transitional 2->3 package pyyaml -- To view, visit https://gerrit.wikimedia.org/r/343960 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib08b793ca9868aa824032f6d0aede9b740b0822a Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: target python2 for now
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343954 ) Change subject: target python2 for now .. target python2 for now Change-Id: I5eaa0aa4380f54263eadfd208584ef9c3bee2c22 --- M bin/cron-generate M bin/run-job M debian/control M debian/rules M setup.py 5 files changed, 7 insertions(+), 11 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/54/343954/1 diff --git a/bin/cron-generate b/bin/cron-generate index 52655aa..5a656b6 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python import sys diff --git a/bin/run-job b/bin/run-job index 8a35f6c..788625b 100755 --- a/bin/run-job +++ b/bin/run-job @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python import sys diff --git a/debian/control b/debian/control index f0214cf..0178c6c 100644 --- a/debian/control +++ b/debian/control @@ -2,15 +2,15 @@ Maintainer: Adam Roses WightSection: admin Priority: optional -Build-Depends: debhelper (>= 9), python3-all, python3-setuptools +Build-Depends: debhelper (>= 9), dh-python, python-all, python-setuptools Standards-Version: 3.9.8 Homepage: https://github.com/adamwight/process-control Vcs-Browser: https://github.com/adamwight/process-control Vcs-Git: git://github.com/adamwight/process-control.git -X-Python3-Version: >= 3.2 +X-Python-Version: >= 2.7 Package: process-control Architecture: all -Depends: ${python3:Depends}, python3-yaml +Depends: ${python:Depends}, python-yaml Description: Tools for Wikimedia Foundation Fundraising job management Control and schedule jobs using configuration files. diff --git a/debian/rules b/debian/rules index 086b21a..6af70d4 100755 --- a/debian/rules +++ b/debian/rules @@ -4,4 +4,4 @@ export PYBUILD_NAME=process-control %: - dh $@ --with python3 + dh $@ --with python2 diff --git a/setup.py b/setup.py index d80d0eb..306aeea 100755 --- a/setup.py +++ b/setup.py @@ -8,11 +8,7 @@ author='Adam Roses Wight', author_email='awi...@wikimedia.org', url='https://github.com/adamwight/process-control', -py_modules=[ -'crontab', -'job_wrapper', -'lock', -], +packages=['processcontrol'], scripts=[ 'bin/cron-generate', 'bin/run-job', -- To view, visit https://gerrit.wikimedia.org/r/343954 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5eaa0aa4380f54263eadfd208584ef9c3bee2c22 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Merge branch 'debian-packaging' of github.com:adamwight/proc...
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343921 ) Change subject: Merge branch 'debian-packaging' of github.com:adamwight/process-control into debian-packaging .. Merge branch 'debian-packaging' of github.com:adamwight/process-control into debian-packaging Change-Id: Ifb70d4530512ba454a2c4450f6269c9ac788917f --- M bin/cron-generate M bin/run-job M processcontrol/job_wrapper.py M setup.py 4 files changed, 0 insertions(+), 99 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/21/343921/1 diff --git a/bin/cron-generate b/bin/cron-generate index 469035a..52655aa 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -3,7 +3,6 @@ import sys import processcontrol.crontab -<<< HEAD (2a6dbe Debian packaging) def usage(): @@ -20,22 +19,3 @@ config_dir = sys.argv[1] print(processcontrol.crontab.make_cron(config_dir)) -=== -import processcontrol.job_wrapper - - -def usage(): - print("Must give a job description directory as the only argument.") - - -if __name__ == "__main__": -# TODO: Parse CLI args. - - if len(sys.argv) != 2: - usage() - sys.exit(-1) - - config_dir = sys.argv[1] - - print(crontab.make_cron(config_dir)) ->>> BRANCH (469870 House modules under a package) diff --git a/bin/run-job b/bin/run-job index 95852da..8a35f6c 100755 --- a/bin/run-job +++ b/bin/run-job @@ -18,9 +18,5 @@ conf_file = sys.argv[1] -<<< HEAD (2a6dbe Debian packaging) wrapper = processcontrol.job_wrapper.JobWrapper(config_path=conf_file) -=== - wrapper = job_wrapper.JobWrapper(config_path=conf_file) ->>> BRANCH (469870 House modules under a package) wrapper.run() diff --git a/processcontrol/job_wrapper.py b/processcontrol/job_wrapper.py index 3d8e307..4c3cae6 100644 --- a/processcontrol/job_wrapper.py +++ b/processcontrol/job_wrapper.py @@ -7,7 +7,6 @@ import yaml import lock -<<< HEAD (2a6dbe Debian packaging) import mailer # TODO: Global config. @@ -80,72 +79,6 @@ message = "Job {name} timed out after {timeout} seconds".format(name=self.name, timeout=self.timeout) print(message, file=sys.stderr) self.mailer.fail_mail(message) -=== - - -# TODO: Global config. -DEFAULT_TIMEOUT = 600 - - -class JobWrapper(object): -def __init__(self, config_path=None): -self.config_path = config_path -self.config = yaml.safe_load(open(config_path, "r")) -self.validate_config() - -self.name = self.config["name"] -self.start_time = datetime.datetime.utcnow().isoformat() - -if "timeout" in self.config: -self.timeout = self.config["timeout"] -else: -self.timeout = DEFAULT_TIMEOUT - -if "disabled" in self.config and self.config["disabled"] is True: -self.enabled = False -else: -self.enabled = True - -if "schedule" not in self.config: -self.enabled = False - -def run(self): -lock.begin(job_tag=self.name) - -command = shlex.split(self.config["command"]) - -self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) -timer = threading.Timer(self.timeout, self.fail_timeout) -timer.start() - -try: -# FIXME: This doesn't stream, so large output will be buffered in memory. -(stdout_data, stderr_data) = self.process.communicate() - -self.store_job_output(stdout_data) - -if len(stderr_data) > 0: -self.fail_has_stderr(stderr_data) -finally: -timer.cancel() -lock.end() - -return_code = self.process.returncode -if return_code != 0: -self.fail_exitcode(return_code) - -def fail_exitcode(self, return_code): -print("Job {name} failed with code {code}".format(name=self.name, code=return_code), file=sys.stderr) -# TODO: Prevent future jobs according to config. - -def fail_has_stderr(self, stderr_data): -print("Job {name} printed things to stderr:".format(name=self.name), file=sys.stderr) -print(stderr_data.decode("utf-8"), file=sys.stderr) - -def fail_timeout(self): -self.process.kill() -print("Job {name} timed out after {timeout} seconds".format(name=self.name, timeout=self.timeout), file=sys.stderr) ->>> BRANCH (469870 House modules under a package) # FIXME: Job will return SIGKILL now, fail_exitcode should ignore that signal now? def store_job_output(self, stdout_data): diff --git a/setup.py b/setup.py index 3b2df76..306aeea 100755 --- a/setup.py +++ b/setup.py @@ -8,15 +8,7 @@ author='Adam Roses Wight', author_email='awi...@wikimedia.org',
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Perform currency fallback earlier
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343795 ) Change subject: [WIP] Perform currency fallback earlier .. [WIP] Perform currency fallback earlier This allows us to validate the changed data. Change-Id: Icf39eeb26860f58ba5244b36d01dcac060c81027 --- M gateway_common/gateway.adapter.php 1 file changed, 14 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/95/343795/1 diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index a7b360d..c0aafe7 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -2453,10 +2453,23 @@ */ public function validate() { $normalized = $this->dataObj->getData(); + + $this->errors = array(); + + // Try to fall back to a default currency, clearing the error if + // successful. + // TODO: Rewrite as something modular? It's in-between validation and + // normalization, it modifies a bunch of values, needs access to the + // error array, and we may need to do post-validation. Whee! + $this->fallbackToDefaultCurrency(); + // FIXME: This is part of the same wart, we're copying potentially + // modified data back out of the data object. + $this->unstaged_data = $this->dataObj->getData(); // Run legacy validations $check_not_empty = $this->getRequiredFields(); - $this->errors = DataValidator::validate( $this, $normalized, $check_not_empty ); + $old_style_errors = DataValidator::validate( $this, $normalized, $check_not_empty ); + $this->errors = array_merge_recursive( $this->errors, $old_style_errors ); // Run modular validations. $transformers = $this->getDataTransformers(); @@ -2464,15 +2477,6 @@ if ( $transformer instanceof ValidationHelper ) { $transformer->validate( $this, $normalized, $this->errors ); } - } - - // TODO: Rewrite as something modular? It's in-between validation and normalization... - if ( isset( $this->errors['currency_code'] ) ) { - // Try to fall back to a default currency, clearing the error if - // successful. - $this->fallbackToDefaultCurrency(); - // FIXME: This is part of the same wart. - $this->unstaged_data = $this->dataObj->getData(); } return $this->validatedOK(); -- To view, visit https://gerrit.wikimedia.org/r/343795 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icf39eeb26860f58ba5244b36d01dcac060c81027 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: House modules under a package
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343764 ) Change subject: House modules under a package .. House modules under a package Change-Id: Ifa551b4db4a4e7557c40fbfec4ecf72af8b135b6 --- M bin/cron-generate M bin/run-job R processcontrol/crontab.py R processcontrol/job_wrapper.py R processcontrol/lock.py M setup.py 6 files changed, 4 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/64/343764/1 diff --git a/bin/cron-generate b/bin/cron-generate index d1adb6f..273642a 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -2,8 +2,8 @@ import sys -import crontab -import job_wrapper +import processcontrol.crontab +import processcontrol.job_wrapper def usage(): diff --git a/bin/run-job b/bin/run-job index a3ae229..054f787 100755 --- a/bin/run-job +++ b/bin/run-job @@ -2,7 +2,7 @@ import sys -import job_wrapper +import processcontrol.job_wrapper def usage(): diff --git a/crontab.py b/processcontrol/crontab.py similarity index 100% rename from crontab.py rename to processcontrol/crontab.py diff --git a/job_wrapper.py b/processcontrol/job_wrapper.py similarity index 100% rename from job_wrapper.py rename to processcontrol/job_wrapper.py diff --git a/lock.py b/processcontrol/lock.py similarity index 100% rename from lock.py rename to processcontrol/lock.py diff --git a/setup.py b/setup.py index d80d0eb..306aeea 100755 --- a/setup.py +++ b/setup.py @@ -8,11 +8,7 @@ author='Adam Roses Wight', author_email='awi...@wikimedia.org', url='https://github.com/adamwight/process-control', -py_modules=[ -'crontab', -'job_wrapper', -'lock', -], +packages=['processcontrol'], scripts=[ 'bin/cron-generate', 'bin/run-job', -- To view, visit https://gerrit.wikimedia.org/r/343764 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifa551b4db4a4e7557c40fbfec4ecf72af8b135b6 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Only run under python3
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343763 ) Change subject: Only run under python3 .. Only run under python3 Change-Id: If41707720ee3309241fec3ea5b5d5bd490bffba0 --- M bin/cron-generate M bin/run-job 2 files changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/63/343763/1 diff --git a/bin/cron-generate b/bin/cron-generate index 81c69f2..d1adb6f 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import sys diff --git a/bin/run-job b/bin/run-job index faff43e..a3ae229 100755 --- a/bin/run-job +++ b/bin/run-job @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import sys -- To view, visit https://gerrit.wikimedia.org/r/343763 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If41707720ee3309241fec3ea5b5d5bd490bffba0 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Barely functional debian packaging
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343762 ) Change subject: Barely functional debian packaging .. Barely functional debian packaging Change-Id: I520c8d4e010fb523ed1fa03639b68b6431068875 --- M bin/cron-generate M bin/run-job M debian/changelog M debian/control A debian/docs M debian/rules A setup.py 7 files changed, 32 insertions(+), 15 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/62/343762/1 diff --git a/bin/cron-generate b/bin/cron-generate index 6b093aa..81c69f2 100755 --- a/bin/cron-generate +++ b/bin/cron-generate @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import sys diff --git a/bin/run-job b/bin/run-job index 82a9a78..faff43e 100755 --- a/bin/run-job +++ b/bin/run-job @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import sys diff --git a/debian/changelog b/debian/changelog index 46b6d21..3d5dac1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python-process-control (0.0.1~rc1-1) UNRELEASED; urgency=low +process-control (0.0.1~rc1-1) UNRELEASED; urgency=low * Initial release. diff --git a/debian/control b/debian/control index ce8c882..f0214cf 100644 --- a/debian/control +++ b/debian/control @@ -1,23 +1,16 @@ -Source: python-process-control +Source: process-control Maintainer: Adam Roses WightSection: admin Priority: optional -Build-Depends: debhelper (>= 9), python-all, python-setuptools, python3-all, python3-setuptools +Build-Depends: debhelper (>= 9), python3-all, python3-setuptools Standards-Version: 3.9.8 Homepage: https://github.com/adamwight/process-control Vcs-Browser: https://github.com/adamwight/process-control Vcs-Git: git://github.com/adamwight/process-control.git -X-Python-Version: >= 2.6 X-Python3-Version: >= 3.2 -Package: python-process-control +Package: process-control Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} -Description: Tools for Wikimedia Foundation Fundraising job management - Control and schedule jobs using configuration files. - -Package: python3-process-control -Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, ${python3:Depends} +Depends: ${python3:Depends}, python3-yaml Description: Tools for Wikimedia Foundation Fundraising job management Control and schedule jobs using configuration files. diff --git a/debian/docs b/debian/docs new file mode 100644 index 000..b43bf86 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +README.md diff --git a/debian/rules b/debian/rules index 04fac7a..086b21a 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,7 @@ #!/usr/bin/make -f +#export DH_VERBOSE=1 +export PYBUILD_NAME=process-control + %: - dh $@ --with python2,python3 --buildsystem=pybuild + dh $@ --with python3 diff --git a/setup.py b/setup.py new file mode 100755 index 000..d80d0eb --- /dev/null +++ b/setup.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +import distutils.core + +distutils.core.setup( +name='process-control', +version='0.0.1', +author='Adam Roses Wight', +author_email='awi...@wikimedia.org', +url='https://github.com/adamwight/process-control', +py_modules=[ +'crontab', +'job_wrapper', +'lock', +], +scripts=[ +'bin/cron-generate', +'bin/run-job', +], +) -- To view, visit https://gerrit.wikimedia.org/r/343762 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I520c8d4e010fb523ed1fa03639b68b6431068875 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Create a bin dir
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343761 ) Change subject: Create a bin dir .. Create a bin dir Change-Id: I7790f12316f0203511ffa82e37521231fa4dca2f --- M README.md R bin/cron-generate R bin/run-job 3 files changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/61/343761/1 diff --git a/README.md b/README.md index 10f2af5..42b2301 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ === To run a job, point at its description file: -crash-override job-desc.yaml +run-job job-desc.yaml A job description file has the following format, diff --git a/cron-generate b/bin/cron-generate similarity index 100% rename from cron-generate rename to bin/cron-generate diff --git a/crash-override b/bin/run-job similarity index 100% rename from crash-override rename to bin/run-job -- To view, visit https://gerrit.wikimedia.org/r/343761 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7790f12316f0203511ffa82e37521231fa4dca2f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: [WIP] Debian packaging
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343218 ) Change subject: [WIP] Debian packaging .. [WIP] Debian packaging Change-Id: Ib4a8481ecc40e72e39c4670bad93786505f8d0d1 TODO: Making empty packages at the moment. copy README. --- A debian/changelog A debian/compat A debian/control A debian/copyright A debian/rules A debian/source/format A debian/upstream/metadata 7 files changed, 48 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/18/343218/1 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000..46b6d21 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +python-process-control (0.0.1~rc1-1) UNRELEASED; urgency=low + + * Initial release. + + -- Adam Roses WightThu, 16 Mar 2017 00:12:17 -0700 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000..767c468 --- /dev/null +++ b/debian/control @@ -0,0 +1,23 @@ +Source: python-process-control +Maintainer: Adam Roses Wight +Section: admin +Priority: optional +Build-Depends: debhelper (>= 9), python-all, python-setuptools, python3-all, python3-setuptools +Standards-Version: 3.9.8 +Homepage: https://github.com/adamwight/process-control +Vcs-Browser: https://github.com/adamwight/process-control +Vcs-Git: git://github.com/adamwight/process-control.git +X-Python-Version: >= 2.6 +X-Python3-Version: >= 3.2 + +Package: python-process-control +Architecture: all +Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} +Description: Tools for Wikimedia Foundation Fundraising job management + Control and schedule jobs using configuration files. + +Package: python3-process-control +Architecture: all +Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} +Description: Tools for Wikimedia Foundation Fundraising job management + Control and schedule jobs using configuration files. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000..ebd8e4d --- /dev/null +++ b/debian/copyright @@ -0,0 +1,7 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: https://github.com/adamwight/process-control + +Files: *.py *.md *.yaml debian/* .gitignore +Copyright: 2017, Adam Roses Wight +License: GPL-2 + /usr/share/common-licenses/GPL-2 diff --git a/debian/rules b/debian/rules new file mode 100755 index 000..5b2ea99 --- /dev/null +++ b/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export PYBUILD_TEST_PLUGIN = nose + +%: + dh $@ --with python2,python3 diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 000..2922586 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,5 @@ +Bug-Database: https://github.com/adamwight/process-control/issues +Bug-Submit: https://github.com/adamwight/process-control/issues/new +Contact: Adam Roses Wight +Repository: git://github.com/adamwight/process-control.git +Repository-Browse: https://github.com/adamwight/process-control -- To view, visit https://gerrit.wikimedia.org/r/343218 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib4a8481ecc40e72e39c4670bad93786505f8d0d1 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: DO NOT MERGE: instrument the damn test
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343213 ) Change subject: DO NOT MERGE: instrument the damn test .. DO NOT MERGE: instrument the damn test Change-Id: I8976df22a1e2a396a6f48f2c455b946b864ddfa5 --- M tests/test_crontab.py 1 file changed, 3 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/13/343213/1 diff --git a/tests/test_crontab.py b/tests/test_crontab.py index a3178be..b16c8af 100644 --- a/tests/test_crontab.py +++ b/tests/test_crontab.py @@ -1,4 +1,6 @@ +from __future__ import print_function import os.path +import sys import crontab @@ -18,4 +20,5 @@ # Skipping disabled job X/unscheduled.yaml """ +print(tab, file=sys.stderr) assert expected == tab -- To view, visit https://gerrit.wikimedia.org/r/343213 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8976df22a1e2a396a6f48f2c455b946b864ddfa5 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Note that you have to quote crontab due to its punctuation
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343212 ) Change subject: Note that you have to quote crontab due to its punctuation .. Note that you have to quote crontab due to its punctuation Change-Id: I23c8a540cb1f7af3118488a4bb6dcf5d1f657d07 --- M README.md 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/12/343212/1 diff --git a/README.md b/README.md index d1653ec..10f2af5 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ # Optional schedule, in Vixie cron format: # minute hour day-of-month month day-of-week -schedule: */5 * * * * +schedule: "*/5 * * * *" # Optional flag to prevent scheduled job execution. The job # can still be run as a single-shot. -- To view, visit https://gerrit.wikimedia.org/r/343212 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I23c8a540cb1f7af3118488a4bb6dcf5d1f657d07 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: "disabled" flag
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343195 ) Change subject: "disabled" flag .. "disabled" flag Change-Id: I055c025544c8f194cd9cfe2d21d43efadb7b5c43 --- M README.md M crontab.py M job_wrapper.py A tests/data/disabled.yaml A tests/data/scheduled/disabled.yaml M tests/test_crontab.py 6 files changed, 28 insertions(+), 4 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/95/343195/1 diff --git a/README.md b/README.md index 9fa2527..d1653ec 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ command: /usr/local/bin/timecard --start 9:00 --end 5:30 +# Optional schedule, in Vixie cron format: +# minute hour day-of-month month day-of-week +schedule: */5 * * * * + +# Optional flag to prevent scheduled job execution. The job +# can still be run as a single-shot. +disabled: true + # Optional timeout in seconds, after which your job will be # aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT timeout: 30 @@ -52,3 +60,5 @@ * Script to kill jobs. * Script to run a job one-off. * Job group tags. +* Slow-start and monitoring. +* Optional backoff. diff --git a/crontab.py b/crontab.py index 0f1d399..90e8908 100644 --- a/crontab.py +++ b/crontab.py @@ -34,7 +34,7 @@ class JobCrontab(object): def __init__(self, job=None): self.job = job -if "schedule" in job.config: +if "schedule" in job.config and job.enabled: self.enabled = True else: self.enabled = False diff --git a/job_wrapper.py b/job_wrapper.py index e07de16..4813b3a 100644 --- a/job_wrapper.py +++ b/job_wrapper.py @@ -27,9 +27,15 @@ else: self.timeout = DEFAULT_TIMEOUT -def run(self): -# if "disabled" in self.config and self.config["disabled"] in ["1", "true"]: +if "disabled" in self.config and self.config["disabled"] is True: +self.enabled = False +else: +self.enabled = True +if "schedule" not in self.config: +self.enabled = False + +def run(self): lock.begin(job_tag=self.name) command = shlex.split(self.config["command"]) diff --git a/tests/data/disabled.yaml b/tests/data/disabled.yaml new file mode 100644 index 000..c9baf66 --- /dev/null +++ b/tests/data/disabled.yaml @@ -0,0 +1,3 @@ +name: Disabled job +command: /bin/true +disabled: true diff --git a/tests/data/scheduled/disabled.yaml b/tests/data/scheduled/disabled.yaml new file mode 100644 index 000..46de851 --- /dev/null +++ b/tests/data/scheduled/disabled.yaml @@ -0,0 +1,4 @@ +name: No cron +command: /bin/true +disabled: true +schedule: "* * * * *" diff --git a/tests/test_crontab.py b/tests/test_crontab.py index a3178be..c0503ad 100644 --- a/tests/test_crontab.py +++ b/tests/test_crontab.py @@ -11,7 +11,8 @@ tab = tab.replace(test_conf_dir, "X") tab = tab.replace(crontab.RUNNER_PATH, "Y") -expected = """# Generated from X/schedule_2.yaml +expected = """# Skipping disabled job X/disabled.yaml +# Generated from X/schedule_2.yaml */10 * * * * jenkins Y X/schedule_2.yaml # Generated from X/schedule_good.yaml */5 * * * * jenkins Y X/schedule_good.yaml -- To view, visit https://gerrit.wikimedia.org/r/343195 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I055c025544c8f194cd9cfe2d21d43efadb7b5c43 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Rough pass at crontab tweezer
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343171 ) Change subject: Rough pass at crontab tweezer .. Rough pass at crontab tweezer Change-Id: I200787ae2f86e3caacbc02db0f674f3c08755533 --- M README.md A cron-generate A crontab.py M job_wrapper.py A tests/data/scheduled/schedule_2.yaml A tests/data/scheduled/schedule_good.yaml A tests/data/scheduled/unscheduled.yaml A tests/test_crontab.py M tests/test_lock.py 9 files changed, 116 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/71/343171/1 diff --git a/README.md b/README.md index c5300d6..9fa2527 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,7 @@ * Prevent future job runs when unrecoverable failure conditions are detected. * Should we support commandline flags? * Fine-tuning of failure detection. +* Script to tweeze crontab. +* Script to kill jobs. +* Script to run a job one-off. +* Job group tags. diff --git a/cron-generate b/cron-generate new file mode 100755 index 000..6b093aa --- /dev/null +++ b/cron-generate @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +import sys + +import crontab +import job_wrapper + + +def usage(): + print("Must give a job description directory as the only argument.") + + +if __name__ == "__main__": +# TODO: Parse CLI args. + + if len(sys.argv) != 2: + usage() + sys.exit(-1) + + config_dir = sys.argv[1] + + print(crontab.make_cron(config_dir)) diff --git a/crontab.py b/crontab.py new file mode 100644 index 000..0f1d399 --- /dev/null +++ b/crontab.py @@ -0,0 +1,56 @@ +import glob +import os.path + +import job_wrapper + + +# FIXME: global config +DEFAULT_USER = "jenkins" + +CRON_TEMPLATE = """# Generated from {source} +{schedule} {user} {command} +""" + +RUNNER_PATH = os.path.dirname(__file__) + "/crash-override" + + +def make_cron(config_dir): +''' +Read all files from the dir and output a crontab. +''' +out = "" + +config_files = glob.glob(config_dir + "/*.yaml") + +for config_path in config_files: +job = job_wrapper.JobWrapper(config_path=config_path) +tab = JobCrontab(job) + +out += str(tab) + +return out + + +class JobCrontab(object): +def __init__(self, job=None): +self.job = job +if "schedule" in job.config: +self.enabled = True +else: +self.enabled = False + +def __str__(self): +if not self.enabled: +return "# Skipping disabled job {path}\n".format(path=self.job.config_path) + +command = "{runner} {conf}".format( +runner=RUNNER_PATH, +conf=self.job.config_path) + +out = CRON_TEMPLATE.format( +source=self.job.config_path, +schedule=self.job.config["schedule"], +user=DEFAULT_USER, +command=command) + +return out diff --git a/job_wrapper.py b/job_wrapper.py index 9ae8512..e07de16 100644 --- a/job_wrapper.py +++ b/job_wrapper.py @@ -8,12 +8,14 @@ import lock + # TODO: Global config. DEFAULT_TIMEOUT = 600 class JobWrapper(object): def __init__(self, config_path=None): +self.config_path = config_path self.config = yaml.safe_load(open(config_path, "r")) self.validate_config() @@ -26,6 +28,8 @@ self.timeout = DEFAULT_TIMEOUT def run(self): +# if "disabled" in self.config and self.config["disabled"] in ["1", "true"]: + lock.begin(job_tag=self.name) command = shlex.split(self.config["command"]) diff --git a/tests/data/scheduled/schedule_2.yaml b/tests/data/scheduled/schedule_2.yaml new file mode 100644 index 000..8d95ded --- /dev/null +++ b/tests/data/scheduled/schedule_2.yaml @@ -0,0 +1,3 @@ +name: Another cronjob +command: /bin/true +schedule: "*/10 * * * *" diff --git a/tests/data/scheduled/schedule_good.yaml b/tests/data/scheduled/schedule_good.yaml new file mode 100644 index 000..5f4476e --- /dev/null +++ b/tests/data/scheduled/schedule_good.yaml @@ -0,0 +1,3 @@ +name: Valid cron +command: /bin/true +schedule: "*/5 * * * *" diff --git a/tests/data/scheduled/unscheduled.yaml b/tests/data/scheduled/unscheduled.yaml new file mode 100644 index 000..7d8caa5 --- /dev/null +++ b/tests/data/scheduled/unscheduled.yaml @@ -0,0 +1,2 @@ +name: No cron +command: /bin/true diff --git a/tests/test_crontab.py b/tests/test_crontab.py new file mode 100644 index 000..a3178be --- /dev/null +++ b/tests/test_crontab.py @@ -0,0 +1,21 @@ +import os.path + +import crontab + + +def test_crontab(): +test_conf_dir = os.path.dirname(__file__) + "/data/scheduled" +tab = crontab.make_cron(test_conf_dir) + +# Strip regional variations. +tab = tab.replace(test_conf_dir, "X") +tab = tab.replace(crontab.RUNNER_PATH, "Y") + +expected = """# Generated from
[MediaWiki-commits] [Gerrit] wikimedia...process-control[debian-packaging]: [WIP] Debian packaging
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343129 ) Change subject: [WIP] Debian packaging .. [WIP] Debian packaging Change-Id: Ib4a8481ecc40e72e39c4670bad93786505f8d0d1 TODO: Making empty packages at the moment. copy README. --- A debian/changelog A debian/compat A debian/control A debian/copyright A debian/rules A debian/source/format A debian/upstream/metadata 7 files changed, 48 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/29/343129/1 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000..46b6d21 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +python-process-control (0.0.1~rc1-1) UNRELEASED; urgency=low + + * Initial release. + + -- Adam Roses WightThu, 16 Mar 2017 00:12:17 -0700 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000..767c468 --- /dev/null +++ b/debian/control @@ -0,0 +1,23 @@ +Source: python-process-control +Maintainer: Adam Roses Wight +Section: admin +Priority: optional +Build-Depends: debhelper (>= 9), python-all, python-setuptools, python3-all, python3-setuptools +Standards-Version: 3.9.8 +Homepage: https://github.com/adamwight/process-control +Vcs-Browser: https://github.com/adamwight/process-control +Vcs-Git: git://github.com/adamwight/process-control.git +X-Python-Version: >= 2.6 +X-Python3-Version: >= 3.2 + +Package: python-process-control +Architecture: all +Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} +Description: Tools for Wikimedia Foundation Fundraising job management + Control and schedule jobs using configuration files. + +Package: python3-process-control +Architecture: all +Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} +Description: Tools for Wikimedia Foundation Fundraising job management + Control and schedule jobs using configuration files. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000..ebd8e4d --- /dev/null +++ b/debian/copyright @@ -0,0 +1,7 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: https://github.com/adamwight/process-control + +Files: *.py *.md *.yaml debian/* .gitignore +Copyright: 2017, Adam Roses Wight +License: GPL-2 + /usr/share/common-licenses/GPL-2 diff --git a/debian/rules b/debian/rules new file mode 100755 index 000..5b2ea99 --- /dev/null +++ b/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export PYBUILD_TEST_PLUGIN = nose + +%: + dh $@ --with python2,python3 diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 000..2922586 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,5 @@ +Bug-Database: https://github.com/adamwight/process-control/issues +Bug-Submit: https://github.com/adamwight/process-control/issues/new +Contact: Adam Roses Wight +Repository: git://github.com/adamwight/process-control.git +Repository-Browse: https://github.com/adamwight/process-control -- To view, visit https://gerrit.wikimedia.org/r/343129 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib4a8481ecc40e72e39c4670bad93786505f8d0d1 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: debian-packaging Gerrit-Owner: Awight ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: More docs
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343124 ) Change subject: More docs .. More docs Change-Id: Id210abfa259c8f3bc2c9e62ba8fc2907554fc70a --- M README.md 1 file changed, 29 insertions(+), 6 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/24/343124/1 diff --git a/README.md b/README.md index 8bce9c0..c5300d6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ Job wrapper which does a bit of bookkeeping for a subprocess. * Prevents simultaneous runners by saving a lock file per job. -* Configurable by commandline or config file parameters. -* Captures stdout and stderr, and can do TBD things with the output. -* Can prevent future job runs when unrecoverable failure conditions are detected. +* Configurable by config file parameters. +* Captures stdout and stderr. We can redirect stdout to a +file. Any stderr is interpreted as a job failure. + +Running and configuration +=== To run a job, point at its description file: crash-override job-desc.yaml @@ -15,13 +18,33 @@ command: /usr/local/bin/timecard --start 9:00 --end 5:30 -# Optional timeout in seconds, after which your job will be aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT +# Optional timeout in seconds, after which your job will be +# aborted. Defaults to 10 minutes, JobWrapper.DEFAULT_TIMEOUT timeout: 30 -# Optional filename for the job output. All output will be concatenated into this file, with a header for each job. +# Optional filename for the job output. All output will be +# concatenated into this file, with a header for each job. stdout_destination: "/tmp/jobnuts.log" ``` -TODO: +Failure detection +== + +The following conditions will be interpreted as a job failure, after +which we report the problem to stderr and exit with a non-zero return +code. + +* Any output on stderr. This output is relayed back to the calling +process stderr, so may be included in failure email at the moment. +* Non-zero subprocess exit code. +* Timeout. + + +TODO + + * Syslog actions, at least when tweezing new crontabs. * Log invocations. +* Prevent future job runs when unrecoverable failure conditions are detected. +* Should we support commandline flags? +* Fine-tuning of failure detection. -- To view, visit https://gerrit.wikimedia.org/r/343124 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id210abfa259c8f3bc2c9e62ba8fc2907554fc70a Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Fix flake8 typos
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343121 ) Change subject: Fix flake8 typos .. Fix flake8 typos Change-Id: I7b76505cb5c02db1fbe1eb7350f5a3c59d28c459 --- M lock.py M tests/test_job_wrapper.py M tests/test_validation.py 3 files changed, 4 insertions(+), 7 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/21/343121/1 diff --git a/lock.py b/lock.py index 67e2cdd..6c91863 100644 --- a/lock.py +++ b/lock.py @@ -8,8 +8,6 @@ import os.path import sys -from logging import Logger as log - lockfile = None diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index bd020d9..2c61a50 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -1,4 +1,3 @@ -import datetime import iocapture import nose import os diff --git a/tests/test_validation.py b/tests/test_validation.py index 19bd635..2cee3e5 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -15,22 +15,22 @@ @nose.tools.raises(AssertionError) def test_missing_fields(): -job = load_job("missing_fields.yaml") +load_job("missing_fields.yaml") @nose.tools.raises(AssertionError) def test_schedule_atsign(): -job = load_job("schedule_atsign.yaml") +load_job("schedule_atsign.yaml") @nose.tools.raises(AssertionError) def test_schedule_assign(): -job = load_job("schedule_assign.yaml") +load_job("schedule_assign.yaml") @nose.tools.raises(AssertionError) def test_schedule_invalid(): -job = load_job("schedule_invalid.yaml") +load_job("schedule_invalid.yaml") def test_schedule_good(): -- To view, visit https://gerrit.wikimedia.org/r/343121 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7b76505cb5c02db1fbe1eb7350f5a3c59d28c459 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Config validation
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343120 ) Change subject: Config validation .. Config validation Change-Id: Id9783d59eb69c82a1552b6ef330dbed830cefe86 --- M README.md M job_wrapper.py A tests/data/missing_fields.yaml A tests/data/schedule_assign.yaml A tests/data/schedule_atsign.yaml A tests/data/schedule_good.yaml A tests/data/schedule_invalid.yaml A tests/test_validation.py 8 files changed, 71 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/20/343120/1 diff --git a/README.md b/README.md index 54583c8..8bce9c0 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,7 @@ # Optional filename for the job output. All output will be concatenated into this file, with a header for each job. stdout_destination: "/tmp/jobnuts.log" ``` + +TODO: +* Syslog actions, at least when tweezing new crontabs. +* Log invocations. diff --git a/job_wrapper.py b/job_wrapper.py index eb5d5cf..9ae8512 100644 --- a/job_wrapper.py +++ b/job_wrapper.py @@ -8,12 +8,15 @@ import lock +# TODO: Global config. DEFAULT_TIMEOUT = 600 class JobWrapper(object): def __init__(self, config_path=None): self.config = yaml.safe_load(open(config_path, "r")) +self.validate_config() + self.name = self.config["name"] self.start_time = datetime.datetime.utcnow().isoformat() @@ -75,3 +78,16 @@ print(header, file=out) out.write(stdout_data.decode("utf-8")) + +def validate_config(self): +assert "name" in self.config +assert "command" in self.config +if "schedule" in self.config: +# No tricky assignments. +assert "=" not in self.config["schedule"] +# Legal cron, but I don't want to deal with it. +assert "@" not in self.config["schedule"] + +# Be sure the schedule is valid. +terms = self.config["schedule"].split() +assert len(terms) == 5 diff --git a/tests/data/missing_fields.yaml b/tests/data/missing_fields.yaml new file mode 100644 index 000..f52d584 --- /dev/null +++ b/tests/data/missing_fields.yaml @@ -0,0 +1 @@ +command: /bin/true diff --git a/tests/data/schedule_assign.yaml b/tests/data/schedule_assign.yaml new file mode 100644 index 000..4a881a5 --- /dev/null +++ b/tests/data/schedule_assign.yaml @@ -0,0 +1,3 @@ +name: Bad assignment job +command: /bin/true +schedule: USER=root a b c d diff --git a/tests/data/schedule_atsign.yaml b/tests/data/schedule_atsign.yaml new file mode 100644 index 000..c55c51c --- /dev/null +++ b/tests/data/schedule_atsign.yaml @@ -0,0 +1,3 @@ +name: Bad schedule job +command: /bin/true +schedule: "@daily root a b c" diff --git a/tests/data/schedule_good.yaml b/tests/data/schedule_good.yaml new file mode 100644 index 000..5f4476e --- /dev/null +++ b/tests/data/schedule_good.yaml @@ -0,0 +1,3 @@ +name: Valid cron +command: /bin/true +schedule: "*/5 * * * *" diff --git a/tests/data/schedule_invalid.yaml b/tests/data/schedule_invalid.yaml new file mode 100644 index 000..9bfbe2a --- /dev/null +++ b/tests/data/schedule_invalid.yaml @@ -0,0 +1,3 @@ +name: Invalid cron +command: /bin/true +schedule: "*/5 * * *" diff --git a/tests/test_validation.py b/tests/test_validation.py new file mode 100644 index 000..19bd635 --- /dev/null +++ b/tests/test_validation.py @@ -0,0 +1,38 @@ +import nose +import os + +import job_wrapper + + +data_dir = os.path.dirname(__file__) + "/data" + + +def load_job(filename): +path = data_dir + "/" + filename +job = job_wrapper.JobWrapper(config_path=path) +return job + + +@nose.tools.raises(AssertionError) +def test_missing_fields(): +job = load_job("missing_fields.yaml") + + +@nose.tools.raises(AssertionError) +def test_schedule_atsign(): +job = load_job("schedule_atsign.yaml") + + +@nose.tools.raises(AssertionError) +def test_schedule_assign(): +job = load_job("schedule_assign.yaml") + + +@nose.tools.raises(AssertionError) +def test_schedule_invalid(): +job = load_job("schedule_invalid.yaml") + + +def test_schedule_good(): +job = load_job("schedule_good.yaml") +assert job.config["schedule"] -- To view, visit https://gerrit.wikimedia.org/r/343120 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id9783d59eb69c82a1552b6ef330dbed830cefe86 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] integration/config[master]: Run tox for new repo
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343113 ) Change subject: Run tox for new repo .. Run tox for new repo Change-Id: Iaa04f8cf6bc6dac0c9efc3109b3badea938d2fa8 --- M zuul/layout.yaml 1 file changed, 4 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/integration/config refs/changes/13/343113/1 diff --git a/zuul/layout.yaml b/zuul/layout.yaml index 8e4a35d..d0edef9 100644 --- a/zuul/layout.yaml +++ b/zuul/layout.yaml @@ -2420,6 +2420,10 @@ # Depends on node-syslog@1.1.7 which does not work on Node 4.3 - name: npm-node-0.10 + - name: wikimedia/fundraising/process-control +template: + - name: tox-jessie + - name: wikimedia/fundraising/stats gate-and-submit: - noop -- To view, visit https://gerrit.wikimedia.org/r/343113 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iaa04f8cf6bc6dac0c9efc3109b3badea938d2fa8 Gerrit-PatchSet: 1 Gerrit-Project: integration/config Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Add .gitreview
Awight has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/342967 ) Change subject: Add .gitreview .. Add .gitreview Change-Id: I027ec8c2450799814e2929d6681d15ea1c8ddb8d --- A .gitreview 1 file changed, 6 insertions(+), 0 deletions(-) Approvals: Cdentinger: Verified Awight: Looks good to me, approved diff --git a/.gitreview b/.gitreview new file mode 100644 index 000..c8e2bce --- /dev/null +++ b/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=wikimedia/fundraising/process-control.git +defaultbranch=master +defaultrebase=0 -- To view, visit https://gerrit.wikimedia.org/r/342967 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I027ec8c2450799814e2929d6681d15ea1c8ddb8d Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: AwightGerrit-Reviewer: Awight Gerrit-Reviewer: Cdentinger ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Correct failopen test
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342970 ) Change subject: Correct failopen test .. Correct failopen test Change-Id: I2316941b63079c8a7845cf957091c72ddfdda8d1 --- M tests/test_lock.py 1 file changed, 2 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/70/342970/1 diff --git a/tests/test_lock.py b/tests/test_lock.py index 469d019..cd9e35a 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -48,7 +48,7 @@ @nose.tools.raises(lock.LockError) def test_stale_lock_failopen(): tag = "stale-open" -lock.begin(job_tag=tag, failopen=True) +lock.begin(job_tag=tag) # Make the lockfile stale by changing the process ID. assert lock.lockfile @@ -56,7 +56,7 @@ f.write("-1") f.close() -lock.begin(job_tag=tag) +lock.begin(job_tag=tag, failopen=True) def test_invalid_lock(): -- To view, visit https://gerrit.wikimedia.org/r/342970 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2316941b63079c8a7845cf957091c72ddfdda8d1 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: test failopen; py3
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342969 ) Change subject: test failopen; py3 .. test failopen; py3 Change-Id: Id33866f7887aa404f453cf5ced6307fd83e2c2fd --- M lock.py M tests/test_lock.py 2 files changed, 15 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/69/342969/1 diff --git a/lock.py b/lock.py index 7efd9d7..67e2cdd 100644 --- a/lock.py +++ b/lock.py @@ -3,6 +3,7 @@ Self-corrects stale locks unless "failopen" is True. ''' +from __future__ import print_function import os import os.path import sys diff --git a/tests/test_lock.py b/tests/test_lock.py index c06e4dd..469d019 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -45,6 +45,20 @@ lock.end() +@nose.tools.raises(lock.LockError) +def test_stale_lock_failopen(): +tag = "stale-open" +lock.begin(job_tag=tag, failopen=True) + +# Make the lockfile stale by changing the process ID. +assert lock.lockfile +f = open(lock.lockfile, "w") +f.write("-1") +f.close() + +lock.begin(job_tag=tag) + + def test_invalid_lock(): tag = "stale" lock.begin(job_tag=tag) -- To view, visit https://gerrit.wikimedia.org/r/342969 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id33866f7887aa404f453cf5ced6307fd83e2c2fd Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Tests for the lock module
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342968 ) Change subject: Tests for the lock module .. Tests for the lock module Change-Id: I242a42518e1eaab5c8b039af2ac75615db9d01cc --- M lock.py M tests/data/timeout.yaml M tests/test_job_wrapper.py A tests/test_lock.py M tox.ini 5 files changed, 93 insertions(+), 21 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/68/342968/1 diff --git a/lock.py b/lock.py index 523b56c..7efd9d7 100644 --- a/lock.py +++ b/lock.py @@ -17,7 +17,7 @@ filename = "/tmp/{name}.lock".format(name=job_tag) if os.path.exists(filename): -log.warn("Lockfile found!") +print("Lockfile found!", file=sys.stderr) f = open(filename, "r") pid = None try: @@ -26,18 +26,16 @@ pass f.close() if not pid: -log.error("Invalid lockfile contents.") +print("Invalid lockfile contents.", file=sys.stderr) else: try: os.getpgid(pid) -log.error("Aborting! Previous process ({pid}) is still alive. Remove lockfile manually if in error: {path}".format(pid=pid, path=filename)) -sys.exit(1) +raise LockError("Aborting! Previous process ({pid}) is still alive. Remove lockfile manually if in error: {path}".format(pid=pid, path=filename)) except OSError: if failopen: -log.fatal("Aborting until stale lockfile is investigated: {path}".format(path=filename)) -sys.exit(1) -log.error("Lockfile is stale.") -log.info("Removing old lockfile.") +raise LockError("Aborting until stale lockfile is investigated: {path}".format(path=filename)) +print("Lockfile is stale.", file=sys.stderr) +print("Removing old lockfile.", file=sys.stderr) os.unlink(filename) f = open(filename, "w") @@ -50,7 +48,11 @@ def end(): global lockfile -if lockfile: +if lockfile and os.path.exists(lockfile): os.unlink(lockfile) else: -raise RuntimeError("Already unlocked!") +raise LockError("Already unlocked!") + + +class LockError(RuntimeError): +pass diff --git a/tests/data/timeout.yaml b/tests/data/timeout.yaml index 5dfe4ee..9e01920 100644 --- a/tests/data/timeout.yaml +++ b/tests/data/timeout.yaml @@ -1,3 +1,3 @@ name: Timing out job -command: /bin/sleep 2 +command: /bin/sleep 10 timeout: 0.1 diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index 463edbd..cea8ef6 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -1,5 +1,6 @@ import datetime import iocapture +import nose import os import job_wrapper @@ -31,9 +32,9 @@ assert captured.stderr == "Job False job failed with code 1\n" +# Must finish in less than two seconds, i.e. must have timed out. +@nose.tools.timed(2) def test_timeout(): -start_time = datetime.datetime.utcnow() - with iocapture.capture() as captured: run_job("timeout.yaml") @@ -42,11 +43,6 @@ "Job Timing out job timed out after 0.1 seconds\n" "Job Timing out job failed with code -9\n" ) - -end_time = datetime.datetime.utcnow() -delta = end_time - start_time - -assert delta.total_seconds() < 2 def test_stderr(): diff --git a/tests/test_lock.py b/tests/test_lock.py new file mode 100644 index 000..c06e4dd --- /dev/null +++ b/tests/test_lock.py @@ -0,0 +1,77 @@ +import nose +import os.path + +import lock + + +def test_success(): +tag = "success" +lock.begin(job_tag=tag) +assert lock.lockfile +assert os.path.exists(lock.lockfile) + +lock.end() +assert not os.path.exists(lock.lockfile) + + +@nose.tools.raises(lock.LockError) +def test_live_lock(): +tag = "live" +lock.begin(job_tag=tag) + +# Will die because the process (this one) is still running. +lock.begin(job_tag=tag) + + +def test_stale_lock(): +tag = "stale" +lock.begin(job_tag=tag) + +# Make the lockfile stale by changing the process ID. +assert lock.lockfile +f = open(lock.lockfile, "w") +f.write("-1") +f.close() + +lock.begin(job_tag=tag) + +# Check that we overwrote the contents with the current PID. +assert lock.lockfile +f = open(lock.lockfile, "r") +pid = int(f.read()) +f.close() +assert pid == os.getpid() + +lock.end() + + +def test_invalid_lock(): +tag = "stale" +lock.begin(job_tag=tag) + +# Make the lockfile invalid by changing the process ID to non-numeric. +assert lock.lockfile +f = open(lock.lockfile, "w") +f.write("ABC") +f.close() + +lock.begin(job_tag=tag) + +# Check that we overwrote the contents with the current PID. +assert
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: Add .gitreview
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342967 ) Change subject: Add .gitreview .. Add .gitreview Change-Id: I027ec8c2450799814e2929d6681d15ea1c8ddb8d --- A .gitreview 1 file changed, 6 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/67/342967/1 diff --git a/.gitreview b/.gitreview new file mode 100644 index 000..c8e2bce --- /dev/null +++ b/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=wikimedia/fundraising/process-control.git +defaultbranch=master +defaultrebase=0 -- To view, visit https://gerrit.wikimedia.org/r/342967 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I027ec8c2450799814e2929d6681d15ea1c8ddb8d Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] wikimedia...process-control[master]: 100% test coverage
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342971 ) Change subject: 100% test coverage .. 100% test coverage Change-Id: I80fc8f0abf20ec0d0f971f4da3762e4f7a41b448 --- M .gitignore D tests/data/boot.yaml A tests/data/which-out.yaml M tests/test_job_wrapper.py 4 files changed, 22 insertions(+), 4 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/process-control refs/changes/71/342971/1 diff --git a/.gitignore b/.gitignore index 1a0929d..d503969 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc .cache +cover +.coverage .tox diff --git a/tests/data/boot.yaml b/tests/data/boot.yaml deleted file mode 100644 index 8ae5294..000 --- a/tests/data/boot.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Boots -command: ls -timeout: 100 -stdout_destination: "/tmp/a" diff --git a/tests/data/which-out.yaml b/tests/data/which-out.yaml new file mode 100644 index 000..e29d0d8 --- /dev/null +++ b/tests/data/which-out.yaml @@ -0,0 +1,3 @@ +name: Which job +command: /bin/which bash +stdout_destination: /tmp/which-out.log diff --git a/tests/test_job_wrapper.py b/tests/test_job_wrapper.py index cea8ef6..bd020d9 100644 --- a/tests/test_job_wrapper.py +++ b/tests/test_job_wrapper.py @@ -55,3 +55,20 @@ "grep: Invalid regular expression\n\n" "Job Bad grep job failed with code 2\n" ) + + +def test_store_output(): +path = "/tmp/which-out.log" + +if os.path.exists(path): +os.unlink(path) + +run_job("which-out.yaml") + +contents = open(path, "r").read() +lines = contents.split("\n") + +assert len(lines) == 6 +assert lines[4] == "/bin/bash" + +os.unlink(path) -- To view, visit https://gerrit.wikimedia.org/r/342971 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I80fc8f0abf20ec0d0f971f4da3762e4f7a41b448 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/process-control Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] A few changes. distinguish between unstaged and norma...
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342553 ) Change subject: [WIP] A few changes. distinguish between unstaged and normalized, split construct, validate and stage steps. .. [WIP] A few changes. distinguish between unstaged and normalized, split construct, validate and stage steps. Bug: T159910 Change-Id: Ib29a85fec1c7ccf11b99c8538651cde792c75e15 --- M adyen_gateway/adyen.adapter.php M amazon_gateway/amazon.adapter.php M astropay_gateway/astropay.adapter.php M extras/FraudFilter.php M extras/banner_history/BannerHistoryLogIdProcessor.php M extras/conversion_log/conversion_log.body.php M extras/custom_filters/custom_filters.body.php M extras/custom_filters/filters/ip_velocity/ip_velocity.body.php M extras/custom_filters/filters/minfraud/minfraud.body.php M extras/custom_filters/filters/referrer/referrer.body.php M extras/custom_filters/filters/source/source.body.php M extras/session_velocity/session_velocity.body.php M gateway_common/DonationData.php M gateway_common/GatewayType.php M gateway_common/gateway.adapter.php M gateway_forms/Form.php M gateway_forms/Mustache.php M gateway_forms/MustacheErrorForm.php M globalcollect_gateway/GlobalCollectOrphanRectifier.php M globalcollect_gateway/globalcollect.adapter.php M globalcollect_gateway/orphan.adapter.php M paypal_gateway/express_checkout/paypal_express.adapter.php M paypal_gateway/legacy/paypal_legacy.adapter.php M tests/phpunit/Adapter/Adyen/AdyenTest.php M tests/phpunit/Adapter/Amazon/AmazonTest.php M tests/phpunit/Adapter/AstroPay/AstroPayTest.php M tests/phpunit/Adapter/GatewayAdapterTest.php M tests/phpunit/Adapter/GlobalCollect/BankTransferTest.php M tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php M tests/phpunit/Adapter/GlobalCollect/GlobalCollectTest.php M tests/phpunit/Adapter/GlobalCollect/RealTimeBankTransferIdealTest.php M tests/phpunit/Adapter/GlobalCollect/YandexTest.php M tests/phpunit/Adapter/PayPal/PayPalLegacyTest.php M tests/phpunit/DonationInterfaceTestCase.php M tests/phpunit/GatewayPageTest.php 35 files changed, 343 insertions(+), 353 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/53/342553/1 diff --git a/adyen_gateway/adyen.adapter.php b/adyen_gateway/adyen.adapter.php index 140fa6b..e94b086 100644 --- a/adyen_gateway/adyen.adapter.php +++ b/adyen_gateway/adyen.adapter.php @@ -98,23 +98,6 @@ //'deliveryAddressType', ); - // Add address fields for countries that use them. - $addressFields = array ( - 'billingAddress.street', - 'billingAddress.city', - 'billingAddress.postalCode', - 'billingAddress.stateOrProvince', - 'billingAddress.country', - 'billingAddressType', - 'billingAddress.houseNumberOrName', - ); - - if ( in_array( 'street', $this->getRequiredFields() ) ) { - $requestFields = array_merge( $requestFields, $addressFields ); - } - - - $this->transactions[ 'donate' ] = array( 'request' => $requestFields, 'values' => array( @@ -131,6 +114,30 @@ ); } + public function stageData() { + parent::stageData(); + + $this->tuneTransactions(); + } + + protected function tuneTransactions() { + if ( in_array( 'street', $this->getRequiredFields() ) ) { + // Add address fields for countries that use them. + $addressFields = array ( + 'billingAddress.street', + 'billingAddress.city', + 'billingAddress.postalCode', + 'billingAddress.stateOrProvince', + 'billingAddress.country', + 'billingAddressType', + 'billingAddress.houseNumberOrName', + ); + + $requestFields &= $this->transactions['donate']['request']; + $requestFields = array_merge( $requestFields, $addressFields ); + } + } + protected function getAllowedPaymentMethods() { return array( 'card', diff --git a/amazon_gateway/amazon.adapter.php b/amazon_gateway/amazon.adapter.php index 151bbd1..9a916cf 100644 --- a/amazon_gateway/amazon.adapter.php +++ b/amazon_gateway/amazon.adapter.php @@ -57,13 +57,12 @@ function __construct( $options = array() ) { parent::__construct( $options ); + } - if (
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Comments and todos
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342547 ) Change subject: Comments and todos .. Comments and todos Change-Id: I16be18f5618cb34b341b6c3b76c730b928f727c9 --- M gateway_common/GatewayPage.php M gateway_common/donation.api.php M gateway_common/gateway.adapter.php 3 files changed, 11 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/47/342547/1 diff --git a/gateway_common/GatewayPage.php b/gateway_common/GatewayPage.php index 8d32960..104c519 100644 --- a/gateway_common/GatewayPage.php +++ b/gateway_common/GatewayPage.php @@ -122,6 +122,7 @@ return; } + // FIXME: Should have checked this before creating the adapter. if ( $this->adapter->getGlobal( 'Enabled' ) !== true ) { $this->logger->info( 'Displaying fail page for disabled gateway' ); $this->displayFailPage(); @@ -341,7 +342,8 @@ protected function handleDonationRequest() { $this->setHeaders(); - // TODO: this is where we should feed GPCS parameters into DonationData. + // TODO: This is where we should feed GPCS parameters into the gateway + // and DonationData, rather than harvest params in the adapter itself. // dispatch forms/handling if ( $this->adapter->checkTokens() ) { diff --git a/gateway_common/donation.api.php b/gateway_common/donation.api.php index d560699..8b2e1fa 100644 --- a/gateway_common/donation.api.php +++ b/gateway_common/donation.api.php @@ -30,6 +30,7 @@ $gatewayObj->revalidate(); if ( $gatewayObj->getAllErrors() ) { $outputResult['errors'] = $gatewayObj->getAllErrors(); + // FIXME: What is this junk? Smaller API, like getResult()->addErrors $this->getResult()->setIndexedTagName( $outputResult['errors'], 'error' ); $this->getResult()->addValue( null, 'result', $outputResult ); return; diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 8d7ed15..24bd3b0 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -237,6 +237,7 @@ $this->session_resetOnSwitch(); // Need to do this before creating DonationData // FIXME: this should not have side effects like setting order_id_meta['final'] + // TODO: On second thought, neither set data nor validate in this constructor. $this->dataObj = new DonationData( $this, $options['external_data'] ); $this->setValidationErrors( $this->getOriginalValidationErrors() ); @@ -348,6 +349,8 @@ } foreach ( $this->config['transformers'] as $className ) { + // TODO: Pass $this to the constructor so we can take gateway out + // of the interfaces. $this->data_transformers[] = new $className(); } } @@ -896,10 +899,12 @@ $this->session_addDonorData(); if ( !$this->validatedOK() ){ //If the data didn't validate okay, prevent all data transmissions. + // TODO: Rename variable to "response". $return = new PaymentTransactionResponse(); $return->setCommunicationStatus( false ); $return->setMessage( 'Failed data validation' ); foreach ( $this->getAllErrors() as $code => $error ) { + // TODO: Error should already be in a native format. $return->addError( $code, array( 'message' => $error, 'logLevel' => LogLevel::INFO, 'debugInfo' => '' ) ); } // TODO: should we set $this->transaction_response ? @@ -1470,6 +1475,8 @@ /** * Parse the response to get the errors in a format we can log and otherwise deal with. * @return array a key/value array of codes (if they exist) and messages. +* TODO: Move to a parsing class, where these are part of an interface +* rather than empty although non-abstract. */ protected function parseResponseErrors( $response ) { return array(); -- To view, visit https://gerrit.wikimedia.org/r/342547 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I16be18f5618cb34b341b6c3b76c730b928f727c9 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Correct parameters to wfMessage
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342548 ) Change subject: Correct parameters to wfMessage .. Correct parameters to wfMessage FIXME: Wrap a more sane API than wfMessage. Use the message class directly, and pass params without c_u_f_a, maybe via the functional interface. Change-Id: I43808d60c2763804823d0c7ad735c50edada9851 --- M gateway_common/MessageUtils.php M gateway_common/WmfFramework.mediawiki.php 2 files changed, 11 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/48/342548/1 diff --git a/gateway_common/MessageUtils.php b/gateway_common/MessageUtils.php index e05cfdb..2ce5025 100644 --- a/gateway_common/MessageUtils.php +++ b/gateway_common/MessageUtils.php @@ -27,19 +27,24 @@ # look for the first message that exists foreach ( $msg_keys as $m ){ if ( WmfFramework::messageExists( $m, $language ) ){ - return WmfFramework::formatMessage( $m, $params ); + // FIXME: Just use a sane function signature. + $varargs = array_merge( array( $m ), $params ); + return call_user_func_array( 'WmfFramework::formatMessage', $varargs ); } } # we found nothing in the requested language, return the first fallback message that exists + # FIXME: How is this different than the above loop? foreach ( $msg_keys as $m ){ if ( WmfFramework::messageExists( $m, $language ) ){ - return WmfFramework::formatMessage( $m, $params ); + $varargs = array_merge( array( $m ), $params ); + return call_user_func_array( 'WmfFramework::formatMessage', $varargs ); } } # somehow we still don't have a message, return a default error message - return WmfFramework::formatMessage( $msg_keys[0], $params ); + $varargs = array_merge( array( $msg_keys[0] ), $params ); + return call_user_func_array( 'WmfFramework::formatMessage', $varargs ); } /** diff --git a/gateway_common/WmfFramework.mediawiki.php b/gateway_common/WmfFramework.mediawiki.php index 37ecf9b..9c03541 100644 --- a/gateway_common/WmfFramework.mediawiki.php +++ b/gateway_common/WmfFramework.mediawiki.php @@ -31,8 +31,9 @@ return wfHostname(); } - static function formatMessage( $message_identifier /*, ... */ ) { - return call_user_func_array( 'wfMessage', func_get_args() )->text(); + static function formatMessage( /* $message_identifier, ... */ ) { + $args = func_get_args(); + return call_user_func_array( 'wfMessage', $args )->text(); } static function getLanguageCode() { -- To view, visit https://gerrit.wikimedia.org/r/342548 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I43808d60c2763804823d0c7ad735c50edada9851 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Play with stringification
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342176 ) Change subject: [WIP] Play with stringification .. [WIP] Play with stringification Change-Id: Ida2727720bd27eb26d789b026d497cf158fe1540 --- M gateway_common/DonationData.php M tests/phpunit/Adapter/Amazon/AmazonTest.php M tests/phpunit/DonationDataTest.php M tests/phpunit/DonationInterfaceTestCase.php M tests/phpunit/includes/test_gateway/TestingGlobalCollectAdapter.php 5 files changed, 30 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/76/342176/1 diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php index 35019fc..51fd091 100644 --- a/gateway_common/DonationData.php +++ b/gateway_common/DonationData.php @@ -253,7 +253,15 @@ * @param string $val The value you'd like to assign to the key. */ public function setVal( $key, $val ) { - $this->normalized[$key] = $val; + // Convert empty to null for consistency. + if ( $val === '' ) { + $val = null; + } + + $this->normalized[$key] = (string) $val; + + // TODO: Set something dirty so that we're sure to normalize before + // pulling data. } /** @@ -302,6 +310,15 @@ // FIXME: there's a ghost invocation during DonationData construction. // This condition should actually be "did data come from anywhere?" if ( !empty( $this->normalized ) ) { + // Cast all values to string. + $toStringOrNull = function ( $value ) { + if ( $value === null || $value === '' ) { + return null; + } + return (string) $value; + }; + $this->normalized = array_map( $toStringOrNull, $this->normalized ); + $updateCtRequired = $this->handleContributionTrackingID(); // Before Order ID $this->setNormalizedOrderIDs(); $this->setReferrer(); diff --git a/tests/phpunit/Adapter/Amazon/AmazonTest.php b/tests/phpunit/Adapter/Amazon/AmazonTest.php index 8284d51..b7c2ef9 100644 --- a/tests/phpunit/Adapter/Amazon/AmazonTest.php +++ b/tests/phpunit/Adapter/Amazon/AmazonTest.php @@ -65,6 +65,8 @@ * Integration test to verify that the Amazon gateway converts Canadian * dollars before redirecting * +* FIXME: Merge with currency fallback tests? +* * @dataProvider canadaLanguageProvider */ function testCanadianDollarConversion( $language ) { diff --git a/tests/phpunit/DonationDataTest.php b/tests/phpunit/DonationDataTest.php index 96b7cfc..1f69d2b 100644 --- a/tests/phpunit/DonationDataTest.php +++ b/tests/phpunit/DonationDataTest.php @@ -88,10 +88,12 @@ $ddObj = new DonationData( $this->getFreshGatewayObject( self::$initial_vars ) ); //as if we were posted. $returned = $ddObj->getData(); - $expected = array( 'posted' => '', + $expected = array( 'amount' => '0.00', 'appeal' => 'JimmyQuote', 'country' => 'XX', + 'currency_code' => '', + 'email' => '', 'payment_method' => '', 'referrer' => '', 'utm_source' => '..', diff --git a/tests/phpunit/DonationInterfaceTestCase.php b/tests/phpunit/DonationInterfaceTestCase.php index 9a33ce1..6f98a66 100644 --- a/tests/phpunit/DonationInterfaceTestCase.php +++ b/tests/phpunit/DonationInterfaceTestCase.php @@ -434,23 +434,23 @@ * @return GatewayAdapter The new relevant gateway adapter object. */ function getFreshGatewayObject( $external_data = null, $setup_hacks = array() ) { - $p1 = null; + $data = null; if ( !is_null( $external_data ) ) { - $p1 = array ( + $data = array ( 'external_data' => $external_data, ); } if ( $setup_hacks ) { - if ( !is_null( $p1 ) ) { - $p1 = array_merge( $p1, $setup_hacks ); + if ( !is_null( $data ) ) { + $data = array_merge( $data, $setup_hacks ); } else { - $p1 = $setup_hacks; + $data = $setup_hacks; } } $class =
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Stop prematurely escaping
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/342047 ) Change subject: Stop prematurely escaping .. Stop prematurely escaping Escaping should be done before HTML display, not as pseduo-sanitization. Change-Id: Ifefc3f5990992730098dede918ccee269cad0194 --- M astropay_gateway/astropay.adapter.php M gateway_common/DonationData.php M gateway_common/gateway.adapter.php M tests/phpunit/Adapter/GlobalCollect/GlobalCollectTest.php 4 files changed, 16 insertions(+), 33 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/47/342047/1 diff --git a/astropay_gateway/astropay.adapter.php b/astropay_gateway/astropay.adapter.php index 6e042fd..950f5b4 100644 --- a/astropay_gateway/astropay.adapter.php +++ b/astropay_gateway/astropay.adapter.php @@ -359,8 +359,8 @@ } else if ( preg_match( '/param x_cpf$/i', $response['desc'] ) ) { // Something wrong with the fiscal number $context = 'fiscal_number'; - $language = $this->dataObj->getVal_Escaped( 'language' ); - $country = $this->dataObj->getVal_Escaped( 'country' ); + $language = $this->dataObj->getVal( 'language' ); + $country = $this->dataObj->getVal( 'country' ); $message = DataValidator::getErrorMessage( 'fiscal_number', 'calculated', $language, $country ); } else if ( preg_match( '/invalid control/i', $response['desc'] ) ) { // They think we screwed up the signature. Log what we signed. diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php index 07c6d43..26088eb 100644 --- a/gateway_common/DonationData.php +++ b/gateway_common/DonationData.php @@ -201,13 +201,12 @@ } /** -* Returns an array of normalized and escaped donation data +* Returns the array of all normalized donation data. +* * @return array */ - public function getDataEscaped() { - $escaped = $this->normalized; - array_walk( $escaped, array( $this, 'sanitizeInput' ) ); - return $escaped; + public function getData() { + return $this->normalized; } /** @@ -229,30 +228,14 @@ } /** -* getVal_Escaped -* @param string $key The data field you would like to retrieve. Pulls the -* data from $this->normalized if it is found to be something. -* @return mixed The normalized and escaped value of that $key. -*/ - public function getVal_Escaped( $key ) { - if ( $this->isSomething( $key ) ) { - //TODO: If we ever start sanitizing in a more complicated way, we should move this - //off to a function and have both getVal_Escaped and sanitizeInput call that. - return htmlspecialchars( $this->normalized[$key], ENT_COMPAT, 'UTF-8', false ); - } else { - return null; - } - } - - /** -* getVal -* For Internal Use Only! External objects should use getVal_Escaped. +* Return the value at a key, or null if the key isn't populated. +* * @param string $key The data field you would like to retrieve directly * from $this->normalized. * @return mixed The normalized value of that $key, or null if it isn't * something. */ - protected function getVal( $key ) { + public function getVal( $key ) { if ( $this->isSomething( $key ) ) { return $this->normalized[$key]; } else { diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 84b980d..8d7ed15 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -241,7 +241,7 @@ $this->setValidationErrors( $this->getOriginalValidationErrors() ); - $this->unstaged_data = $this->dataObj->getDataEscaped(); + $this->unstaged_data = $this->dataObj->getData(); $this->staged_data = $this->unstaged_data; // checking to see if we have an edit token in the request... @@ -924,7 +924,7 @@ $this->regenerateOrderID(); // Pull anything changed from dataObj - $this->unstaged_data = $this->dataObj->getDataEscaped(); + $this->unstaged_data = $this->dataObj->getData();
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Put the ctor sequence back as it was, fix fatals.
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341848 ) Change subject: [WIP] Put the ctor sequence back as it was, fix fatals. .. [WIP] Put the ctor sequence back as it was, fix fatals. Change-Id: I820e7c847619928a70e63ddb1102ee663a8120ce --- M gateway_common/gateway.adapter.php M globalcollect_gateway/orphan.adapter.php M tests/phpunit/DonationDataTest.php M tests/phpunit/GatewayValidationTest.php 4 files changed, 45 insertions(+), 61 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/48/341848/1 diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 65619bc..fc2dc29 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -245,6 +245,18 @@ $this->defineDataTransformers(); + $this->session_resetOnSwitch(); // Need to do this before creating DonationData + + // FIXME: this should not have side effects like setting order_id_meta['final'] + // TODO: On second thought, neither set data nor validate in this constructor. + $this->dataObj = new DonationData( $this, $options['external_data'] ); + + $this->unstaged_data = $this->dataObj->getData(); + $this->staged_data = $this->unstaged_data; + + // checking to see if we have an edit token in the request... + $this->posted = ( $this->dataObj->wasPosted() && ( !is_null( WmfFramework::getRequestValue( 'wmf_token', null ) ) ) ); + $this->findAccount(); $this->defineAccountInfo(); $this->defineTransactions(); @@ -254,23 +266,9 @@ $this->setGatewayDefaults( $options ); - $this->session_resetOnSwitch(); // Need to do this before creating DonationData - - // FIXME: this should not have side effects like setting order_id_meta['final'] - // TODO: On second thought, neither set data nor validate in this constructor. - $this->dataObj = new DonationData( $this, $options['external_data'] ); - // FIXME: Same as above, don't validate or stage in the constructor. - // Sets $this->errors if validation fails. $this->validate(); - $this->unstaged_data = $this->dataObj->getData(); - $this->staged_data = $this->unstaged_data; - - // checking to see if we have an edit token in the request... - $this->posted = ( $this->dataObj->wasPosted() && ( !is_null( WmfFramework::getRequestValue( 'wmf_token', null ) ) ) ); - - // FIXME: Don't stage if invalid. $this->stageData(); BannerHistoryLogIdProcessor::onGatewayReady( $this ); @@ -1232,7 +1230,7 @@ */ public function getPaymentMethod() { // FIXME: this should return the final calculated method - return $this->dataObj->getVal( 'payment_method' ); + return $this->getData_Unstaged_Escaped( 'payment_method' ); } /** @@ -1247,7 +1245,7 @@ } public function getPaymentSubmethod() { - return $this->dataObj->getVal( 'payment_submethod' ); + return $this->getData_Unstaged_Escaped( 'payment_submethod' ); } public function getPaymentSubmethods() { @@ -2379,7 +2377,7 @@ // Add any country-specific required fields if ( isset( $this->config['country_fields'] ) ) { - $country = $this->dataObj->getVal( 'country' ); + $country = $this->getData_Unstaged_Escaped( 'country' ); if ( $country && isset( $this->config['country_fields'][$country] ) ) { $validation = $this->config['country_fields'][$country]; } @@ -2417,7 +2415,7 @@ //however, that's not happening in this class in the code I'm replacing, so... //TODO: Something clever in the DataValidator with data groups like these. ); - $country = $this->dataObj->getVal( 'country' ); + $country = $this->getData_Unstaged_Escaped( 'country' ); if ( $country && Subdivisions::getByCountry( $country ) ) { $check_not_empty[] = 'state'; } diff --git a/globalcollect_gateway/orphan.adapter.php b/globalcollect_gateway/orphan.adapter.php index c1edf13..aaf48c2 100644 --- a/globalcollect_gateway/orphan.adapter.php +++
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Do not pass go. This has gone too far, constructor or...
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341748 ) Change subject: [WIP] Do not pass go. This has gone too far, constructor order is fragile. .. [WIP] Do not pass go. This has gone too far, constructor order is fragile. Change-Id: I7bf79b71f3c7410c61ccd24889996315e1097815 --- M gateway_common/gateway.adapter.php M tests/phpunit/GatewayPageTest.php 2 files changed, 24 insertions(+), 20 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/48/341748/1 diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 69b0f05..65619bc 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -245,18 +245,6 @@ $this->defineDataTransformers(); - $this->session_resetOnSwitch(); // Need to do this before creating DonationData - - // FIXME: this should not have side effects like setting order_id_meta['final'] - // TODO: On second thought, neither set data nor validate in this constructor. - $this->dataObj = new DonationData( $this, $options['external_data'] ); - - $this->unstaged_data = $this->dataObj->getData(); - $this->staged_data = $this->unstaged_data; - - // checking to see if we have an edit token in the request... - $this->posted = ( $this->dataObj->wasPosted() && ( !is_null( WmfFramework::getRequestValue( 'wmf_token', null ) ) ) ); - $this->findAccount(); $this->defineAccountInfo(); $this->defineTransactions(); @@ -266,9 +254,23 @@ $this->setGatewayDefaults( $options ); - // FIXME: Same as above, don't validate or stage in the constructor. - $this->errors = $this->validate(); + $this->session_resetOnSwitch(); // Need to do this before creating DonationData + // FIXME: this should not have side effects like setting order_id_meta['final'] + // TODO: On second thought, neither set data nor validate in this constructor. + $this->dataObj = new DonationData( $this, $options['external_data'] ); + + // FIXME: Same as above, don't validate or stage in the constructor. + // Sets $this->errors if validation fails. + $this->validate(); + + $this->unstaged_data = $this->dataObj->getData(); + $this->staged_data = $this->unstaged_data; + + // checking to see if we have an edit token in the request... + $this->posted = ( $this->dataObj->wasPosted() && ( !is_null( WmfFramework::getRequestValue( 'wmf_token', null ) ) ) ); + + // FIXME: Don't stage if invalid. $this->stageData(); BannerHistoryLogIdProcessor::onGatewayReady( $this ); @@ -532,6 +534,8 @@ return $staged_data; } + // FIXME: Rename and drop "escaped" at the least. Better yet, only use + // normalized data. See T134548. public function getData_Unstaged_Escaped( $val = '' ) { if ( $val === '' ) { return $this->unstaged_data; @@ -1228,7 +1232,7 @@ */ public function getPaymentMethod() { // FIXME: this should return the final calculated method - return $this->getData_Unstaged_Escaped( 'payment_method' ); + return $this->dataObj->getVal( 'payment_method' ); } /** @@ -1243,7 +1247,7 @@ } public function getPaymentSubmethod() { - return $this->getData_Unstaged_Escaped( 'payment_submethod' ); + return $this->dataObj->getVal( 'payment_submethod' ); } public function getPaymentSubmethods() { @@ -2375,7 +2379,7 @@ // Add any country-specific required fields if ( isset( $this->config['country_fields'] ) ) { - $country = $this->getData_Unstaged_Escaped( 'country' ); + $country = $this->dataObj->getVal( 'country' ); if ( $country && isset( $this->config['country_fields'][$country] ) ) { $validation = $this->config['country_fields'][$country]; } @@ -2413,7 +2417,7 @@ //however, that's not happening in this class in the code I'm replacing, so... //TODO: Something clever in the DataValidator with data groups like these. ); - $country = $this->getData_Unstaged_Escaped( 'country' ); + $country = $this->dataObj->getVal(
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] snippet for grading
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341726 ) Change subject: [WIP] snippet for grading .. [WIP] snippet for grading Change-Id: Id6fbe69fa1ce2f0575a2deb2c4bbcdf8ab0d6898 --- M gateway_common/gateway.adapter.php 1 file changed, 13 insertions(+), 2 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/26/341726/1 diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 84b980d..fe1cc9a 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -152,8 +152,19 @@ * constants defined in @see FinalStatus */ protected $final_status; - protected $validation_errors; - protected $manual_errors = array(); + /** +* @var array Map of errors preventing this transaction from continuing. +* Structure is like: +* [ +* # An i18n key name to an error message that will display atop of +* # the screen, indicating that something general needs fixing. +* 'general' => 'warning-currency-fallback', +* # Example of a very specific error string that only the gateway +* # could calculate. +* 'address' => 'key saying: "Address is required for E-Commerce transactions."', +* ] +*/ + protected $errors = array(); /** * Name of the current transaction. Set via @see setCurrentTransaction -- To view, visit https://gerrit.wikimedia.org/r/341726 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id6fbe69fa1ce2f0575a2deb2c4bbcdf8ab0d6898 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Deprecate "manual" errors
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341727 ) Change subject: [WIP] Deprecate "manual" errors .. [WIP] Deprecate "manual" errors The original intent may have been a firewall between the validation errors which can only be set by the adapter, and errors which can be set by other classes. I'm simplifying down to a single list of errors. If any errors are present, you will not advance to the next step in your donation. Change-Id: I279052521a20e28d0935ce100c31087a2519e365 --- M amazon_gateway/amazon.api.php M gateway_common/DonationData.php M gateway_common/GatewayPage.php M gateway_common/donation.api.php M gateway_common/gateway.adapter.php M gateway_forms/Mustache.php M globalcollect_gateway/orphan.adapter.php M tests/phpunit/Adapter/AstroPay/AstroPayTest.php M tests/phpunit/GatewayPageTest.php M tests/phpunit/GatewayValidationTest.php M tests/phpunit/includes/test_gateway/TestingGenericAdapter.php 11 files changed, 82 insertions(+), 97 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/27/341727/1 diff --git a/amazon_gateway/amazon.api.php b/amazon_gateway/amazon.api.php index 07ad771..c82a956 100644 --- a/amazon_gateway/amazon.api.php +++ b/amazon_gateway/amazon.api.php @@ -25,11 +25,11 @@ $adapter = new AmazonAdapter( $adapterParams ); - if ( $adapter->getAllErrors() ) { + if ( $adapter->getErrors() ) { $output->addValue( null, 'errors', - $adapter->getAllErrors() + $adapter->getErrors() ); } else if ( $token && $adapter->checkTokens() ) { if ( $recurring ) { diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php index 07c6d43..4983ab1 100644 --- a/gateway_common/DonationData.php +++ b/gateway_common/DonationData.php @@ -1088,7 +1088,7 @@ $this->getVal( 'language' ), array( $this->gateway->getGlobal( 'FallbackCurrency' ) ) ); - $this->gateway->addManualError( $error ); + $this->gateway->mergeError( $error ); } } } diff --git a/gateway_common/GatewayPage.php b/gateway_common/GatewayPage.php index 8d32960..f4ce1c7 100644 --- a/gateway_common/GatewayPage.php +++ b/gateway_common/GatewayPage.php @@ -163,14 +163,13 @@ * a piece of mostly UI, this function needs to be moved inside the gateway * adapter class. * -* @return boolean Returns false on an error-free validation, otherwise true. -* FIXME: that return value seems backwards to me. +* @return boolean Returns true on an error-free validation, otherwise false. */ public function validateForm() { - $validated_ok = $this->adapter->revalidate(); + $validated_ok = $this->adapter->validate(); - return !$validated_ok; + return $validated_ok; } /** @@ -348,14 +347,16 @@ if ( $this->isProcessImmediate() ) { // Check form for errors // FIXME: Should this be rolled into adapter.doPayment? - $form_errors = $this->validateForm() || $this->adapter->getManualErrors(); + $validated_ok = $this->validateForm(); - // If there were errors, redisplay form, otherwise proceed to next step - if ( $form_errors ) { - $this->displayForm(); - } else { - // Attempt to process the payment, and render the response. + // Proceed to the next step, unless there were errors. + if ( $validated_ok ) { + // Attempt to process the payment, then render the response. $this->processPayment(); + } else { + // Redisplay form to give the donor notification and a + // chance correct their errors. + $this->displayForm(); } } else { $this->adapter->session_addDonorData(); @@ -363,7 +364,7 @@ } } else { //token mismatch $error['general']['token-mismatch'] = $this->msg( 'donate_interface-token-mismatch'
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: Remove deprecated function
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341721 ) Change subject: Remove deprecated function .. Remove deprecated function Change-Id: I2a36b910b7181fc4db101bfd90cdbb41cf372181 --- M gateway_common/DonationData.php 1 file changed, 0 insertions(+), 16 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/21/341721/1 diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php index 96a2650..07c6d43 100644 --- a/gateway_common/DonationData.php +++ b/gateway_common/DonationData.php @@ -1015,22 +1015,6 @@ return $this->validationErrors; } - /** -* validatedOK -* Checks to see if the data validated ok (no errors). -* @return boolean True if no errors, false if errors exist. -*/ - public function validatedOK() { - if ( is_null( $this->validationErrors ) ) { - $this->getValidationErrors(); - } - - if ( count( $this->validationErrors ) === 0 ) { - return true; - } - return false; - } - private function expungeNulls() { foreach ( $this->normalized as $key => $val ) { if ( is_null( $val ) ) { -- To view, visit https://gerrit.wikimedia.org/r/341721 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2a36b910b7181fc4db101bfd90cdbb41cf372181 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Remove irrelevant test?
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341722 ) Change subject: [WIP] Remove irrelevant test? .. [WIP] Remove irrelevant test? However, this test is failing on I4f1ebc984419a62401b820d7778ce4e46c90733a so I'm concerned that nothing else is covering the same conditions. Change-Id: I9d948b2ed063bd142fa9423a94fe0d7afe04 --- M tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php 1 file changed, 0 insertions(+), 28 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/22/341722/1 diff --git a/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php b/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php index 6682a87..27c7c4e 100644 --- a/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php +++ b/tests/phpunit/Adapter/GlobalCollect/GlobalCollectOrphanAdapterTest.php @@ -114,34 +114,6 @@ $this->verifyNoLogErrors(); } - public function testGCFormLoad() { - $init = $this->getDonorTestData( 'US' ); - unset( $init['order_id'] ); - $init['payment_method'] = 'cc'; - $init['payment_submethod'] = 'visa'; - $init['ffname'] = 'cc-vmad'; - - $assertNodes = array ( - 'submethod-mc' => array ( - 'nodename' => 'input' - ), - 'selected-amount' => array ( - 'nodename' => 'span', - 'innerhtmlmatches' => '/^\s*' . - str_replace( '$', '\$', - Amount::format( 1.55, 'USD', $init['language'] . '_' . $init['country'] ) - ). - '\s*$/', - ), - 'state' => array ( - 'nodename' => 'select', - 'selected' => 'CA', - ), - ); - - $this->verifyFormOutput( 'GlobalCollectGateway', $init, $assertNodes, true ); - } - /** * Tests to make sure that certain error codes returned from GC will * trigger order cancellation, even if retryable errors also exist. -- To view, visit https://gerrit.wikimedia.org/r/341722 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9d948b2ed063bd142fa9423a94fe0d7afe04 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...DonationInterface[master]: [WIP] Form did not validate if manual errors are present
Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341592 ) Change subject: [WIP] Form did not validate if manual errors are present .. [WIP] Form did not validate if manual errors are present TODO: I'd like to understand when and why this changed, and whether we ever do care only about validation errors. Bug: T98447 Change-Id: I22d7ee350820db8a1fb37124a0690b0b3d397784 --- M gateway_common/GatewayPage.php 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/92/341592/1 diff --git a/gateway_common/GatewayPage.php b/gateway_common/GatewayPage.php index 491add7..8d32960 100644 --- a/gateway_common/GatewayPage.php +++ b/gateway_common/GatewayPage.php @@ -348,7 +348,7 @@ if ( $this->isProcessImmediate() ) { // Check form for errors // FIXME: Should this be rolled into adapter.doPayment? - $form_errors = $this->validateForm(); + $form_errors = $this->validateForm() || $this->adapter->getManualErrors(); // If there were errors, redisplay form, otherwise proceed to next step if ( $form_errors ) { -- To view, visit https://gerrit.wikimedia.org/r/341592 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I22d7ee350820db8a1fb37124a0690b0b3d397784 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits