Skip to content

12. Shipping

Your module works on your machine. Here is how it gets elsewhere.

Packaging

Fenêtre de terminal
kewos module pack ./modules/library --out library-0.3.0.kws

A .kws is an archive, and you can open it to check what it holds. It also carries a digest manifest: every file is listed with its hash, which is how a package modified between export and install is detected.

Installing

Fenêtre de terminal
kewos module install library-0.3.0.kws --modules-root /opt/kewos/current/modules

Then align the schema and restart:

Fenêtre de terminal
kewos reconcile --confirm --modules-root /opt/kewos/current/modules
sudo systemctl restart kewos kewos-worker

And do not forget to switch the module on for the installation, or it stays invisible (see Making it visible).

The signature

By default, install refuses an unsigned package. A module arriving from a third party has to prove its origin: it runs inside the server’s process, with access to the database.

While developing, that requirement would be pointless friction, so the behaviour follows the environment:

Fenêtre de terminal
# On a developer machine: accepted without a signature.
KEWOS_ENV=development kewos module install library-0.3.0.kws
# On a server, you have to say so explicitly.
kewos module install library-0.3.0.kws --allow-unsigned
kewos module install library-0.3.0.kws --require-signed

To sign, you need a keypair and the target installation must trust your public key. Talk to Kewos if you distribute modules to your customers.

Migrations

From your module’s second version onwards, a schema change ships as a migration.

modules/library/migrations/versions/0001_add_lost_note.py

And migrations are non-destructive by default: you rename, you backfill, you add. Dropping a column, or a not-null constraint with no backfill, is asked for explicitly, because it can destroy a customer’s data.

A checklist before shipping

  • The manifest carries the right version and category.
  • icon.svg exists and uses currentColor.
  • Every language file has the same keys as the others.
  • No visible string is hard-coded, in Python or in JSON.
  • The module’s groups are prefixed with its name.
  • No hand-written state machine.
  • No float for an amount.
  • No import of another business module.
  • The tests pass, including one edge case and one error case per behaviour.
  • A non-administrator account has been tested, not only kws_admin.

Next

You have been round the walkthrough. Two companions are worth reading:

The finished module, to download

You do not have to retype any of it. The module from this walkthrough is packaged exactly as described here, with its screens, translations, permissions, PDF report, flow and tests:

  • library-0.3.0.kws (23 KB): the complete library module, steps 1 through 13, plus its business rules, its fee with its currency and its members map.

The checksum, to verify before installing anything:

03e62249c512b723c021a820131c8d4c7b83b7dc8b471217f0e2152d83fd6676 library-0.3.0.kws
Fenêtre de terminal
sha256sum library-0.3.0.kws

Installing it on your instance

Fenêtre de terminal
kewos module install library-0.3.0.kws \
--database-url "$KEWOS_DATABASE_URL" \
--modules-root "$KEWOS_MODULES_ROOT" \
--allow-unsigned
installed library 0.1.0 (UNSIGNED) into /opt/kewos/app/modules

--modules-root has to exist. Otherwise:

REFUSED: modules root /opt/kewos/modules does not exist (or is not a directory);
point --modules-root at the instance's modules folder

The folder is not created for you, deliberately: a typo would drop the module into a path the server never reads, and the install would report success.

Then the two gestures the package does not do for you:

Fenêtre de terminal
# 1. The schema: the module's tables do not exist yet.
kewos reconcile --confirm
# 2. Restart, so the process loads the module it now has on disk.
systemctl restart kewos

And activate it for the installation, under Settings → Modules. That is step 4 of the walkthrough, and the one people forget: a module whose API answers perfectly stays invisible until it is activated, with no error and nothing in the log.

Why it refuses at first

Fenêtre de terminal
kewos module install library-0.3.0.kws --database-url ... --modules-root ...
REFUSED: package is not signed; install it with an explicit allowance
(never in production) or publish a signed build

This package is unsigned, deliberately: signing it would mean having you install something carrying our guarantee on your instance, for a practice module. The --allow-unsigned you type is a consent, not a formality worked around — it is exactly what you will never type on a production machine.

A module you publish for real is signed at publishing time, with your delivery chain’s key, never from the machine that wrote it.

What next?

You can build a module. The other half of the job is extending one that already exists, without copying it: Extending an existing module.