diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..07af33a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,41 @@ +# myos, for agents working on this repository + +myos runs docker compose stacks. `skills/myos/SKILL.md` explains how to *use* +it; this file is about changing it. + +## Check your work + +```sh +make test # unit + golden, both engines, docker is mocked +make lint # shellcheck +``` + +Golden tests compare the output of the CLI **and** of the legacy make engine +against recordings made at the tag `legacy-1.0-beta`. If a change moves an +output on purpose, record the CLI expectation in `spec/golden/expected.cli/` +and write down why in `spec/golden/DELTAS.md`. Never edit +`spec/golden/expected/` by hand: it is the behaviour of the old engine. + +## Layout + +See `skills/myos/references/authoring.md`. In short: `bin/myos` parses and +dispatches, `lib/*.sh` holds one concern each, `lib/cmd/.sh` holds one +command each, `share/compose/` holds the two overlays the framework itself +provides, and the stacks live in another repository, `myos-stacks`. + +## Shell constraints + +POSIX shell only: this runs on the bash 3.2 of macOS and on Alpine. No `local`, +no arrays, no `[[`. Two traps already paid for: + +- `[a-z]` in a `case` pattern also matches uppercase under a `fr_FR` collation; + use `[:lower:]`. +- a function called inside `$( )` cannot return anything through a global. + +## Do not + +- Reintroduce a `stack/` or `docker/` directory here: they belong to + `myos-stacks`. +- Make an unknown command or an unknown stack succeed silently. +- Change a default project name without an entry in `DELTAS.md` and a note in + the skill: it renames the containers and volumes of every deployment. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/bin/myos b/bin/myos index b4aacc6..431285d 100755 --- a/bin/myos +++ b/bin/myos @@ -196,7 +196,7 @@ if [ -f "$MYOS_ROOT/lib/cmd/$MYOS_CMD.sh" ]; then exit $? fi -# compose passthrough commands +# commands that map straight onto docker compose case $MYOS_CMD in up|down|start|stop|restart|ps|logs|config|build|pull|create|kill|top|images) ;; *) myos_error "unknown command: $MYOS_CMD"; usage >&2; exit "$MYOS_E_USAGE" ;; diff --git a/lib/cmd/exec.sh b/lib/cmd/exec.sh new file mode 100644 index 0000000..6de1cf6 --- /dev/null +++ b/lib/cmd/exec.sh @@ -0,0 +1,28 @@ +#shellcheck shell=sh +# myos exec [-- command...] run a command in a running service +# myos run [-- command...] run it in a new container +# +# The service defaults to the stack name, which is what it is called in most +# stacks; SERVICE= picks another one. +myos_cmd_exec() { myos_service_command exec; } +myos_cmd_run() { myos_service_command run; } + +myos_service_command() { + _what=$1 + _ref=$(printf '%s' "$MYOS_STACKS" | head -1) + [ -n "$_ref" ] || myos_die "$MYOS_E_USAGE" "usage: myos $_what [SERVICE=name] -- command..." + _service=${SERVICE:-$(myos_stack_name "$_ref")} + _files=$(myos_stack_compose_files "$_ref") || return $? + _fw=$(myos_framework_compose_files) + [ -n "$_fw" ] && _files="$_files +$_fw" + _app=$(myos_stack_name "$_ref") + case $_ref in .|./*|/*|../*) _app=$(basename "$(myos_stack_resolve "$_ref")") ;; esac + _project=$(myos_project_name "$(myos_scope "$_ref")" "$USER" "$ENV" "$_app") + case $_what in + exec) _opts="" ;; + run) _opts=${DOCKER_COMPOSE_RUN_OPTIONS:---rm} ;; + esac + # shellcheck disable=SC2086 # options and arguments are deliberate word lists + myos_compose "$_project" "$_files" -- "$_what" $_opts "$_service" ${MYOS_ARGS:-} +} diff --git a/lib/cmd/run.sh b/lib/cmd/run.sh new file mode 100644 index 0000000..abc5fc9 --- /dev/null +++ b/lib/cmd/run.sh @@ -0,0 +1,4 @@ +#shellcheck shell=sh +# myos run: see lib/cmd/exec.sh +# shellcheck source=lib/cmd/exec.sh +. "$MYOS_ROOT/lib/cmd/exec.sh" diff --git a/lib/cmd/scale.sh b/lib/cmd/scale.sh new file mode 100644 index 0000000..d1419c5 --- /dev/null +++ b/lib/cmd/scale.sh @@ -0,0 +1,13 @@ +#shellcheck shell=sh +# shellcheck source=lib/cmd/_compose.sh +# myos scale SERVICE= NUM= run n containers of a service +. "$MYOS_ROOT/lib/cmd/_compose.sh" + +myos_cmd_scale() { + _ref=$(printf '%s' "$MYOS_STACKS" | head -1) + [ -n "$_ref" ] || myos_die "$MYOS_E_USAGE" "usage: myos scale SERVICE=name NUM=n" + _service=${SERVICE:-$(myos_stack_name "$_ref")} + [ -n "${NUM:-}" ] || myos_die "$MYOS_E_USAGE" "myos scale needs NUM=" + MYOS_ARGS="--scale $_service=$NUM ${MYOS_ARGS:-}" + myos_cmd_compose up +} diff --git a/skills/myos/SKILL.md b/skills/myos/SKILL.md new file mode 100644 index 0000000..c756727 --- /dev/null +++ b/skills/myos/SKILL.md @@ -0,0 +1,91 @@ +--- +name: myos +description: Deploy, inspect and troubleshoot docker compose stacks on a server or a fleet with the myos CLI (Make Your Own Stack). Use when asked to install myos, to start/stop/debug a stack (a host singleton, an application, a user stack), to add a stack to the catalogue, or to work on the myos framework itself. +--- + +# myos + +myos runs docker compose stacks. It decides which compose files to load, under +which project name, with which variables. Everything else is docker. + +## Is this the right tool + +Use it when the repository or the host has one of: +- a `stack/` directory holding compose files, +- a `Makefile` that includes `make/include.mk`, +- `/etc/conf.d/myos` or `/etc/default/myos`, +- the `myos` command on PATH. + +Otherwise call `docker compose` directly. + +## Look before you touch + +```sh +myos doctor # requirements, config layers, stack path +myos ls # stacks reachable from here +myos ls --groups # groups and what they expand to +myos env # resolved variables +myos -n up host # print what `up` would run, without running it +``` + +**Always run `myos -n` before `up`, `down` or `restart` on a `host/` stack.** +Host stacks bind privileged ports and are shared by everything on the machine: +taking `host/fabio` down drops every site the machine serves. + +## Working loop + +```sh +myos ls # find the stack +myos -n config # check the file list and the project name +myos up # create and start +myos ps # what is running +myos logs # follow the logs +myos exec -- sh # a shell in the service named after the stack +myos down # remove the containers +``` + +## Naming a stack + +A reference is `[/][:]`, or a path. + +```sh +myos up # the current directory, when it holds a compose file +myos up host # a group: expands to host/consul host/fabio ... +myos up host/fabio # one stack +myos up postgres:9.6 # the 9.6 overlay of the postgres stack +myos -C /opt/app up # somewhere else +myos -e master up # in another environment +``` + +Stacks are looked up along the stack path, project first: +`./stack`, `../stack`, `~/.local/share/myos/stack`, `/usr/local/share/myos/stack`, +`/usr/share/myos/stack`. `myos doctor` prints the resolved path. + +## Three kinds of stack + +| kind | reference | compose project | meaning | +|---|---|---|---| +| host | `host/*` | the hostname | one per machine: binds 80/443, consul, certbot. Shared. Treat as production. | +| user | `User/*` | the user identity | one per user: ssh-agent, personal services | +| app | anything else | `--` | many per machine, one per user and environment | + +Set `MYOS_PROJECT_FORMAT=user-app-env` on a deployment created before the +rename, otherwise its containers and volumes look like a different project. +See `references/conventions.md`. + +## Rules + +- Never run `myos clean` on a host stack: it removes images **and volumes**, + including the certificates. +- Secrets belong in a file outside the repository, never in a compose file. +- A stack of the catalogue is shared: change it in `myos-stacks`, not in place + on a server. +- Before upgrading myos on a machine that already runs stacks, pin the naming + (`references/conventions.md`), or every project gets a new name. + +## More + +- `references/commands.md` — every command, and its equivalent in the old make targets +- `references/conventions.md` — file layout, naming, networks, variables, tags +- `references/troubleshooting.md` — what each failure means and how to fix it +- `references/authoring.md` — writing a stack, and working on myos itself diff --git a/skills/myos/references/authoring.md b/skills/myos/references/authoring.md new file mode 100644 index 0000000..ffe04a2 --- /dev/null +++ b/skills/myos/references/authoring.md @@ -0,0 +1,74 @@ +# Writing a stack, and working on myos + +## A new stack in the catalogue + +``` +stack//.yml the services +stack//.local.yml what only makes sense on a workstation (published ports…) +stack//.labels.yml the registrator labels, so routing stays optional +stack//.env.dist the variables it expects, with defaults +stack//README.md what it is and what it needs +``` + +Rules that keep a stack reusable: +- no `container_name`, except in a `host/` stack: it prevents scaling and + collides between users, +- no fixed host port outside `host/`; publish through the load balancer, +- reference variables with a default: `${POSTGRES_VERSION:-16}`, +- attach to `private` to be reachable by the other stacks of the user, to + `public` to be routed, +- name volumes, never bind-mount an absolute path. + +Check it before committing: + +```sh +myos -n config # the file list and the project +myos config # the rendered yaml +``` + +## A group + +```sh +# stack/.env +mygroup= other/ +``` + +Lowercase, and it may name other groups. + +## Working on myos itself + +```sh +make test # unit + golden, against both engines, with a mocked docker +make test-golden # golden only +make golden-record # re-record the golden expectations from the make engine +make lint # shellcheck +``` + +Layout: + +``` +bin/myos argument parsing, configuration, dispatch +lib/core.sh logging, exit codes, dry run +lib/str.sh strings and version comparison +lib/naming.sh project names, networks, user identity +lib/stack.sh stack path, references, overlays, groups +lib/config.sh dotenv, variables of the compose files +lib/compose.sh finding and calling docker compose +lib/tags.sh fabio tags +lib/cmd/.sh one file per command +share/compose/ the networks and volumes overlays myos provides +spec/ shellspec +``` + +Adding a command: write `lib/cmd/.sh` defining `myos_cmd_`, add it +to the usage text in `bin/myos`, and cover it in `spec/unit`. + +Constraints: +- POSIX shell, no bashisms: it has to run under the bash 3.2 of macOS and the + ash of Alpine. `make test` runs on both. +- No `a-z` ranges in a `case` pattern: under a dictionary collation such as + `fr_FR` they also match uppercase. Use `[:lower:]`. +- A function that has to return several values takes them out through printf, + not through a global: a caller inside `$( )` would lose the global. +- Changing what a command prints means updating `spec/golden/expected*/` and + explaining the change in `spec/golden/DELTAS.md`. diff --git a/skills/myos/references/commands.md b/skills/myos/references/commands.md new file mode 100644 index 0000000..58657ca --- /dev/null +++ b/skills/myos/references/commands.md @@ -0,0 +1,74 @@ +# Commands + +``` +myos [options] [stack...] [VAR=value...] [-- args...] +``` + +| option | effect | +|---|---| +| `-C DIR` | work in DIR instead of the current directory | +| `-e ENV` | environment: picks `.env.` and the `..yml` overlays | +| `-n`, `--dry-run` | print the commands instead of running them | +| `-v`, `--verbose` | say what myos is doing | +| `-d`, `--debug` | print every command | + +| command | effect | +|---|---| +| `up` | create and start; creates the external networks first | +| `down` | remove the containers | +| `start` / `stop` / `restart` | on the existing containers | +| `ps` | what is running | +| `logs` | follow the logs | +| `config` | the resolved compose file | +| `exec` | run a command in a running service | +| `run` | run it in a new container, removed afterwards | +| `scale` | `myos scale SERVICE= NUM=` | +| `build` / `pull` | images | +| `ls [--groups]` | the stacks and groups myos can see | +| `env [VAR...]` | resolved variables | +| `doctor` | check the installation | +| `version` | the myos version | + +Anything after `--` goes to docker compose: + +```sh +myos logs host/fabio -- --tail 20 +myos up postgres -- --force-recreate +``` + +`exec` and `run` take the service from the stack name, since most stacks name +their main service after themselves. `SERVICE=` picks another one: + +```sh +myos exec host/consul -- consul members # service consul, command "consul members" +myos exec host/fabio SERVICE=fabio -- sh +myos run postgres -- psql -l +``` + +## Exit codes + +| code | meaning | +|---|---| +| 0 | fine | +| 1 | the command failed | +| 2 | bad invocation, or an unknown command | +| 3 | stack not found (the message prints the search path) | +| 4 | missing requirement, run `myos doctor` | + +The make engine exited 0 on an unknown target, printing only a warning. The CLI +does not: a typo is an error. + +## Coming from the make targets + +| make | myos | +|---|---| +| `make up STACK=host` | `myos up host` | +| `make print-COMPOSE_FILE` | `myos env COMPOSE_FILE` | +| `make host` | `myos up host` | +| `make stack-host-config` | `myos config host` | +| `make up@master` | `myos -e master up` | +| `make exec SERVICE=php ARGS='ls'` | `myos exec -- php ls` | +| `make DRYRUN=true up` | `myos -n up` | + +`print-VAR`, `stack--` and `@` still work. +A project `Makefile` that includes `make/include.mk` keeps working too. diff --git a/skills/myos/references/conventions.md b/skills/myos/references/conventions.md new file mode 100644 index 0000000..8a89e57 --- /dev/null +++ b/skills/myos/references/conventions.md @@ -0,0 +1,113 @@ +# Conventions + +## A stack is a directory of compose files + +For stack `` in environment ``, myos loads whichever of these exist, +in this order. A later file overrides the ones before it. + +``` +.yml the stack +..yml this environment only +/.yml same, when the stack keeps a directory per environment +..yml an optional overlay, see below +...yml +..yml when the reference is : +``` + +`docker-compose.yml` is read under the same rules, so a stack can keep an +upstream `docker-compose.yml` untouched and add its own `.yml` on top. + +Then myos appends its own `share/compose/networks.yml`, and the +`volumes...yml` of the enabled suffixes. + +## Overlay suffixes + +Every `COMPOSE_FILE_` variable that is not `false` enables the suffix ``. + +| variable | default | loads | +|---|---|---| +| `COMPOSE_FILE_APP` | true | `.app.yml` | +| `COMPOSE_FILE_LABELS` | true | `.labels.yml`, the registrator labels | +| `COMPOSE_FILE_NETWORKS` | true | `.networks.yml` | +| `COMPOSE_FILE_SSH` | true | `.ssh.yml` | +| `COMPOSE_FILE_VOLUMES` | true | `.volumes.yml` | +| `COMPOSE_FILE_WWW`, `_DNS`, `_HOME`, `_LOG`, `_BACKUP` | false | the matching overlay, and the framework bind mount | + +A value that is neither `true` nor `false` also enables `.`: +`COMPOSE_FILE_WWW=nginx` loads `.www.yml` **and** `.www.nginx.yml`. + +## Project names + +| scope | project | why | +|---|---|---| +| `host/*` | `$HOSTNAME` | a singleton of the machine: one consul, one fabio on 80/443 | +| `User/*` | the user identity derived from the mail address | one per user | +| `cluster/*` | the stack name | one namespace per swarm | +| anything else | `--` | one per user, environment and app | + +`MYOS_PROJECT_FORMAT=user-app-env` restores the older order. **Any deployment +created before the rename must set it**, in its `.env` or in +`/etc/conf.d/myos`; otherwise the containers and volumes of the old project +are orphaned and the stack comes back up empty. + +## Networks + +| network | name | scope | +|---|---|---| +| `default` | `_` | the project. The leading underscore keeps it first alphabetically, so it is the first interface attached and service names never resolve across stacks. | +| `private` | `-` | external, shared between the stacks of one user and environment | +| `public` | `` | external, where the load balancer reaches the services | + +`myos up` creates the external ones when they are missing. + +## Routing: registrator, consul, fabio + +A service is published by labels, which registrator copies into consul, and on +which fabio routes: + +```yaml +labels: + - SERVICE_8000_NAME=${COMPOSE_SERVICE_NAME}-kong-8000 + - SERVICE_8000_TAGS=${SUPABASE_KONG_SERVICE_8000_TAGS:-urlprefix-supabase.localhost/*} + - SERVICE_8000_CHECK_TCP=true + - SERVICE_8001_IGNORE=true +``` + +Registrator only sees ports that are `expose`d, and consul only routes a +service whose check passes. + +Tag variables follow `_SERVICE__`, with `PATH`, `OPTS`, +`URIS`, `NAME`, and the fabio options `allow`, `auth`, `deny`, `prepend`, +`proto`, `register`, `strip`: + +```sh +HOST_NGINX_SERVICE_443_PROTO='https tlsskipverify=true' +DUNITER_V2S_SERVICE_9944_STRIP=/ws +``` + +## Configuration + +Layers, the last one wins: + +``` +defaults < /etc/conf.d/myos, /etc/default/myos < ~/.config/myos/config + < /.env < /.env. < environment < VAR=value on the command line +``` + +All of them are dotenv: `KEY=value`, `#` comments, optional quotes. They are +parsed, never sourced, so a value may contain a `#` or a `$(...)` without +breaking anything or being executed. The make engine included `.env` as a +makefile, where both broke. + +## Groups + +A group is a lowercase name whose value lists stacks. It can live in a `.env`, +in the environment, in `/.env`, or in a legacy `.mk`: + +```sh +host=host/consul host/fabio host/registrator +testing=drone/drone drone/gc +``` + +Groups expand recursively. Only lowercase names are considered, so an +environment variable can never be mistaken for a group. diff --git a/skills/myos/references/troubleshooting.md b/skills/myos/references/troubleshooting.md new file mode 100644 index 0000000..1571db1 --- /dev/null +++ b/skills/myos/references/troubleshooting.md @@ -0,0 +1,64 @@ +# Troubleshooting + +Start with `myos doctor`, then `myos -n ` to see what would run. + +## `stack not found: ` (exit 3) + +The reference is not on the stack path, which the message prints. +- `myos ls` shows what is reachable. +- The catalogue may not be installed: `git clone /usr/local/share/myos`. +- A stack of the project is only found from the project: use `myos -C /path/to/project`. + +## `docker compose >= 2.24.4 not found` (exit 4) + +Install the compose plugin, or a `docker-compose` binary of that version. +myos no longer falls back to a compose image. + +## `unknown command: ` (exit 2) + +Check the spelling against `myos help`. The make engine accepted any target +and exited 0 after printing a warning, so typos used to look like successes. + +## The containers came back under a different name + +The default project name changed from `--` to +`--`. The old containers and volumes are still there, under the +old project. Put `MYOS_PROJECT_FORMAT=user-app-env` in the `.env` of the +deployment (or in `/etc/conf.d/myos`) and bring it up again. + +Check first: `myos env COMPOSE_PROJECT_NAME` against `docker ps --format '{{.Names}}'`. + +## `network declared as external, but could not be found` + +The `private` or `public` network is missing. `myos up` creates them; a bare +`docker compose up` does not. Or create it by hand: +`docker network create -`. + +## A service is up but not routed + +In order: the port must be `expose`d (registrator ignores what it cannot see), +the labels must be on the service, the consul check must pass, and only then +does fabio route the `urlprefix-` tag. + +```sh +myos config | grep -A5 labels # what the labels resolve to +myos exec host/consul -- consul catalog services +myos logs host/registrator +``` + +## A variable is empty in the container + +myos only passes the variables the compose files actually mention. Check with +`myos env` and `myos config `. A variable set in a `.env` of another +directory is not read: only the workdir's `.env` is. + +## On macOS with Colima + +The daemon lives in a VM: a bind mount only works for a path the VM shares, and +`host.docker.internal` is the way back to the host. `myos doctor` prints the +`DOCKER_HOST` in use. + +## Something changed after upgrading myos + +`spec/golden/DELTAS.md` in the myos repository lists every intentional +difference between the make engine and the CLI, with the reason. diff --git a/spec/golden/cases.txt b/spec/golden/cases.txt index 67ca9c5..daba4bc 100644 --- a/spec/golden/cases.txt +++ b/spec/golden/cases.txt @@ -70,3 +70,10 @@ inc-app-print-env-vars | app-git | @make print-ENV_VARS inc-app-print-network-default | app-git | @make print-DOCKER_NETWORK_DEFAULT inc-app-stack-postgres-up | app-git | @make up STACK=postgres inc-app-unknown-target | app-git | @make doesnotexist +cmd-exec-host | host-project | exec host/consul -- consul members +cmd-exec-service | host-project | exec host/fabio SERVICE=fabio -- sh +cmd-run-catalogue | app-nogit | run postgres -- psql -l +cmd-scale | app-nogit | scale postgres SERVICE=postgres NUM=3 +cmd-ls | host-project | ls +cmd-ls-groups | host-project | ls --groups +cmd-env-domain | host-project | env DOMAIN diff --git a/spec/golden/expected.cli/app-run.txt b/spec/golden/expected.cli/app-run.txt index 5995550..8f36a55 100644 --- a/spec/golden/expected.cli/app-run.txt +++ b/spec/golden/expected.cli/app-run.txt @@ -1,26 +1,2 @@ -ERROR: unknown command: run -Usage: myos [options] [stack...] [VAR=value...] [-- args...] - -Options: - -C DIR work in DIR instead of the current directory - -e ENV environment (default: local, or ENV from the config) - -H HOSTS run on remote hosts instead (comma separated, or "all") - -n, --dry-run print the commands instead of running them - -v, --verbose show what myos does - -d, --debug show every command - -h, --help this help - -Commands: - up down start stop restart recreate manage the containers of a stack - ps logs config exec run inspect and enter them - ls [--groups] list the stacks myos can see - env [VAR...] show resolved variables - doctor check the installation - version print the myos version - -Stacks: - myos up the stack of the current directory - myos up host a group, expanded from host=... in a .env or .mk - myos up host/fabio a single stack - myos up postgres:9.6 a versioned stack -[exit 2] +docker compose -f @WD@/docker-compose.yml -f @WD@/docker-compose.local.yml -f @WD@/docker/docker-compose.yml -f @MYOS@/share/compose/networks.yml -p tester-wd-local --project-directory @WD@ run --rm app +[exit 0] diff --git a/spec/golden/expected.cli/app-scale.txt b/spec/golden/expected.cli/app-scale.txt index 0b56706..377f463 100644 --- a/spec/golden/expected.cli/app-scale.txt +++ b/spec/golden/expected.cli/app-scale.txt @@ -1,26 +1,4 @@ -ERROR: unknown command: scale -Usage: myos [options] [stack...] [VAR=value...] [-- args...] - -Options: - -C DIR work in DIR instead of the current directory - -e ENV environment (default: local, or ENV from the config) - -H HOSTS run on remote hosts instead (comma separated, or "all") - -n, --dry-run print the commands instead of running them - -v, --verbose show what myos does - -d, --debug show every command - -h, --help this help - -Commands: - up down start stop restart recreate manage the containers of a stack - ps logs config exec run inspect and enter them - ls [--groups] list the stacks myos can see - env [VAR...] show resolved variables - doctor check the installation - version print the myos version - -Stacks: - myos up the stack of the current directory - myos up host a group, expanded from host=... in a .env or .mk - myos up host/fabio a single stack - myos up postgres:9.6 a versioned stack -[exit 2] +docker network create tester-local +docker network create testhost +docker compose -f @WD@/docker-compose.yml -f @WD@/docker-compose.local.yml -f @WD@/docker/docker-compose.yml -f @MYOS@/share/compose/networks.yml -p tester-wd-local --project-directory @WD@ up -d --scale app=2 +[exit 0] diff --git a/spec/golden/expected.cli/cmd-env-domain.txt b/spec/golden/expected.cli/cmd-env-domain.txt new file mode 100644 index 0000000..dbe4149 --- /dev/null +++ b/spec/golden/expected.cli/cmd-env-domain.txt @@ -0,0 +1,2 @@ +DOMAIN example.test +[exit 0] diff --git a/spec/golden/expected.cli/cmd-exec-host.txt b/spec/golden/expected.cli/cmd-exec-host.txt new file mode 100644 index 0000000..aef04d1 --- /dev/null +++ b/spec/golden/expected.cli/cmd-exec-host.txt @@ -0,0 +1,2 @@ +docker compose -f @WD@/stack/host/consul.yml -f @MYOS@/share/compose/networks.yml -p testhost --project-directory @WD@/stack/host exec consul consul members +[exit 0] diff --git a/spec/golden/expected.cli/cmd-exec-service.txt b/spec/golden/expected.cli/cmd-exec-service.txt new file mode 100644 index 0000000..2c33970 --- /dev/null +++ b/spec/golden/expected.cli/cmd-exec-service.txt @@ -0,0 +1,2 @@ +docker compose -f @WD@/stack/host/fabio.yml -f @MYOS@/share/compose/networks.yml -p testhost --project-directory @WD@/stack/host exec fabio sh +[exit 0] diff --git a/spec/golden/expected.cli/cmd-ls-groups.txt b/spec/golden/expected.cli/cmd-ls-groups.txt new file mode 100644 index 0000000..345961c --- /dev/null +++ b/spec/golden/expected.cli/cmd-ls-groups.txt @@ -0,0 +1,4 @@ +host host/consul host/fabio host/registrator +default postgres redis +testing drone/drone redis +[exit 0] diff --git a/spec/golden/expected.cli/cmd-ls.txt b/spec/golden/expected.cli/cmd-ls.txt new file mode 100644 index 0000000..439ff25 --- /dev/null +++ b/spec/golden/expected.cli/cmd-ls.txt @@ -0,0 +1,9 @@ +@WD@/stack + host 3 compose file(s) +@HOME@/.local/share/myos/stack + User 1 compose file(s) + drone 2 compose file(s) + host 3 compose file(s) + postgres 3 compose file(s) + redis 1 compose file(s) +[exit 0] diff --git a/spec/golden/expected.cli/cmd-run-catalogue.txt b/spec/golden/expected.cli/cmd-run-catalogue.txt new file mode 100644 index 0000000..ec001fe --- /dev/null +++ b/spec/golden/expected.cli/cmd-run-catalogue.txt @@ -0,0 +1,2 @@ +docker compose -f @HOME@/.local/share/myos/stack/postgres/postgres.yml -f @HOME@/.local/share/myos/stack/postgres/postgres.local.yml -f @MYOS@/share/compose/networks.yml -p tester-postgres-local --project-directory @HOME@/.local/share/myos/stack/postgres run --rm postgres psql -l +[exit 0] diff --git a/spec/golden/expected.cli/cmd-scale.txt b/spec/golden/expected.cli/cmd-scale.txt new file mode 100644 index 0000000..4031cfa --- /dev/null +++ b/spec/golden/expected.cli/cmd-scale.txt @@ -0,0 +1,4 @@ +docker network create tester-local +docker network create testhost +docker compose -f @HOME@/.local/share/myos/stack/postgres/postgres.yml -f @HOME@/.local/share/myos/stack/postgres/postgres.local.yml -f @MYOS@/share/compose/networks.yml -p tester-postgres-local --project-directory @HOME@/.local/share/myos/stack/postgres up -d --scale postgres=3 +[exit 0] diff --git a/spec/golden/expected.cli/host-exec.txt b/spec/golden/expected.cli/host-exec.txt index a4d10a9..31478e2 100644 --- a/spec/golden/expected.cli/host-exec.txt +++ b/spec/golden/expected.cli/host-exec.txt @@ -1,26 +1,2 @@ -ERROR: unknown command: exec -Usage: myos [options] [stack...] [VAR=value...] [-- args...] - -Options: - -C DIR work in DIR instead of the current directory - -e ENV environment (default: local, or ENV from the config) - -H HOSTS run on remote hosts instead (comma separated, or "all") - -n, --dry-run print the commands instead of running them - -v, --verbose show what myos does - -d, --debug show every command - -h, --help this help - -Commands: - up down start stop restart recreate manage the containers of a stack - ps logs config exec run inspect and enter them - ls [--groups] list the stacks myos can see - env [VAR...] show resolved variables - doctor check the installation - version print the myos version - -Stacks: - myos up the stack of the current directory - myos up host a group, expanded from host=... in a .env or .mk - myos up host/fabio a single stack - myos up postgres:9.6 a versioned stack -[exit 2] +docker compose -f @WD@/stack/host/consul.yml -f @MYOS@/share/compose/networks.yml -p testhost --project-directory @WD@/stack/host exec consul +[exit 0] diff --git a/spec/golden/expected/cmd-env-domain.txt b/spec/golden/expected/cmd-env-domain.txt new file mode 100644 index 0000000..6fbc4f8 --- /dev/null +++ b/spec/golden/expected/cmd-env-domain.txt @@ -0,0 +1,3 @@ +WARNING: myos[0] env-rule-exists: target env unavailable in app myos +WARNING: myos[0] DOMAIN-rule-exists: target DOMAIN unavailable in app myos +[exit 0] diff --git a/spec/golden/expected/cmd-exec-host.txt b/spec/golden/expected/cmd-exec-host.txt new file mode 100644 index 0000000..9caea5b --- /dev/null +++ b/spec/golden/expected/cmd-exec-host.txt @@ -0,0 +1,5 @@ +docker --log-level=error compose --ansi=auto -f @MYOS@/share/compose/networks.yml -p tester-myos-local exec -T sh -c host/consul consul members +/bin/bash: -c: line 0: syntax error near unexpected token `||' +/bin/bash: -c: line 0: `|| true' +make: *** [exec] Error 2 +[exit 2] diff --git a/spec/golden/expected/cmd-exec-service.txt b/spec/golden/expected/cmd-exec-service.txt new file mode 100644 index 0000000..a6c6113 --- /dev/null +++ b/spec/golden/expected/cmd-exec-service.txt @@ -0,0 +1,5 @@ +docker --log-level=error compose --ansi=auto -f @MYOS@/share/compose/networks.yml -p tester-myos-local exec -T fabio sh -c host/fabio sh +/bin/bash: -c: line 0: syntax error near unexpected token `||' +/bin/bash: -c: line 0: `|| true' +make: *** [exec] Error 2 +[exit 2] diff --git a/spec/golden/expected/cmd-ls-groups.txt b/spec/golden/expected/cmd-ls-groups.txt new file mode 100644 index 0000000..bc1750c --- /dev/null +++ b/spec/golden/expected/cmd-ls-groups.txt @@ -0,0 +1,46 @@ +make: unrecognized option `--groups' +Usage: make [options] [target] ... +Options: + -b, -m Ignored for compatibility. + -B, --always-make Unconditionally make all targets. + -C DIRECTORY, --directory=DIRECTORY + Change to DIRECTORY before doing anything. + -d Print lots of debugging information. + --debug[=FLAGS] Print various types of debugging information. + -e, --environment-overrides + Environment variables override makefiles. + -f FILE, --file=FILE, --makefile=FILE + Read FILE as a makefile. + -h, --help Print this message and exit. + -i, --ignore-errors Ignore errors from commands. + -I DIRECTORY, --include-dir=DIRECTORY + Search DIRECTORY for included makefiles. + -j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg. + -k, --keep-going Keep going when some targets can't be made. + -l [N], --load-average[=N], --max-load[=N] + Don't start multiple jobs unless load is below N. + -L, --check-symlink-times Use the latest mtime between symlinks and target. + -n, --just-print, --dry-run, --recon + Don't actually run any commands; just print them. + -o FILE, --old-file=FILE, --assume-old=FILE + Consider FILE to be very old and don't remake it. + -p, --print-data-base Print make's internal database. + -q, --question Run no commands; exit status says if up to date. + -r, --no-builtin-rules Disable the built-in implicit rules. + -R, --no-builtin-variables Disable the built-in variable settings. + -s, --silent, --quiet Don't echo commands. + -S, --no-keep-going, --stop + Turns off -k. + -t, --touch Touch targets instead of remaking them. + -v, --version Print the version number of make and exit. + -w, --print-directory Print the current directory. + --no-print-directory Turn off -w, even if it was turned on implicitly. + -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE + Consider FILE to be infinitely new. + --warn-undefined-variables Warn when an undefined variable is referenced. + -N OPTION, --NeXT-option=OPTION + Turn on value of NeXT OPTION. + +This program built for i386-apple-darwin11.3.0 +Report bugs to +[exit 2] diff --git a/spec/golden/expected/cmd-ls.txt b/spec/golden/expected/cmd-ls.txt new file mode 100644 index 0000000..4b22725 --- /dev/null +++ b/spec/golden/expected/cmd-ls.txt @@ -0,0 +1,2 @@ +WARNING: myos[0] ls-rule-exists: target ls unavailable in app myos +[exit 0] diff --git a/spec/golden/expected/cmd-run-catalogue.txt b/spec/golden/expected/cmd-run-catalogue.txt new file mode 100644 index 0000000..6bbc95b --- /dev/null +++ b/spec/golden/expected/cmd-run-catalogue.txt @@ -0,0 +1,2 @@ +docker --log-level=error compose --ansi=auto -f @MYOS@/share/compose/networks.yml -p tester-myos-local run --rm postgres psql -l +[exit 0] diff --git a/spec/golden/expected/cmd-scale.txt b/spec/golden/expected/cmd-scale.txt new file mode 100644 index 0000000..13144f1 --- /dev/null +++ b/spec/golden/expected/cmd-scale.txt @@ -0,0 +1,4 @@ +make -o docker-stack-scale MAKE_OLDFILE=docker-stack-scale ENV=local DOCKER_COMPOSE=docker --log-level=error compose docker-compose-scale STACK=myos APP_NAME=myos +docker --log-level=error compose --ansi=auto -f @MYOS@/share/compose/networks.yml -p tester-myos-local up -d --scale postgres=3 +WARNING: myos[0] postgres-rule-exists: target postgres unavailable in app myos +[exit 0]