diff --git a/README.md b/README.md index 9955592..4e24578 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,11 @@ intake } ``` -Each key under `action` defines an action that can be taken for the source. A minimal `intake.json` must contain a `fetch` action with an `exe`. All other configs are optional. +Each key under `action` defines an action that can be taken for the source. An action must contain `exe` and may contain `args`. A source must have a `fetch` action. -The `fetch` action is executed by `intake update`. All other actions are executable with `intake action`. `intake crontab` will create a crontab entry for each source with a `cron` config defined. The value of `cron` is the crontab spec according to which the source should be updated. +Each key under `env` defines an environment variable that will be set when actions are executed. + +If `cron` is present, it must define a crontab schedule. Intake will automatically create crontab entries to update each source according to its cron schedule. ## Interface for source programs @@ -66,7 +68,7 @@ The `fetch` action is used to fetch the current state of the feed source. It rec An item must have a key under `action` with that action's name to support executing that action for that item. The value under that key may be any JSON structure used to manage the item-specific state. -All encoding is done with UTF-8. If an item cannot be parsed or the exit code of the process is nonzero, Intake will consider the action to be a failure. No items or other feed changes will happen as a result of a failed action, except for changes to `state` done by the action process. +All input and output is treated as UTF-8. If an item cannot be parsed or the exit code of the process is nonzero, Intake will consider the action to be a failure. No items or other feed changes will happen as a result of a failed action, except for changes to `state` done by the action process. ## Top-level item fields diff --git a/demo/default.nix b/demo/default.nix index c09dcd9..4539b20 100644 --- a/demo/default.nix +++ b/demo/default.nix @@ -67,19 +67,21 @@ # Include some demo instructions environment.etc.issue.text = '' + ### # Welcome to the intake demo! Log in as `alice` with password `alpha` to begin. - + # # Exit the VM with ctrl+a x, or switch to the qemu console with ctrl+a c and `quit`. - + ### ''; users.motd = '' - + ### # To set a password for the web interface, run `intake passwd` and set a password. - + # # Within this demo VM, the main intake entry point can be found at localhost:8080. This is also exposed on the host machine at localhost:5234. After you set a password, navigate to localhost:5234 on your host machine and log in to see the web interface. - - # Try updating the currenttime source by running `intake update -s currenttime`. You should see a new item after refreshing the source's feed. - - # The `echo` source demonstrates the use of `env` source configuration. Try changing the message in the web interface or via `intake edit -s echo`, then updating the source. + # + # Try updating the `echo` source by running `intake update -s echo`. You should see a new item after refreshing the source's feed. This source uses `env` source configuration, so use `intake edit -s echo` or the web interface to change the message, then update the source again. + # + # Updating a source will also trigger intake to update the user crontab. If you run `crontab -l`, you should see that the `currenttime` source has a crontab entry. You can change this source's cron schedule in the source config. + ### ''; } diff --git a/intake/app.py b/intake/app.py index eabed54..1fe5069 100644 --- a/intake/app.py +++ b/intake/app.py @@ -19,6 +19,7 @@ from flask import ( ) from intake.core import intake_data_dir +from intake.crontab import update_crontab_entries from intake.source import LocalSource, execute_action, Item # Globals @@ -273,6 +274,7 @@ def source_edit(name): error_message, config = _parse_source_config(config_str) if not error_message: source.save_config(config) + update_crontab_entries(data_path) return redirect(url_for("root")) # For GET, load the config diff --git a/intake/cli.py b/intake/cli.py index 74f50bb..23bfa8e 100644 --- a/intake/cli.py +++ b/intake/cli.py @@ -82,6 +82,7 @@ def cmd_edit(cmd_args): return 0 tmp_path.replace(source.source_path / "intake.json") + update_crontab_entries(data_path) break return 0 @@ -297,24 +298,6 @@ def cmd_passwd(cmd_args): return 0 -def cmd_crontab(cmd_args): - """Update cron with configured source cron entries.""" - parser = argparse.ArgumentParser( - prog="intake crontab", - description=cmd_crontab.__doc__, - ) - parser.add_argument( - "--data", - "-d", - help="Path to the intake data directory containing source directories", - ) - args = parser.parse_args(cmd_args) - - data_path: Path = Path(args.data) if args.data else intake_data_dir() - update_crontab_entries(data_path) - return 0 - - def cmd_run(cmd_args): """Run the default Flask server.""" parser = argparse.ArgumentParser( diff --git a/module.nix b/module.nix index 2bdb2df..33757d4 100644 --- a/module.nix +++ b/module.nix @@ -112,6 +112,8 @@ in { systemd.services = let runScript = userName: pkgs.writeShellScript "intake-run.sh" '' + # Add the setuid wrapper directory so `crontab` is accessible + export PATH="${config.security.wrapperDir}:$PATH" ${pythonEnv}/bin/intake run -d /home/${userName}/.local/share/intake --port ${toString userPort.${userName}} ''; # systemd service definition for a single user, given `services.intake.users.userName` = `userCfg`