403 Commits

Author SHA1 Message Date
Muayyad Alsadi
1b85ebe506 version 2024-02-06 00:26:51 +03:00
Muayyad Alsadi
9ed05a23ef add TQDM and implement pool.join 2024-02-06 00:26:51 +03:00
Muayyad Alsadi
d475260951 add TQDM and implement pool.join 2024-02-06 00:26:51 +03:00
Muayyad Alsadi
831caa6276 remove recursion 2024-02-06 00:23:14 +03:00
Ben Plessinger
9ac33392a0 Fix issue #831
Signed-off-by: Ben Plessinger <Benjamin.Plessinger@roswellpark.org>
2024-02-06 00:20:11 +03:00
Falmarri
c5be5bae90 Fixup tests
Signed-off-by: Falmarri <463948+Falmarri@users.noreply.github.com>
2024-02-04 10:11:57 +03:00
Falmarri
c6a1c4c432 Add tests to make sure all async paths are covered
Not at 100% yet. But upped code coverage significantly and covered major
async calls.

Signed-off-by: Falmarri <463948+Falmarri@users.noreply.github.com>
2024-02-04 10:11:57 +03:00
Falmarri
3c9628b462 Fix a couple issues and update docs
Signed-off-by: Falmarri <463948+Falmarri@users.noreply.github.com>
2024-02-04 10:11:57 +03:00
Falmarri
38b13a34ea Use asyncio for subprocess calls
Removes the threads from compose_up and manages it using async. Also
uses async processing to format the log messages instead of piping
through sed. This should work on windows without having sed installed

Adds --parallel to support pull and build in parallel, same as docker
compose

Signed-off-by: Falmarri <463948+Falmarri@users.noreply.github.com>
2024-02-04 10:11:57 +03:00
ambiamber
bce40c2db3 Change "an key-value" to "a key-value" 2023-08-08 18:05:58 +03:00
Kian-Meng Ang
78f8cad7c4 Fix typos
Found via `codespell -L poped`
2023-08-08 18:05:25 +03:00
Mohammed Tayeh
7942a540cd fix styling errors
Signed-off-by: Mohammed Tayeh <m.tayeh94@gmail.com>
2023-08-08 18:05:02 +03:00
Mohammed Tayeh
cb9cf6002f add stats command
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2023-08-08 18:05:02 +03:00
Evedel
06587c1dca rm redundant tests
Signed-off-by: Evedel <svbiriukov@gmail.com>
2023-08-02 14:19:15 +03:00
Evedel
bc9168b039 add no-normalize flag
Signed-off-by: Evedel <svbiriukov@gmail.com>
2023-08-02 14:19:15 +03:00
Sergei Biriukov
57c527c2c9 add edits from review
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-08-02 14:19:15 +03:00
Sergei Biriukov
d1f5ac9edc convert build context path to absolute during final normalisation
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-08-02 14:19:15 +03:00
Natanael Arndt
0164c1db56 Simplify the fix using or.
Signed-off-by: Natanael Arndt <arndtn@gmail.com>
2023-07-26 17:32:14 +03:00
Natanael Arndt
e5cdce4e7d default to an empty dict for the from service if the service is None
Signed-off-by: Natanael Arndt <arndtn@gmail.com>
2023-07-26 17:32:14 +03:00
Natanael Arndt
280f1770bf Add a test to extend using an empty service (placeholder)
Signed-off-by: Natanael Arndt <arndtn@gmail.com>
2023-07-26 17:32:14 +03:00
Muayyad alsadi
f75d12af21 broken in py 3.7 2023-07-18 13:23:55 +03:00
Hedayat Vatankhah
5454c3ad0f Add 'links' aliases to container aliases
Signed-off-by: Hedayat Vatankhah <hedayat.fwd@gmail.com>
2023-07-18 13:14:57 +03:00
Hedayat Vatankhah
901adf47d0 Use defined environment variables in the image build process
Build images with service environment variables defined so that they can be
used in the build process

Signed-off-by: Hedayat Vatankhah <hedayat.fwd@gmail.com>
2023-07-18 13:13:33 +03:00
Mahmoud Abduljawad
bf07e91163 Implement include from compose-spec
Signed-off-by: Mahmoud Abduljawad <mahmoud@masaar.com>
2023-07-18 13:05:46 +03:00
Muayyad alsadi
3890eacf57 Merge branch 'Evedel-allow-config-to-merge-strings-and-dicts-in-build' into devel 2023-05-29 11:47:41 +03:00
Sergei Biriukov
cfd24cc2e8 Merge branch 'devel' into allow-config-to-merge-strings-and-dicts-in-build
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 18:14:44 +10:00
Sergei Biriukov
79bfad103c move logic from rec_merge to normalize_service
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 10:42:44 +03:00
Sergei Biriukov
d1509468c3 allow empty list to be a command/entrypoint
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 10:42:44 +03:00
Sergei Biriukov
9011e9faa1 add tests, dry up code, use shlex.split instead of str.split
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 10:42:44 +03:00
Sergei Biriukov
517aeba330 Allow config to merge strings and lists in command and entrypoint
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 10:42:44 +03:00
Sergei Biriukov
85d5d5dcc9 move logic from rec_merge to normalize_service
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-05-06 15:17:54 +10:00
Cleber Rosa
1ffd24dcf9 Python version support: sync verified and advertised versions
There are differences with regards to the versions of Python that are
verified (somehow) through Pylint, and the ones that are advertised.

Given that there's no pinning of Pylint versions, it shouldn't be
possible to use it on Python versions such as 3.5 and 3.6 (latest
Pylint doesn't support those).  With that, let's cover all the
currently supported Python versions.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
2023-05-06 00:28:13 +03:00
Sergei Biriukov
8c66b1cda7 add test case for when build is a complex dictionary
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-04-30 15:37:52 +10:00
Sergei Biriukov
a0005db474 add code implementing build value merge
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-04-29 13:52:19 +10:00
Sergei Biriukov
221cf14501 add tests for build value merge
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-04-29 13:17:43 +10:00
Sergei Biriukov
a61945b516 fix format
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-04-21 20:47:53 +03:00
Sergei Biriukov
6b6330c587 add build subcommand and --build arg to compose_run
Signed-off-by: Sergei Biriukov <svbiriukov@gmail.com>
2023-04-21 20:47:53 +03:00
BugFest
5d279c4948 Build-fail test example
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-12 22:25:33 +03:00
BugFest
5a3bdbf89b Exit code managed at PodmanCompose.run()
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-12 22:25:33 +03:00
BugFest
1eb166445b Linting fixes
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-12 22:25:33 +03:00
BugFest
82182b7bc6 Finish execution in compose_build only on command=build calls
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-12 22:25:33 +03:00
BugFest
3f4618866b Update project-1.env 2023-04-10 14:14:14 +03:00
BugFest
91bc6ebdb4 Keep chdir after loading env file
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 14:14:14 +03:00
BugFest
59a59c1a3a Fixes #636: env-file shall be resolved relative to the CWD
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 14:14:14 +03:00
BugFest
620f5d7473 pre-commit black config: run in check only mode
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 14:13:00 +03:00
BugFest
6f902faed0 Fix linting issues
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 14:12:32 +03:00
Muayyad Alsadi
ccdf01e9b0 Revert "Use SELinux mount flag for secrets"
This reverts commit 874192568f.
2023-04-10 12:26:53 +03:00
Muayyad Alsadi
e6b1eabe4c Revert "Use more lenient SELinux mount flag for secrets"
This reverts commit 75de39c239.
2023-04-10 12:26:53 +03:00
Henry Reed
75de39c239 Use more lenient SELinux mount flag for secrets
Signed-off-by: Henry Reed <60915078+henryreed@users.noreply.github.com>
2023-04-10 12:25:53 +03:00
Henry Reed
874192568f Use SELinux mount flag for secrets
Signed-off-by: Henry Reed <github.69ofd@simplelogin.com>
2023-04-10 12:25:53 +03:00
Bhavin Gandhi
0b853f29f4 Ignore access mode when merging volumes short syntax
The target path inside the container is treated as a key. Ref:
https://github.com/compose-spec/compose-spec/blob/master/spec.md#merging-service-definitions

Signed-off-by: Bhavin Gandhi <bhavin7392@gmail.com>
2023-04-10 12:25:05 +03:00
waechtjn
847f01a6c6 Add a docker-compose test file for uidmaps/gidmaps
Add a simple docker-compose.yml test to use the x-podman extension with
uidmaps and gitmaps
2023-04-10 12:22:25 +03:00
waechtjn
e511e6420f FIXES #228: Add support for uidmap and gidmap
Implement an x-podman extension on the level of the individual services
to handle `--uidmap` and `--gidmap`
2023-04-10 12:22:25 +03:00
KuhnChris
a9723ec1cf Added a way to start containers with multiple ips and nets
Signed-off-by: KuhnChris <kuhnchris@kuhnchris.eu>
2023-04-10 12:16:54 +03:00
Kuan-Yi Li
1cb608d8a7 allow project name to be fetched from dotenv
Look for project name in `self.environ` which includes both `os.environ`
and dotenv variables so that the project name can also be defined in an
environment file.

Signed-off-by: Kuan-Yi Li <kyli@abysm.org>
2023-04-10 12:13:23 +03:00
Dixon Whitmire
252f1d57a5 updating black formatting for podman-compose.py
Signed-off-by: Dixon Whitmire <dixonwh@gmail.com>
2023-04-10 12:12:18 +03:00
Dixon Whitmire
13856d2e9c updating black formatting
Signed-off-by: Dixon Whitmire <dixonwh@gmail.com>
2023-04-10 12:12:18 +03:00
Dixon Whitmire
8d8df0bc28 Adding basic support for --profile argument
Signed-off-by: Dixon Whitmire <dixonwh@gmail.com>
2023-04-10 12:12:18 +03:00
Richard de Vos
bc5f0123d9 add option to start podman in existing network namespace 2023-04-10 12:11:02 +03:00
Roman Blanco
9a08f85ffd FIXES #586: preserve exit code for podman-compose build
Signed-off-by: Roman Blanco <rblanco@redhat.com>
2023-04-10 12:10:16 +03:00
Benedikt Braunger
8625d7a4e8 add ipam-driver support
Signed-off-by: Benedikt Braunger <bb@emlix.com>
2023-04-10 12:02:47 +03:00
BugFest
016c97fd1e Fixes #663 - Fixes linting/pylint errors
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 11:53:47 +03:00
BugFest
2df11674c4 Fixes #661 - Fixes linting/flake8 errors
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 11:53:47 +03:00
BugFest
5eff38e743 Fixes #659: fix permissions when installing OS packages for linting/black
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-10 11:28:07 +03:00
Muayyad alsadi
7f5ce26b1b start version 1.0.7 and default with pod enabled by default 2023-04-09 14:08:54 +03:00
Muayyad alsadi
f6dbce3618 version 1.0.6 2023-04-09 14:02:10 +03:00
Muayyad alsadi
dfb64d884d fix pylint 2023-04-09 13:10:33 +03:00
Muayyad alsadi
990f774659 fix pylint 2023-04-09 12:47:15 +03:00
Muayyad alsadi
5e518c7ca7 #648: check if sed exists to color logs 2023-04-09 12:07:43 +03:00
Muayyad alsadi
9046f7eee0 #634: follow up 2023-04-09 12:00:45 +03:00
Benedikt Braunger
ef55067834 add support for network priorities
Signed-off-by: Benedikt Braunger <bb@emlix.com>
2023-04-09 11:44:21 +03:00
Michel Jung
ed2a6c0917 Support network_mode: none
Fixes #566
2023-04-09 11:36:30 +03:00
Sander Hoentjen
b4c0792995 Add --remove-orphans on down command
Signed-off-by: Sander Hoentjen <shoentjen@antagonist.nl>
2023-04-09 11:35:46 +03:00
Sander Hoentjen
e84451f4ea Allow environment parameters without value
Signed-off-by: Sander Hoentjen <shoentjen@antagonist.nl>
2023-04-09 11:34:25 +03:00
Excedrin
456370bd46 Support build secrets
Signed-off-by: Excedrin <290525+Excedrin@users.noreply.github.com>
2023-04-09 11:33:45 +03:00
molasses11
efe3714266 Add support for the group_add property of a service. 2023-04-09 11:33:16 +03:00
BugFest
c55a2f4c26 Fixes #657: Support act and developer-friendly environment
Signed-off-by: BugFest <bugfest.dev@pm.me>
2023-04-09 11:31:12 +03:00
Muayyad alsadi
b8a7593026 #154: timeout 2023-03-29 11:30:24 +03:00
Muayyad alsadi
bd29ddb3e9 #154: no -t for start 2023-03-29 01:31:42 +03:00
Muayyad alsadi
38219eb85c FIXES #154: handle stop_grace_period 2023-03-28 17:33:02 +03:00
Dixon Whitmire
08ffcf6126 updating test_podman_compose_extends_w_file_subdir to use the correct image name
Signed-off-by: Dixon Whitmire <dixonwh@gmail.com>
2022-10-28 00:13:56 +02:00
dependabot[bot]
801faea30b Bump actions/setup-python from 2 to 4
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-19 00:00:10 +03:00
dependabot[bot]
06da9667f3 Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-18 23:59:50 +03:00
John Losito
de3f607758 Check for github actions updates weekly
Signed-off-by: John Losito <lositojohnj@gmail.com>
2022-10-17 18:15:27 +03:00
Aleksandr Mezin
db1861d33f pull: accept service names as positional arguments
Fixes #547

Signed-off-by: Aleksandr Mezin <mezin.alexander@gmail.com>
2022-09-01 23:07:56 +03:00
Simon Cornish
9d5b255927 Use top-level name property as project name if user doesn't set one explicitly
Signed-off-by: Simon Cornish <7t9jna402@sneakemail.com>
2022-08-18 10:00:28 +03:00
Muayyad alsadi
2d05c5c339 FIXES #534: add systemd unit label 2022-07-29 21:13:44 +03:00
Muayyad alsadi
3c460160e0 FIXES #534: add systemd unit label 2022-07-29 21:13:07 +03:00
Wilke Schwiedop
5b9cfe5d17 implement services.*.build.tags
https://github.com/compose-spec/compose-spec/blob/master/build.md#tags
2022-07-28 02:25:49 +03:00
Carmine Zaccagnino
8d1a4d7274 Implemented basic Bash shell completion
Signed-off-by: Carmine Zaccagnino <carmine@carminezacc.com>
2022-07-20 00:33:22 +03:00
inganault
859f03cbe6 Add healthcheck.disable support
Signed-off-by: inganault <p.po.oo.on.n@gmail.com>
2022-07-14 23:33:16 +03:00
Muayyad alsadi
ae6be272b5 reformat 2022-07-14 00:59:10 +03:00
Mohammed Tayeh
ccdb98c0e4 implement podman kill command
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2022-07-14 00:55:33 +03:00
Muayyad alsadi
909d05e718 reformat 2022-07-13 20:45:16 +03:00
Mohammed Tayeh
0cf98c7893 reimplement the of pause and unpause commands
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2022-07-13 20:31:46 +03:00
Mohammed Tayeh
843b876885 fix typo
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2022-07-13 20:31:46 +03:00
Mohammed Tayeh
1188463734 fix Typo podman-composer in version command
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2022-07-13 20:31:46 +03:00
Mohammed Tayeh
10580db329 Add pause,unpause commands support
Signed-off-by: Mohammed Tayeh <info@tayeh.me>
2022-07-13 20:31:46 +03:00
Muayyad alsadi
f7d335dc6a #516: allow empty network 2022-07-04 18:21:31 +03:00
Muayyad alsadi
4a73ae86bc FIXES #511: ipv6 2022-06-29 12:03:54 +03:00
Muayyad alsadi
f674ab8cfb #512: only use --net when bridge 2022-06-29 11:55:39 +03:00
Muayyad alsadi
265e0ca32a #512: only use --net when bridge 2022-06-29 10:46:47 +03:00
Muayyad alsadi
92662f3409 FIXES #511: ipv6 2022-06-28 15:58:19 +03:00
Muayyad alsadi
42c0078e6b mac_address with dash 2022-06-22 14:24:34 +03:00
Muayyad alsadi
da5ee723c3 reformat 2022-06-21 21:54:44 +03:00
Muayyad alsadi
06fc0715fe reformat 2022-06-21 21:51:09 +03:00
Muayyad alsadi
9eda56caf9 FIXES #507: respecte mac_address 2022-06-21 21:48:45 +03:00
Stefan Marinov
13c8981c6d Fix help message for systemd subcommand
- Fix wording in docstring about initial setup of systemd service.
- Trim extra indentation at start of multiline docstrings.

Signed-off-by: Stefan Marinov <smarnv@dnl.sk>
2022-05-15 17:50:27 +03:00
Muayyad alsadi
ee7029fbde reformat 2022-05-10 02:32:08 +03:00
Muayyad alsadi
75033a4ed7 add python demo example 2022-05-10 02:28:17 +03:00
Muayyad alsadi
c175fd1b10 reformat 2022-05-10 01:30:03 +03:00
Muayyad alsadi
d479001454 reference awesome-compose 2022-05-10 01:27:52 +03:00
Muayyad alsadi
a2defdd06a example wordpress 2022-05-10 01:24:06 +03:00
Muayyad alsadi
c55cd67bd2 #307: default to /etc/ 2022-05-10 01:13:34 +03:00
Daniel Roythorne
eed38ce76c Fixed accidental deletion of project functionality. 2022-05-10 01:11:32 +03:00
Daniel Roythorne
86ffad86c7 Added port subcommand. 2022-05-10 01:11:32 +03:00
Gagootron
118d39b5bb Fix linter errors 2022-05-10 01:10:29 +03:00
Gagootron
814bd2a31a Support driver_opts for networks 2022-05-10 01:10:29 +03:00
ohxodi
606b9d94c8 Simplify var assignment 2022-04-29 17:11:58 +03:00
ohxodi
0057a4bb31 Fix default external name in dict case 2022-04-29 17:11:58 +03:00
ohxodi
8ecb74916d Update external volume name management 2022-04-29 17:11:58 +03:00
ohxodi
d983056982 Update external volume name management 2022-04-29 17:11:58 +03:00
ohxodi
ed302ca518 Fix external volume name when no name provided 2022-04-29 17:11:58 +03:00
ohxodi
0b5c844431 Add runtime error if no external volume exists 2022-04-29 17:11:58 +03:00
Muayyad alsadi
9c29c8914f FIXES #486: replace realpath with abspath 2022-04-27 13:01:24 +03:00
Bastian Venthur
89d2062579 Fixed some spelling and grammar issues
Signed-off-by: Bastian Venthur <bastian.venthur@flixbus.com>
2022-04-25 10:49:39 +03:00
Muz
f42b568fc2 Correct the help text for --pod-args
Signed-off-by: Muz <git@mustaqila.li>
2022-04-10 22:21:35 +03:00
Muz Ali
a1d3ba4ea2 Lint fixes for --services flag handling in config
Signed-off-by: Muz Ali <muz.ali@shopify.com>
2022-04-07 08:25:03 +03:00
Shane Smith
6be661f6da Support platform property
As per https://github.com/compose-spec/compose-spec/blob/master/spec.md#platform

Example:

```
services:
  mysql:
    image: mysql:5.7
    platform: linux/x86_64
```

Signed-off-by: Shane Smith <shane.smith@shopify.com>
2022-04-07 08:24:46 +03:00
Muz
fc3598faf2 Allow --services in config
Signed-off-by: Muz <git@mustaqila.li>
2022-04-04 11:20:41 +03:00
Muayyad alsadi
fbff315e18 FIXES #464: accept -v in run 2022-03-29 21:17:02 +03:00
Muayyad alsadi
fc34703dd4 format 2022-03-28 14:07:36 +03:00
Muayyad alsadi
c7ada820de format 2022-03-28 13:54:55 +03:00
Muayyad alsadi
5e286f6356 format 2022-03-28 13:52:21 +03:00
Muayyad alsadi
3dd8b05d74 format 2022-03-28 13:47:28 +03:00
Muayyad alsadi
3ecb4b5dd5 FIXES #462: fix extends merge 2022-03-28 13:40:02 +03:00
Muayyad alsadi
d05cad4c65 FIXES #462: fix extends merge 2022-03-28 13:32:22 +03:00
Muayyad alsadi
ebb3dfe634 #452: better missing network message 2022-03-20 17:16:59 +03:00
Muayyad alsadi
7b99b38f0e nethost test 2022-03-19 00:17:22 +03:00
Muayyad alsadi
4ef8afc63e hit counter with redis cluster example 2022-03-19 00:12:48 +03:00
Muayyad alsadi
a1aed09a58 GCR hello app 2022-03-18 23:14:26 +03:00
Muayyad alsadi
2cacf9cfb5 add echo example 2022-03-18 23:00:21 +03:00
Muayyad alsadi
4064c84521 add azure vote example 2022-03-18 22:43:18 +03:00
Muayyad alsadi
0dde95ac1d update gitignore 2022-03-18 18:34:01 +03:00
Muayyad alsadi
1be41b46a5 do not merge command array 2022-03-18 18:29:27 +03:00
Muayyad alsadi
105c27c8dc example nodejs project 2022-03-18 18:05:57 +03:00
Muayyad alsadi
f820594257 use exec for wait 2022-03-18 15:50:24 +03:00
Muayyad alsadi
8a72321720 FIXES #409: detect changes and recreate 2022-03-16 15:27:30 +03:00
Muayyad alsadi
529391963d FIXES #409: detect changes and recreate 2022-03-16 15:25:57 +03:00
Muayyad alsadi
48a19f13fc print more help with systemd 2022-03-15 23:01:22 +03:00
Muayyad alsadi
a9faabb1b0 print more help with systemd 2022-03-15 22:50:03 +03:00
Muayyad alsadi
3fb2b98ecc print more help with systemd 2022-03-15 22:47:54 +03:00
Muayyad alsadi
b35b7e448a add systemd -a list 2022-03-14 14:17:49 +03:00
Muayyad alsadi
1a72e1e087 add systemd -a list 2022-03-14 14:05:20 +03:00
Muayyad alsadi
b620311aaf FIXES #449: accept int port 2022-03-13 23:36:25 +03:00
Muayyad alsadi
bf8004b04d systemd unit file 2022-03-13 11:20:59 +03:00
Muayyad alsadi
cadf046306 fix pylint 2022-03-13 10:18:03 +03:00
Muayyad alsadi
8d8149cfe5 fix pylint 2022-03-13 10:12:36 +03:00
Muayyad alsadi
3dd981727b fix pylint 2022-03-13 10:08:48 +03:00
Muayyad alsadi
0b469e0590 format 2022-03-12 23:17:26 +03:00
Muayyad alsadi
9e3020a9df FIXES #307: systemd command 2022-03-12 23:08:24 +03:00
Muayyad alsadi
fc9ed19b2b wait command 2022-03-12 21:16:16 +03:00
Muayyad alsadi
2d6bb52e36 FIXES #442: allow --no-pod or custom --pod-args 2022-03-08 21:22:43 +03:00
Muayyad alsadi
7942a091c3 FIXES #442: allow --no-pod or custom --pod-args 2022-03-08 21:13:14 +03:00
Muayyad alsadi
701311aa7a FIXES #447: support --env-file 2022-03-08 12:01:02 +03:00
Muayyad alsadi
d7049150d0 FIXES #447: support --env-file 2022-03-08 10:57:44 +03:00
Muayyad alsadi
3b7bf81051 remove unused test 2022-03-08 10:47:16 +03:00
Tom Bu
a735aa5b96 Fix inverted condition in merging arguments
Signed-off-by: Tom Bu <tombu@tombu.info>
2022-03-02 06:12:26 +03:00
Piotr Husiatyński
b78509527b Fix linter issues
Make _cmd_desc a public attribute, so that it can be used outside of the
class methods.

Signed-off-by: Piotr Husiatyński <phusiatynski@gmail.com>
2022-03-01 17:16:04 +03:00
Piotr Husiatyński
762318093c Force black formatting
Black removes the burden of manual code formatting and is by now
considered the standard Python formatting tool.

https://black.readthedocs.io/en/stable/

Format all Python code with black.

GitHub linting action is updated to ensure all files are formatted with
Black.

Signed-off-by: Piotr Husiatyński <phusiatynski@gmail.com>
2022-03-01 17:16:04 +03:00
Muayyad alsadi
af10345483 FIXES #440: absolute secret 2022-02-28 01:19:39 +03:00
Muayyad alsadi
2d1bcddf09 update readme 2022-02-26 03:13:38 +03:00
Muayyad alsadi
4f025679cf add unit tests 2022-02-26 03:10:35 +03:00
Muayyad alsadi
064521255b add badge 2022-02-26 02:58:26 +03:00
Muayyad alsadi
b7c5609603 pylint 2022-02-26 02:51:06 +03:00
Muayyad alsadi
44508352e8 pylint 2022-02-26 02:49:34 +03:00
Muayyad alsadi
5c33e4efbb pylint 2022-02-26 01:41:07 +03:00
Muayyad alsadi
cbd6f6b1b6 pylint cleanups 2022-02-26 00:48:42 +03:00
Muayyad alsadi
de1e59d1d5 fix some pylint 2022-02-25 23:59:15 +03:00
Muayyad alsadi
2f0ca9e41d add pytest ci 2022-02-25 21:50:52 +03:00
Muayyad alsadi
59c9a69689 add pylint 2022-02-25 21:42:32 +03:00
Muayyad Alsadi
b7eac1e898 pylint 2022-02-25 21:39:10 +03:00
Muayyad Alsadi
0d47e470fc activate test 2022-02-25 21:30:15 +03:00
Piotr Husiatyński
c2d7b26f2e #434: handle unknown service 2022-02-25 21:13:10 +03:00
Muayyad alsadi
1e895c0873 calc proper hash 2022-02-25 18:56:36 +03:00
Muayyad alsadi
132a22b524 #130: handle nested extend and normalize build context 2022-02-25 18:32:19 +03:00
kjunker
0bde01de07 remove unused imports
Signed-off-by: kjunker <junker.kurt@googlemail.com>
2022-02-22 13:26:44 +02:00
kjunker
91a579b81e Adding Test that the changes can build Image from build context of extended compose-file
Signed-off-by: kjunker <junker.kurt@googlemail.com>
2022-02-22 13:26:44 +02:00
kjunker
56b88639ad Fixing subdirectory from extends where extended service will build a Service from Dockerfile in an own subdirectory
Signed-off-by: kjunker <junker.kurt@googlemail.com>
2022-02-22 13:26:44 +02:00
Muayyad alsadi
5c3ec5f49a FIXES #431: support dns 2022-02-20 22:11:15 +02:00
Muayyad alsadi
779198b003 #379: no infra container 2022-02-17 17:19:25 +02:00
Muayyad alsadi
40cb6a760e log version 2022-02-17 13:36:44 +02:00
Muayyad alsadi
4fd9d86e17 #379: nothing shared in the pod to allow hostname 2022-02-17 13:28:31 +02:00
Devansh Sharma
2a2c3a09c1 Fix timeout value data type
Signed-off-by: Devansh Sharma <devansh.sharma@gmail.com>
2022-02-17 10:16:39 +02:00
Muayyad alsadi
80e852717d #379: create a pod 2022-02-15 01:55:28 +02:00
Muayyad alsadi
d6e21dc752 FIXES #425: pass --requires 2022-02-15 01:33:00 +02:00
Muayyad alsadi
b9b2f83d04 FIXES #415: allow network_mode=slirp4netns 2022-02-12 17:39:42 +02:00
Muayyad alsadi
9af65ea112 adjust comment 2022-02-12 17:35:04 +02:00
Muayyad alsadi
3e6e268034 test for logs 2022-02-12 13:54:30 +02:00
Cody Hutchins
af6a3069ce fix syntax error without a new line
Signed-off-by: Cody Hutchins <codyhutchins@seed-innovations.com>
2022-02-12 13:47:45 +02:00
Cody Hutchins
68f745fe62 referenced unmerged pr #192 to bring colors into container logging
Signed-off-by: Cody Hutchins <codyhutchins@seed-innovations.com>
2022-02-12 13:47:45 +02:00
Muayyad alsadi
90dcfdbf44 FIXES #420: document -t 2022-02-12 13:42:00 +02:00
Geoffroy Doucet
ed8635a9a3 FIXES #422: Remove debug print
Signed-off-by: Geoffroy Doucet <geoffroy.doucet@kloodz.com>
2022-02-12 13:35:58 +02:00
Adrian Torres
1d972ef174 Propagate all bind-type mount options
Before this commit, adding multiple options to a bind-type mount
(e.g. /foo/bar:/baz:Z,U) would result in a podman command in which
only the last option would be used (e.g. U).

This is because when parsing the mount string, a loop would go over
each mount option and assign it to mount_opt_dict, this meant that
this dict was overridden for each option, thus only the last option
in the mount string would be kept and passed onto podman.

This commit solves this by appending to a temporary list and then
converting it to a comma-separated string and assigning it to the
mount_opt_dict.

Fixes #412

Signed-off-by: Adrian Torres <atorresj@redhat.com>
2022-02-12 13:27:49 +02:00
Bernd Schoolmann
536925ca78 FIXES #413: parse network_mode: container:container_name correctly
Signed-off-by: Bernd Schoolmann <mail@quexten.com>
2022-01-30 14:55:21 +02:00
Muayyad alsadi
09c6cbe503 FIXES #408: preserve exit code 2022-01-22 00:24:17 +02:00
Muayyad alsadi
154a51245f FIXES #386: make sure volumes are present in top level 2022-01-22 00:15:05 +02:00
Muayyad alsadi
523d215b48 #407: allow network_mode=service:mysrv 2022-01-18 20:40:29 +02:00
Muayyad Alsadi
25494b5f6e Update README.md 2022-01-18 17:57:37 +02:00
tengattack
19662c02a1 Fix healthcheck test type on replicas 2022-01-15 20:22:05 +02:00
Muayyad alsadi
4943e52344 #395: make podman respect PODMAN_* in .env 2022-01-12 22:06:47 +02:00
Muayyad alsadi
4aa08cd016 FIXES #399: pass specific ip 2022-01-12 21:48:42 +02:00
Muayyad alsadi
15e0ab9261 FIXES #397: support host network mode 2022-01-12 15:44:47 +02:00
Muayyad alsadi
f66861f89a #249: read COMPOSE_PROJECT_NAME env 2022-01-12 15:37:07 +02:00
Luiz Carvalho
af53b65068 Simplify volume identification
The filtering provided by "volume ls" did not work as expected
in previous versions of podman:
https://github.com/containers/podman/pull/8345

Verified that this now works properly on podman 3.4.4

Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
2022-01-06 17:39:52 +02:00
Muayyad Alsadi
890c584881 Update README.md 2022-01-04 16:18:20 +02:00
Mohamed Akram
0bd493f1ba Allow empty default/error value in substitution 2021-12-31 18:40:26 +02:00
Muayyad alsadi
481c6d0a41 #394: config: multiple yaml 2021-12-31 01:54:32 +02:00
Hao Luo
31df70b8d2 updated per maintainer review 2021-12-31 01:39:03 +02:00
Hao Luo
df400518a7 removes version from CONTRIBUTING 2021-12-31 01:39:03 +02:00
Hao Luo
21a716cfd3 added log back in 2021-12-31 01:39:03 +02:00
Hao Luo
f00ac92640 added config command 2021-12-31 01:39:03 +02:00
Hao Luo
0433410702 added args for version 2021-12-31 01:39:03 +02:00
Muayyad alsadi
0f9fe2bf9f FiXES #393: missing arg when build as part of run 2021-12-31 01:17:26 +02:00
Muayyad alsadi
a1be5ce6b3 add fallback to get 2021-12-31 00:06:48 +02:00
Mohamed Akram
56a4988481 Add support for volume driver and options 2021-12-31 00:04:58 +02:00
Mohamed Akram
377b5525c9 Fix substitution for empty variables 2021-12-31 00:00:10 +02:00
Muayyad alsadi
c50599c0e7 FIXES #388: do not force build in run 2021-12-28 21:03:21 +02:00
Muayyad alsadi
4557279930 #88: multiple aliases 2021-12-25 21:06:29 +02:00
Muayyad alsadi
7ad377557d FIXES #380: output to stderr 2021-12-24 18:55:30 +02:00
Viacheslav Dubrovskyi
30051c2f5b Update README.md. Add link to podman dns plugin source 2021-12-24 14:05:46 +02:00
Muayyad alsadi
9e8e25c159 #378: down -v 2021-12-23 01:17:34 +02:00
Muayyad alsadi
2c60516f77 fix hostname in test 2021-12-23 00:34:01 +02:00
Muayyad alsadi
24ec539932 release 1.0.3 2021-12-21 23:15:52 +02:00
Muayyad alsadi
2803046ac3 add awx 17 example 2021-12-21 22:57:45 +02:00
Muayyad alsadi
d1768c1d9d FIXES #377: down -v 2021-12-21 22:57:45 +02:00
Muayyad alsadi
820ea012c5 FIXES #: U mount propagation option 2021-12-21 22:57:45 +02:00
Muayyad alsadi
5ba96a1082 #365: 'Namespace' object has no attribute 'volumes' 2021-12-21 22:57:45 +02:00
Muayyad Alsadi
49fe6e7e0f Update README.md 2021-12-18 23:34:32 +02:00
Avi Duda
6c1ccfcefa Add missing arguments to the log (latest, names, since, until) 2021-12-14 11:35:30 +02:00
Avi Duda
724d2fd18c Support viewing all logs 2021-12-14 11:35:30 +02:00
Avi Duda
3e940579d9 Support for starting/stopping/restarting all services
Reverse services when stopping or restarting
2021-12-14 11:35:30 +02:00
Muayyad alsadi
af1697e9bf FIXES #288: extenal as dict 2021-12-13 03:25:17 +02:00
Muayyad alsadi
e62f1a54af FIXES #288: extenal as dict 2021-12-13 01:21:34 +02:00
Muayyad alsadi
179f9ab0e3 FIXES #288: do not create external network 2021-12-13 00:24:23 +02:00
Muayyad alsadi
dd6b1ee88c FIXES #288: do not create external network 2021-12-13 00:21:53 +02:00
Muayyad alsadi
9a8dc4ca17 release 1.0.2 2021-12-11 02:06:10 +02:00
Mark Stosberg
6b5f62d693 Fixes #199: seccomp:unconfined 2021-12-11 01:50:40 +02:00
Muayyad alsadi
3782b4ab84 FIXES #371: respect COMPOSE_FILE env 2021-12-10 23:26:13 +02:00
Muayyad alsadi
95e07e27f0 FIXES #185: creates dirs 2021-12-10 22:46:22 +02:00
Muayyad alsadi
a3123ce480 #222: normalize basedir using os.path.realpath 2021-12-10 22:27:00 +02:00
Muayyad alsadi
02f78dc3d7 FIXES #333: when volumes are merged, remove duplicates 2021-12-10 02:06:43 +02:00
Muayyad alsadi
8cd97682d0 FIXES #370: bug-for-bug hanlding of .env 2021-12-10 01:01:45 +02:00
Muayyad alsadi
85244272ff FIXES #368: parse depends_on of type dict 2021-12-09 16:18:52 +02:00
Muayyad alsadi
30cfe2317c set version 2021-12-09 16:12:59 +02:00
Tim Elliott
7fda1cc835 fix AttributeError when running a one-off command
Without this, I get errors when running "podman-compose -p podname run".
2021-12-09 16:11:04 +02:00
Luiz Carvalho
5f40f4df31 Remove named volumes during "down -v"
Fixes containers#105

Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
2021-12-09 16:09:59 +02:00
Muayyad alsadi
d38aeaa713 update README 2021-12-09 15:59:34 +02:00
aanno
17f9ca61bd test fixes for SELinux (Fedora) 2021-11-24 18:06:18 +02:00
Muayyad alsadi
80a47a13d5 add network-alias 2021-11-21 12:35:13 +02:00
Muayyad alsadi
872404c3a7 initial work on CNI podman network create 2021-11-21 01:23:29 +02:00
Muayyad alsadi
1f989ed133 FIXES #356: respect pull_policy 2021-11-16 11:12:08 +02:00
Muayyad alsadi
66ce2a34f5 release 0.1.8 2021-11-15 00:27:03 +02:00
Muayyad alsadi
d8e11d59ef FIXES #312: run starts dependencies 2021-11-14 01:37:22 +02:00
Muayyad alsadi
72c3572123 #289: exit code and test for that 2021-11-14 00:59:41 +02:00
Muayyad alsadi
c187e88eaf up and down specific containers 2021-11-14 00:28:43 +02:00
Muayyad alsadi
31b8bb477d simpler passing of env 2021-11-14 00:00:08 +02:00
Anatoli Babenia
f177712585 Fix up arguments parsing
These is already parsed here
502d7cc206/podman_compose.py (L1644)
2021-11-13 23:53:57 +02:00
Muayyad alsadi
ae3deb19dc #355: fix dry run 2021-11-13 13:08:32 +02:00
Muayyad alsadi
117b7fbb9e command list of strings 2021-11-11 17:52:02 +02:00
Muayyad alsadi
5acb9978eb command list of strings 2021-11-11 17:47:26 +02:00
Muayyad Alsadi
02b2f6585d Update issue templates 2021-11-11 17:43:47 +02:00
Muayyad Alsadi
a36b6f1feb Update issue templates 2021-11-11 17:16:47 +02:00
Muayyad Alsadi
e3be6dd511 Update issue templates 2021-11-11 17:13:56 +02:00
Muayyad Alsadi
4b756786f3 Update issue templates 2021-11-11 17:12:02 +02:00
Muayyad alsadi
dcb038ef3a remove tabs 2021-11-11 14:27:30 +02:00
Muayyad alsadi
a2fef56b07 FIXES #353: down in reverse order 2021-11-11 11:32:24 +02:00
Muayyad alsadi
c753b8e2cf FIXES #167: support ContainerFile 2021-11-11 11:27:33 +02:00
Muayyad alsadi
c9486c9f3b #115: handle string entrypoint 2021-10-25 00:14:19 +03:00
Muayyad alsadi
f2aeaba0d6 #348: conditional --infra-name 2021-10-24 17:35:36 +03:00
Muayyad alsadi
2d80e435dd remove print 2021-10-14 02:12:28 +03:00
Muayyad alsadi
d1a77defcd external name 2021-10-14 02:11:45 +03:00
Muayyad alsadi
c49f0700c8 volumes with names 2021-10-14 01:30:44 +03:00
Igor Kuznetsov
6d69b7c74c Add support external volumes
# docker-compose.yml
version: '3'
services:
  test:
     volumes:
        - data:/data
volumes:
  data:
     name: some
     external: true
2021-10-14 00:12:06 +03:00
Muayyad alsadi
ab135030c8 add support for long port publishing format 2021-10-10 00:43:01 +03:00
Muayyad alsadi
069018c5b1 #342: set infra container name 2021-10-04 14:40:54 +03:00
Anatoli Babenia
b33c42b7e2 Readability fix for missing commands
Of course it would be better to have a proper compatibility page (#26)
2021-09-23 14:58:45 +03:00
Kangwook Lee
785f7ad8a3 Get version info with setup.cfg 2021-09-11 23:35:36 +03:00
Muayyad alsadi
b6a9f8efd4 #335: report version with -v 2021-09-09 00:33:07 +03:00
Jiangge Zhang
4a5fd23a2e #275 make pipx happy 2021-09-08 14:23:02 +03:00
Sam
dc0ac0d03c docs: added the transform_policy default and description 2021-09-06 10:02:13 +03:00
Muayyad alsadi
502d7cc206 #327: accept ports as string 2021-08-26 12:37:14 +03:00
kozlowskim6
e85d79d4f4 added cpu_shares flag for v2 2021-08-18 11:56:12 +03:00
kozlowskim6
bfb57b9ba2 added cpu_shares flag for v2 2021-08-18 11:56:12 +03:00
Gerhard Bräunlich
2d0aad6692 Also pull images with a build section 2021-08-05 15:07:05 +03:00
Gerhard Bräunlich
ff5b9f1663 Support for logging 2021-07-27 14:54:36 +03:00
Sam
62aa337f17 feat(secrets): Add support for secrets
Adds support for -
- (1) Declared secrets with the file location.
- (2) Declared secrets with file location, mounted as a different named secret.
- (3) Declared secrets with file location, mounted at arbitrary location.
- (4) External secrets (type=mount), mounted as original secret name.
- (5) External secrets (type=mount), mounted as original secret name, with specified uid, gid and mode.
2021-07-24 02:29:32 +03:00
Paul Wilde
3836094c64 Update podman_compose.py
it would be nice to use "podman-compose.yml" as a compose file name. compose.yml is useful, but I prefer the clarity of having the "podman" prefix.
2021-07-17 16:18:40 +03:00
Muayyad alsadi
d97a20d563 #308: fix environment 2021-06-23 18:04:13 +03:00
Muayyad alsadi
f417c9ab8c #120: extend not add 2021-06-22 23:52:24 +03:00
Muayyad alsadi
5ed5528294 FIXES #120: parse mem and cpu limits 2021-06-22 23:48:05 +03:00
Muayyad alsadi
3d6ca3c204 FIXES #120: parse mem and cpu limits 2021-06-22 23:30:22 +03:00
Stefan Weil
6e3383de72 Convert numeric command arguments to string (fixes #77)
The input argument cmd_args is a list which may contain numeric elements.

Convert all elements to strings before passing them to functions which
expect str data type.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
2021-06-16 22:19:42 +03:00
Stefan Weil
8ef7587aa1 Fix some typos (found by codespell)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2021-06-16 22:17:28 +03:00
Mattias Giese
039fe30a70 Make sure port entries are converted to strings
Otherwise concatenating all parameters might fail with a TypeError
2021-05-28 21:10:55 +03:00
Robert Hensing
62d2024fee Add stop_signal service attribute 2021-05-18 22:14:21 +03:00
Muayyad alsadi
9317f987fc #278: args 2021-05-17 15:03:47 +03:00
Sander Hoentjen
045cef299b #289: report exit code when --exit-code-from 2021-05-06 02:08:48 +03:00
Muayyad alsadi
a7f97b6120 implement -e in run 2021-05-06 01:17:01 +03:00
Diogo Galvão
0ea18b4419 Force adding an .env file for the tests 2021-05-06 00:50:41 +03:00
Muayyad alsadi
905914b0dc Merge branch 'garotosopa-devel' into devel 2021-05-06 00:49:54 +03:00
Muayyad alsadi
00840d0613 resolve conflict 2021-05-06 00:49:42 +03:00
Diogo Galvão
2ad7daa81f Test variable interpolation in the YAML 2021-05-06 00:44:46 +03:00
Daniel Helgenberger
080b8a369e Prefer 'compose.yaml' as per compose spec
https://github.com/compose-spec/compose-spec/blob/master/spec.md#compose-file
2021-05-05 17:32:25 +03:00
Joakim Repomaa
226ac4fb3a fix missing --label flag in volume creation 2021-05-05 02:13:42 +03:00
Eric Lathrop
030a196102 Fix README typo 2021-04-29 19:20:47 +03:00
SsjackX
901213e5b3 Update podman_compose.py
repair mode written as size
2021-04-29 19:20:26 +03:00
Christian Taedcke
b3370603d9 Add support for sysctls in compose file 2021-04-29 19:19:42 +03:00
Radoslaw Smigielski
b3090c3c3a Mode Python installation and test deps to requirement files
Installation with setup.py fails on missing yaml package, which should
be installed by "install_requires" but this also does not work because
podman_compose.__version__ also needs yaml.
Put all the Python dependencies into separate files:
    - requirements.txt
    - test-requirements.txt
2021-04-29 19:19:14 +03:00
Marcello Sylvester Bauer
5fabfee497 Support annotations
Support annotations analog to "security opt" in commit 29e2bf4c.

Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
2021-04-29 19:18:29 +03:00
Sebastian Ramirez Magri
75a63df954 fix: check .env in current dir with isfile instead of exists
This prevents cases in which an `.env` directory exists, for example
in Python projects with a local virtual environment, and then
dotenv gets passed the directory path as input.
2021-04-29 19:18:06 +03:00
Joakim Repomaa
08dd36f4c1 Add docker-compose labels for interoperability 2021-04-29 19:17:20 +03:00
Martin Häcker
669953b3d3 Rework argument generation to adhere directly to what podman accepts. 2021-04-29 19:10:55 +03:00
Martin Häcker
d3df688aee Remove test code 2021-04-29 19:10:55 +03:00
Martin Häcker
bda7b5e812 Add exec support 2021-04-29 19:10:55 +03:00
Muayyad alsadi
6289d25a42 fixes #236: compatible with docker-compose 2020-12-02 15:31:51 +02:00
Andreas Kohn
abc08135ba Only pull each image once 2020-11-27 18:09:58 +02:00
Daniel Helgenberger
9cd837f01d Fixes #236: Ensure project name works with podman
In case we use dir_basename as podman project name, ensure it matches
podman project name requirement regex: [a-zA-Z0-9][a-zA-Z0-9_.-]*
2020-11-19 17:52:49 +02:00
Davide Madrisan
a4b8b5e709 Fix 'podman-compose version' with no compose file in the working directory
Signed-off-by: Davide Madrisan <davide.madrisan@gmail.com>
2020-11-19 14:51:06 +02:00
Muayyad alsadi
5971f57130 FIXES #249: update dotenv with some envs 2020-11-05 00:14:57 +02:00
Muayyad alsadi
ab96f12dba FIXES #249: update dotenv with some envs 2020-11-05 00:08:19 +02:00
Jonas Eriksson
f6a3cb0aff Allow environment variables to be unset
Leaving keys with empty values in YAML will result in the value
ending up being None after parsing the configuration file. This
should result in the variable being imported from the external
environment according to the Compose file version 3 reference.
The resulting action for podman should be an added "-e VAR"
(without =), which is working correctly.

However, when overwriting an external variable by setting it to
e.g. "", the result in docker-compose is that the variable is
unset. For podman, this means adding "-e VAR=". This is not the
case, and this patch does a more strict check to make this case
behave correctly.
2020-10-12 12:45:14 +03:00
Jonas Eriksson
497355fcfb Re-order environment/env_files to match compose
docker-compose reads the 'env_files' and adds the content as
environment values before adding the 'environment' data. This
means that that 'environment' data overrides 'env_files' data.
Emulate this behaviour by re-ordering -e statements to end up
after --env-file statements.

Relevant function in docker-compose can be viewed here:
https://github.com/docker/compose/blob/1.27.4/compose/config/config.py#L694-L697
2020-10-08 23:25:52 +03:00
Florian Bezannier
20a86ea563 add --no-cache arg to build 2020-09-27 14:14:55 +03:00
Florian BEZANNIER
4e2e960106 build specific service 2020-09-27 14:14:55 +03:00
pinfort
efba3a1380 support str style configuration for env_file 2020-09-10 00:59:51 +03:00
Johannes Laurin Hörmann
90639769f0 BUG: 'podman stop -t 360.0' called for float, expects int on cli 2020-09-06 12:22:01 +03:00
Johannes Laurin Hörmann
3712b545a9 ENH: add timeout option to podman-compose down, as in https://docs.docker.com/compose/reference/down/ 2020-09-06 12:22:01 +03:00
Chris Hozian
294f8ee37b Hashlib to generate SHA256 instead of MD5 for FIPS
Changed hashlib to generate a SHA256 instead of MD5 in order for
podman-compose to function on systems with FIPS mode enabled.
2020-06-15 22:44:00 +03:00
Michael Scherer
105b129b08 Fix infinite loop
Since we never remove thread from the list of thread, podman-compose
up never return as long as 1 thread is alive.
2020-06-02 23:14:59 +03:00
Muayyad alsadi
d3f37112a7 FIXES #181: accept init and init-path 2020-05-22 23:52:48 +03:00
Johannes Laurin Hoermann
7eacf14693 MAINT: resolve https://github.com/containers/podman-compose/pull/180#issuecomment-632722974 2020-05-22 18:09:25 +03:00
Your Name
8cd98ab708 MAINT: extend instead of append 2020-05-22 18:09:25 +03:00
Your Name
047820dbf1 ENH: Added restart policy forwarding to podmann run, compose build args added to up args 2020-05-22 18:09:25 +03:00
Andrej Zieger
e7b1382b1b Add --build-arg to 'up' (Fixes #161) 2020-05-22 17:06:38 +03:00
Mohamed Akram
64ed554543 Allow empty default/error value in substitution 2020-05-13 17:54:20 +03:00
Daniel J Walsh
0ac75fd361 Merge pull request #172 from TomSweeneyRedHat/sec1
Add Security Policy
2020-05-11 10:59:07 -04:00
TomSweeneyRedHat
93bf39e9e2 Add Security Policy
As the title says, plus a small fix in the readme.

Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>
2020-05-09 17:54:44 -04:00
Sam Tygier
5915ba345f Catch error when compose file is empty
Also catch cases such as the top element being a list or a string
2020-05-09 20:04:52 +03:00
Muayyad alsadi
1ca6a88ebd target once 2020-04-22 14:44:36 +03:00
Renee Margaret McConahy
7b40079c06 Pass "target" parameter when building an image. 2020-04-22 14:42:32 +03:00
Matt Novenstern
f9915c47b4 Check for target property when building images
For multi-stage builds, this allows picking a stage to build up to
2020-04-22 14:36:35 +03:00
Andrej Zieger
19733407b4 Add support for --build-arg option 2020-04-22 14:31:00 +03:00
Bao Trinh
e8147e350b Add support for cap_add/cap_drop
Currently, `cap_add` and `cap_drop` are being ignored by podman-compose.
Add the arguments (`--cap-add` and `--cap-drop`, respectively) to
`podman create` when appropriate.
2020-04-22 14:27:33 +03:00
Michael Mraka
7f210ffc43 fixing "Error: unknown flag: --shm_size" 2020-04-21 17:12:11 +03:00
Muayyad alsadi
cbed801c0d start detached 2020-04-19 03:53:55 +03:00
Muayyad alsadi
6a42d6861d add ports test 2020-04-18 22:41:06 +03:00
Muayyad alsadi
07a2430c41 Fixes #152: validate that podman is useable 2020-04-18 22:18:36 +03:00
Muayyad alsadi
5215782cba Fixes #152: validate that podman is useable 2020-04-18 22:15:55 +03:00
Muayyad alsadi
80e7ba188d resolve 2020-04-18 18:46:23 +03:00
Muayyad alsadi
03cbd2929b pass volumes using -v 2020-04-18 18:39:59 +03:00
Enrico204
796e6a4473 Avoid crash when no services are defined
If no services are defined, podman-compose
crashes as services variable is None,
while the expected behavior might be
an error or the same as docker-compose, which will continue the
execution of the compose file (eg. creating networks, etc).

This commit fixes the crash and allows the program to continue, mimicking
docker-compose behavior.
2020-04-05 10:42:31 +03:00
Adam Jones
efcbc75f63 Pass ulimit parameters when building container
When running podman-compose build, pass ulimit arguments from
docker-compose.yml through to podman build.
2020-02-27 17:39:33 +02:00
TomSweeneyRedHat
dacc7538ec Add Code of Conduct
Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>
2020-02-09 01:23:49 +02:00
Christian W
8c3b7e6c54 Added mount option delegated and cached 2019-11-24 10:18:15 +02:00
Maverick
147f0ae42f Update README with dnf install instructions. 2019-11-24 10:17:23 +02:00
Thomas Coldrick
27d3cafb7b Add support for privileged option
Adds support for the `privileged` option in docker-compose.yml. This has
been supported in docker-compose since 0.4.0, so it seems reasonable to
add support here.

See https://docs.docker.com/compose/compose-file/#domainname-hostname-ipc-mac_address-privileged-read_only-shm_size-stdin_open-tty-user-working_dir
2019-11-17 13:13:03 +02:00
Anass Ahmed
e7a9bd3b70 Show stopped containers in ps 2019-11-10 17:16:02 +02:00
Anass Ahmed
ddd582c861 Add support for logs subcommand 2019-11-10 17:15:36 +02:00
Vincent Rischmann
169eaee9b2 Fix override of the run command
If there's no command defined in the arguments, `podman-compose run`
should use the command defined in docker-compose.yml
2019-11-10 17:03:17 +02:00
wampagingwabbits
c5f8973bd5 Mixed-case directory names break 'podman create'
The default project_name uses the directory name, but 'podman create' fails if the directory is mixed case.
2019-11-10 17:02:43 +02:00
Muayyad alsadi
12036aa54e FIXES #76: a service extends a service with same name 2019-11-07 19:09:32 +02:00
Muayyad alsadi
0fc864ffbe Merge branch 'devel' of github.com:containers/podman-compose into devel 2019-11-07 18:56:00 +02:00
Muayyad alsadi
7222fdb6e7 exit if not files 2019-11-07 18:55:49 +02:00
Anass Ahmed
bb7120f3ff Fix stop command runs start instead 2019-10-26 20:45:19 +02:00
Marius Hoch
7ebbe2efc6 Fix KeyErrors encountered with extended services
Docker compose file used:
https://github.com/wikimedia/mediawiki-extensions-Wikibase/blob/master/view/lib/wikibase-tainted-ref/docker-compose.yml
2019-10-25 16:09:38 +02:00
William José Moreno Reyes
29d4cdc9ab Remove unused funtion in setup.py
Signed-off-by: William José Moreno Reyes <williamjmorenor@gmail.com>
2019-10-13 00:31:50 +03:00
Simon Li
a9216c3980 podman volume inspect mountPoint/Mountpoint
podman version 1.6.1 volume inspect outputs Mountpoint instead of mountPoint
2019-10-05 23:44:38 +03:00
Muayyad alsadi
e538852dbe #57: better ps via label 2019-10-05 22:47:04 +03:00
Aric Renzo
b1c2b0222b podman_compose.py 2019-10-05 22:38:50 +03:00
Muayyad alsadi
9e0dd2da9d extends with external file 2019-10-05 22:37:14 +03:00
Marius Hoch
72c1992737 Remove never-shared options. 2019-10-05 22:35:05 +03:00
Marius Hoch
3e2381f040 Support extends
https://docs.docker.com/compose/extends/

Doesn't yet support referring to another file.

Needs Python 3.5+ (for merging dicts using **)
2019-10-05 22:35:05 +03:00
Muayyad alsadi
dee813a4b6 #47: version command 2019-10-04 20:57:07 +03:00
Muayyad alsadi
9684429157 #52: fix how we split commands 2019-10-04 20:36:30 +03:00
Muayyad alsadi
87e7211ade #54: fix ulimits 2019-10-04 20:27:19 +03:00
Mario
72697016f9 Fixed get of ulimit tag, according to docker-compose specification 2019-10-04 20:24:36 +03:00
Marius Hoch
b369073574 Fix podman-compose run command parsing
This got confused with the main command (up, down, …),
thus leading to:

    cmd = self.commands[cmd_name]
TypeError: unhashable type: 'list'
2019-10-01 13:26:38 +03:00
Lorenzo Benvenuti
62f0cc492c Changed -l flag to --label in order to be compatible with Podman 1.0.2.dev 2019-10-01 13:25:01 +03:00
Aric Renzo
c152d28af7 Support for generic container-compose format 2019-09-20 23:33:59 +03:00
Muayyad Alsadi
8e43e69c5b FIX #41: compare original volume name 2019-09-14 00:32:00 +03:00
Muayyad Alsadi
4c07e875a0 Merge branch 'devel' of github.com:containers/podman-compose into devel 2019-09-13 22:25:52 +03:00
Kevin Elliott
751aaa87f6 Add support for devices in a service 2019-09-13 22:25:26 +03:00
Tyler Ramer
243bdb688d Add support for setting container ulimit
- supports `ulimit: host` or other single value
- As well as `ulimit: [nofile=5000, nproc=5000]` array
- As well as `ulimit: {nofile: 5000, nproc: 5000}` dict

Authored-by: Tyler Ramer <tramer@pivotal.io>
2019-09-13 22:25:26 +03:00
Muayyad Alsadi
d9cd0d6186 Merge branch 'master' of github.com:containers/podman-compose into devel 2019-09-13 22:23:22 +03:00
Muayyad Alsadi
ec06da2265 Merge pull request #38 from tylarb/ulimit
Add support for setting container ulimit
2019-09-12 02:00:23 +03:00
Tyler Ramer
2202e7f39b Add support for setting container ulimit
- supports `ulimit: host` or other single value
- As well as `ulimit: [nofile=5000, nproc=5000]` array
- As well as `ulimit: {nofile: 5000, nproc: 5000}` dict

Authored-by: Tyler Ramer <tramer@pivotal.io>
2019-09-11 18:12:29 -04:00
Muayyad Alsadi
f505e499a2 a test showing yaml anchor magic 2019-09-09 00:48:25 +03:00
Muayyad Alsadi
813dc8b149 Merge remote-tracking branch 'origin/master' into devel 2019-09-09 00:18:41 +03:00
Muayyad Alsadi
6f2e5de57c Merge pull request #37 from thenomemac/patch-3
add string check for cmd line args
2019-09-08 20:17:13 +03:00
Josiah Olson
2e4378f7ad add string check for cmd line args 2019-09-08 12:57:49 -04:00
Muayyad Alsadi
2a8d430c92 FIXES #35: now support multiple composer files 2019-09-08 02:20:48 +03:00
Muayyad Alsadi
a512c0cb82 #35: test for multiple -f 2019-09-04 16:12:13 +03:00
141 changed files with 6736 additions and 805 deletions

2
.coveragerc Normal file
View File

@@ -0,0 +1,2 @@
[run]
parallel=True

54
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,54 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
Please make sure it's not a bug in podman (in that case report it to podman)
or your understanding of docker-compose or how rootless containers work (for example, it's normal for rootless container not to be able to listen for port less than 1024 like 80)
please try to reproduce the bug in latest devel branch
**To Reproduce**
Steps to reproduce the behavior:
1. what is the content of the current working directory (ex. `docker-compose.yml`, `.env`, `Dockerfile`, ...etc.)
2. what is the sequence of commands you typed
please use [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) for example give me a small busybox-based compose yaml
**Expected behavior**
A clear and concise description of what you expected to happen.
**Actual behavior**
What is the behavior you actually got and that should not happen.
**Output**
```
$ podman-compose version
using podman version: 3.4.0
podman-compose version 0.1.7dev
podman --version
podman version 3.4.0
$ podman-compose up
...
```
**Environment:**
- OS: Linux / WSL / Mac
- podman version:
- podman compose version: (git hex)
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

41
.github/workflows/pylint.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Pylint
on:
- push
- pull_request
jobs:
lint-black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install psf/black requirements
run: |
sudo apt-get update
sudo apt-get install -y python3 python3-venv
- uses: psf/black@stable
with:
options: "--check --verbose"
version: "~= 23.3"
lint-pylint:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
pip install pylint
- name: Analysing the code with pylint
run: |
python -m compileall podman_compose.py
pylint podman_compose.py
# pylint $(git ls-files '*.py')

39
.github/workflows/pytest.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: PyTest
on:
push:
branches: [ devel ]
pull_request:
branches: [ devel ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install dependencies
run: |
sudo apt update && apt install podman
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
coverage run --source podman_compose -m pytest ./pytests
python -m pytest ./tests
coverage combine
coverage report

32
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,32 @@
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
# It is recommended to specify the latest version of Python
# supported by your project here, or alternatively use
# pre-commit's default_language_version, see
# https://pre-commit.com/#top_level-default_language_version
language_version: python3.10
types: [python]
args: [
"--check", # Don't apply changes automatically
]
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
types: [python]
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
args:
[
"-rn", # Only display messages
"-sn", # Don't display the score
"--rcfile=.pylintrc", # Link to your config file
]

View File

@@ -1,13 +1,18 @@
[MESSAGES CONTROL]
disable=W0614,C0410,C0321,C0111,I0011,C0103
# C0111 missing-docstring: missing-class-docstring, missing-function-docstring, missing-method-docstring, missing-module-docstrin
# consider-using-with: we need it for color formatter pipe
disable=too-many-lines,too-many-branches,too-many-locals,too-many-statements,too-many-arguments,too-many-instance-attributes,fixme,multiple-statements,missing-docstring,line-too-long,consider-using-f-string,consider-using-with,unnecessary-lambda-assignment
# allow _ for ignored variables
# allow generic names like a,b,c and i,j,k,l,m,n and x,y,z
# allow k,v for key/value
# allow e for exceptions, it for iterator
# allow e for exceptions, it for iterator, ix for index
# allow ip for ip address
# allow w,h for width, height
# allow op for operation/operator/opcode
# allow t, t0, t1, t2, and t3 for time
# allow dt for delta time
# allow db for database
# allow ls for list
good-names=_,a,b,c,dt,db,e,f,fn,fd,i,j,k,v,kv,kw,l,m,n,ls,t,t0,t1,t2,t3,w,h,x,y,z,it,op
# allow p for pipe
# allow ex for examples, exists ..etc
good-names=_,a,b,c,dt,db,e,f,fn,fd,i,j,k,v,kv,kw,l,m,n,ls,t,t0,t1,t2,t3,w,h,x,y,z,it,ix,ip,op,p,ex

3
CODE-OF-CONDUCT.md Normal file
View File

@@ -0,0 +1,3 @@
## The Podman Compose Project Community Code of Conduct
The Podman Compose project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).

View File

@@ -1,21 +1,73 @@
# Contributing to podman-compose
## Who can contribute?
- Users that found a bug
- Users that wants to propose new functionalities or enhancements
- Users that want to help other users to troubleshoot their environments
- Developers that want to fix bugs
- Developers that want to implement new functionalities or enhancements
## Branches
Please request your PR to be merged into the `devel` branch.
Changes to the `stable` branch are managed by the repository maintainers.
## Development environment setup
Note: Some steps are OPTIONAL but all are RECOMMENDED.
1. Fork the project repo and clone it
```shell
$ git clone https://github.com/USERNAME/podman-compose.git
$ cd podman-compose
```
1. (OPTIONAL) Create a python virtual environment. Example using [virtualenv wrapper](https://virtualenvwrapper.readthedocs.io/en/latest/):
```shell
mkvirtualenv podman-compose
```
2. Install the project runtime and development requirements
```shell
$ pip install '.[devel]'
```
3. (OPTIONAL) Install `pre-commit` git hook scripts (https://pre-commit.com/#3-install-the-git-hook-scripts)
```shell
$ pre-commit install
```
4. Create a new branch, develop and add tests when possible
5. Run linting & testing before commiting code. Ensure all the hooks are passing.
```shell
$ pre-commit run --all-files
```
6. Run code coverage
```shell
coverage run --source podman_compose -m pytest ./pytests
python -m pytest ./tests
coverage combine
coverage report
coverage html
```
7. Commit your code to your fork's branch.
- Make sure you include a `Signed-off-by` message in your commits. Read [this guide](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) to learn how to sign your commits
- In the commit message reference the Issue ID that your code fixes and a brief description of the changes. Example: `Fixes #516: allow empty network`
7. Open a PR to `containers/podman-compose:devel` and wait for a maintainer to review your work.
## Adding new commands
To add a command you need to add a function that is decorated
with `@cmd_run` passing the compose instance, command name and
description. the wrapped function should accept two arguments
the compose instance and the command-specific arguments (resulted
from python's `argparse` package) inside that command you can
run PodMan like this `compose.podman.run(['inspect', 'something'])`
and inside that function you can access `compose.pods`
and `compose.containers` ...etc.
Here is an example
description. This function must be declared `async` the wrapped
function should accept two arguments the compose instance and
the command-specific arguments (resulted from python's `argparse`
package) inside that command you can run PodMan like this
`await compose.podman.run(['inspect', 'something'])`and inside
that function you can access `compose.pods` and `compose.containers`
...etc. Here is an example
```
@cmd_run(podman_compose, 'build', 'build images defined in the stack')
def compose_build(compose, args):
compose.podman.run(['build', 'something'])
async def compose_build(compose, args):
await compose.podman.run(['build', 'something'])
```
## Command arguments parsing
@@ -46,29 +98,25 @@ do something like:
```
@cmd_run(podman_compose, 'up', 'up desc')
def compose_up(compose, args):
compose.commands['down'](compose, args)
async def compose_up(compose, args):
await compose.commands['down'](compose, args)
# or
compose.commands['down'](argparse.Namespace(foo=123))
await compose.commands['down'](argparse.Namespace(foo=123))
```
## Missing Commands (help needed)
```
bundle Generate a Docker bundle from the Compose file
config Validate and view the Compose file
create Create services
events Receive real time events from containers
exec Execute a command in a running container
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
top Display the running processes
unpause Unpause services
version Show the Docker-Compose version information
```

View File

@@ -1,32 +1,55 @@
# Podman Compose
## [![Pylint Test: ](https://github.com/containers/podman-compose/actions/workflows/pylint.yml/badge.svg)](https://github.com/containers/podman-compose/actions/workflows/pylint.yml) [![Unit tests PyTest](https://github.com/containers/podman-compose/actions/workflows/pytest.yml/badge.svg)](https://github.com/containers/podman-compose/actions/workflows/pytest.yml)
An implementation of `docker-compose` with [podman](https://podman.io/) backend.
The main objective of this project is to be able to run `docker-compose.yml` unmodified and rootless.
This project is aimed to provide drop-in replacement for `docker-compose`,
and it's very useful for certain cases because:
- can run rootless
- only depend on `podman` and Python3 and [PyYAML](https://pyyaml.org/)
- no daemon, no setup.
- can be used by developers to run single-machine containerized stacks using single familiar YAML file
An implementation of [Compose Spec](https://compose-spec.io/) with [Podman](https://podman.io/) backend.
This project focuses on:
* rootless
* daemon-less process model, we directly execute podman, no running daemon.
This project only depends on:
* `podman`
* [podman dnsname plugin](https://github.com/containers/dnsname): It is usually found in the `podman-plugins` or `podman-dnsname` distro packages, those packages are not pulled by default and you need to install them. This allows containers to be able to resolve each other if they are on the same CNI network.
* Python3
* [PyYAML](https://pyyaml.org/)
* [python-dotenv](https://pypi.org/project/python-dotenv/)
And it's formed as a single Python file script that you can drop into your PATH and run.
## References:
* [spec.md](https://github.com/compose-spec/compose-spec/blob/master/spec.md)
* [docker-compose compose-file-v3](https://docs.docker.com/compose/compose-file/compose-file-v3/)
* [docker-compose compose-file-v2](https://docs.docker.com/compose/compose-file/compose-file-v2/)
## Alternatives
As in [this article](https://fedoramagazine.org/use-docker-compose-with-podman-to-orchestrate-containers-on-fedora/) you can setup a `podman.socket` and use unmodified `docker-compose` that talks to that socket but in this case you lose the process-model (ex. `docker-compose build` will send a possibly large context tarball to the daemon)
For production-like single-machine containerized environment consider
- [k3s](https://k3s.io) | [k3s github](https://github.com/rancher/k3s)
- [MiniKube](https://minikube.sigs.k8s.io/)
- [MiniShift](https://www.okd.io/minishift/)
For the real thing (multi-node clusters) check any production
OpenShift/Kubernetes distribution like [OKD](https://www.okd.io/minishift/).
OpenShift/Kubernetes distribution like [OKD](https://www.okd.io/).
## NOTE
## Versions
If you have legacy version of `podman` (before 3.1.0) you might need to stick with legacy `podman-compose` `0.1.x` branch.
The legacy branch 0.1.x uses mappings and workarounds to compensate for rootless limitations.
Modern podman versions (>=3.4) do not have those limitations, and thus you can use latest and stable 1.x branch.
If you are upgrading from `podman-compose` version `0.1.x` then we no longer have global option `-t` to set mapping type
like `hostnet`. If you desire that behavior, pass it the standard way like `network_mode: host` in the YAML.
This project is still underdevelopment.
## Installation
Install latest stable version from PyPI:
Install the latest stable version from PyPI:
```
pip3 install podman-compose
@@ -40,23 +63,18 @@ Or latest development version from GitHub:
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz
```
or
or install from Fedora (starting from f31) repositories:
```
curl -o /usr/local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/devel/podman_compose.py
chmod +x /usr/local/bin/podman-compose
```
or
```
curl -o ~/.local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/devel/podman_compose.py
chmod +x ~/.local/bin/podman-compose
sudo dnf install podman-compose
```
## Basic Usage
We have included fully functional sample stacks inside `examples/` directory.
You can get more examples from [awesome-compose](https://github.com/docker/awesome-compose).
A quick example would be
@@ -77,19 +95,21 @@ which have
- a django tasks
When testing the `AWX3` example, if you got errors just wait for db migrations to end.
When testing the `AWX3` example, if you got errors, just wait for db migrations to end.
There is also AWX 17.1.0
## Tests
Inside `tests/` directory we have many useless docker-compose stacks
that are meant to test as much cases as we can to make sure we are compatible
that are meant to test as many cases as we can to make sure we are compatible
## How it works
### Unit tests with pytest
run a pytest with following command
The default mapping `1podfw` creates a single pod and attach all containers to
its network namespace so that all containers talk via localhost.
For more information see [docs/Mappings.md](docs/Mappings.md).
```shell
python -m pytest pytests
```
If you are running as root, you might use identity mapping.
# Contributing guide
If you are a user or a developer and want to contribute please check the [CONTRIBUTING](CONTRIBUTING.md) section

3
SECURITY.md Normal file
View File

@@ -0,0 +1,3 @@
## Security and Disclosure Information Policy for the Podman Compose Project
The Podman Compose Project follows the [Security and Disclosure Information Policy](https://github.com/containers/common/blob/master/SECURITY.md) for the Containers Projects.

View File

@@ -0,0 +1,411 @@
# Naming convention:
# * _camelCase for function names
# * snake_case for variable names
# all functions will return 0 if they successfully complete the argument
# (or establish there is no need or no way to complete), and something
# other than 0 if that's not the case
# complete arguments to global options
_completeGlobalOptArgs() {
# arguments to options that take paths as arguments: complete paths
for el in ${path_arg_global_opts}; do
if [[ ${prev} == ${el} ]]; then
COMPREPLY=( $(compgen -f -- ${cur}) )
return 0
fi
done
# arguments to options that take generic arguments: don't complete
for el in ${generic_arg_global_opts}; do
if [[ ${prev} == ${el} ]]; then
return 0
fi
done
return 1
}
# complete root subcommands and options
_completeRoot() {
# if we're completing an option
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${global_opts}" -- ${cur}) )
return 0
fi
# complete root commands
COMPREPLY=( $(compgen -W "${root_commands}" -- ${cur}) )
return 0
}
# complete names of Compose services
_completeServiceNames() {
# ideally we should complete service names,
# but parsing the compose spec file in the
# completion script is quite complex
return 0
}
# complete commands to run inside containers
_completeCommand() {
# we would need to complete commands to run inside
# a container
return 0
}
# complete the arguments for `podman-compose up` and return 0
_completeUpArgs() {
up_opts="${help_opts} -d --detach --no-color --quiet-pull --no-deps --force-recreate --always-recreate-deps --no-recreate --no-build --no-start --build --abort-on-container-exit -t --timeout -V --renew-anon-volumes --remove-orphans --scale --exit-code-from --pull --pull-always --build-arg --no-cache"
if [[ ${prev} == "--scale" || ${prev} == "-t" || ${prev} == "--timeout" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${up_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose exec` and return 0
_completeExecArgs() {
exec_opts="${help_opts} -d --detach --privileged -u --user -T --index -e --env -w --workdir"
if [[ ${prev} == "-u" || ${prev} == "--user" || ${prev} == "--index" || ${prev} == "-e" || ${prev} == "--env" || ${prev} == "-w" || ${prev} == "--workdir" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${exec_opts}" -- ${cur}) )
return 0
elif [[ ${comp_cword_adj} -eq 2 ]]; then
# complete service name
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
elif [[ ${comp_cword_adj} -eq 3 ]]; then
_completeCommand
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose down` and return 0
_completeDownArgs() {
down_opts="${help_opts} -v --volumes -t --timeout --remove-orphans"
if [[ ${prev} == "-t" || ${prev} == "--timeout" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${down_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose build` and return 0
_completeBuildArgs() {
build_opts="${help_opts} --pull --pull-always --build-arg --no-cache"
if [[ ${prev} == "--build-arg" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${build_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose logs` and return 0
_completeLogsArgs() {
logs_opts="${help_opts} -f --follow -l --latest -n --names --since -t --timestamps --tail --until"
if [[ ${prev} == "--since" || ${prev} == "--tail" || ${prev} == "--until" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${logs_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose ps` and return 0
_completePsArgs() {
ps_opts="${help_opts} -q --quiet"
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${ps_opts}" -- ${cur}) )
return 0
else
return 0
fi
}
# complete the arguments for `podman-compose pull` and return 0
_completePullArgs() {
pull_opts="${help_opts} --force-local"
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${pull_opts}" -- ${cur}) )
return 0
else
return 0
fi
}
# complete the arguments for `podman-compose push` and return 0
_completePushArgs() {
push_opts="${help_opts} --ignore-push-failures"
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${push_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose restart` and return 0
_completeRestartArgs() {
restart_opts="${help_opts} -t --timeout"
if [[ ${prev} == "-t" || ${prev} == "--timeout" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${restart_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose stop` and return 0
_completeStopArgs() {
stop_opts="${help_opts} -t --timeout"
if [[ ${prev} == "-t" || ${prev} == "--timeout" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${stop_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose start` and return 0
_completeStartArgs() {
start_opts="${help_opts}"
if [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${start_opts}" -- ${cur}) )
return 0
else
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
return 0
fi
}
# complete the arguments for `podman-compose run` and return 0
_completeRunArgs() {
run_opts="${help_opts} -d --detach --privileged -u --user -T --index -e --env -w --workdir"
if [[ ${prev} == "-u" || ${prev} == "--user" || ${prev} == "--index" || ${prev} == "-e" || ${prev} == "--env" || ${prev} == "-w" || ${prev} == "--workdir" ]]; then
return 0
elif [[ ${cur} == -* ]]; then
COMPREPLY=( $(compgen -W "${run_opts}" -- ${cur}) )
return 0
elif [[ ${comp_cword_adj} -eq 2 ]]; then
# complete service name
_completeServiceNames
if [[ $? -eq 0 ]]; then
return 0
fi
elif [[ ${comp_cword_adj} -eq 3 ]]; then
_completeCommand
if [[ $? -eq 0 ]]; then
return 0
fi
fi
}
_podmanCompose() {
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
root_commands="help version pull push build up down ps run exec start stop restart logs"
# options to output help text (used as global and subcommand options)
help_opts="-h --help"
# global options that don't take additional arguments
basic_global_opts="${help_opts} -v --no-ansi --no-cleanup --dry-run"
# global options that take paths as arguments
path_arg_global_opts="-f --file --podman-path"
path_arg_global_opts_array=($arg_global_opts)
# global options that take arguments that are not files
generic_arg_global_opts="-p --project-name --podman-path --podman-args --podman-pull-args --podman-push-args --podman-build-args --podman-inspect-args --podman-run-args --podman-start-args --podman-stop-args --podman-rm-args --podman-volume-args"
generic_arg_global_opts_array=($generic_arg_global_opts)
# all global options that take arguments
arg_global_opts="${path_arg_global_opts} ${generic_arg_global_opts}"
arg_global_opts_array=($arg_global_opts)
# all global options
global_opts="${basic_global_opts} ${arg_global_opts}"
chosen_root_command=""
_completeGlobalOptArgs
if [[ $? -eq 0 ]]; then
return 0
fi
# computing comp_cword_adj, which thruthfully tells us how deep in the subcommands tree we are
# additionally, set the chosen_root_command if possible
comp_cword_adj=${COMP_CWORD}
if [[ ${COMP_CWORD} -ge 2 ]]; then
skip_next="no"
for el in ${COMP_WORDS[@]}; do
# if the user has asked for help text there's no need to complete further
if [[ ${el} == "-h" || ${el} == "--help" ]]; then
return 0
fi
if [[ ${skip_next} == "yes" ]]; then
let "comp_cword_adj--"
skip_next="no"
continue
fi
if [[ ${el} == -* && ${el} != ${cur} ]]; then
let "comp_cword_adj--"
for opt in ${arg_global_opts_array[@]}; do
if [[ ${el} == ${opt} ]]; then
skip_next="yes"
fi
done
elif [[ ${el} != ${cur} && ${el} != ${COMP_WORDS[0]} && ${chosen_root_command} == "" ]]; then
chosen_root_command=${el}
fi
done
fi
if [[ ${comp_cword_adj} -eq 1 ]]; then
_completeRoot
# Given that we check the value of comp_cword_adj outside
# of it, at the moment _completeRoot should always return
# 0, this is just here in case changes are made. The same
# will apply to similar functions below
if [[ $? -eq 0 ]]; then
return 0
fi
fi
case $chosen_root_command in
up)
_completeUpArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
down)
_completeDownArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
exec)
_completeExecArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
build)
_completeBuildArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
logs)
_completeLogsArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
ps)
_completePsArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
pull)
_completePullArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
push)
_completePushArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
restart)
_completeRestartArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
start)
_completeStartArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
stop)
_completeStopArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
run)
_completeRunArgs
if [[ $? -eq 0 ]]; then
return 0
fi
;;
esac
}
complete -F _podmanCompose podman-compose

37
examples/awx17/README.md Normal file
View File

@@ -0,0 +1,37 @@
# AWX Compose
the directory roles is taken from [here](https://github.com/ansible/awx/tree/17.1.0/installer/roles/local_docker)
also look at https://github.com/ansible/awx/tree/17.1.0/tools/docker-compose
```
mkdir deploy awx17
ansible localhost \
-e host_port=8080 \
-e awx_secret_key='awx,secret.123' \
-e secret_key='awx,secret.123' \
-e admin_user='admin' \
-e admin_password='admin' \
-e pg_password='awx,123.' \
-e pg_username='awx' \
-e pg_database='awx' \
-e pg_port='5432' \
-e redis_image="docker.io/library/redis:6-alpine" \
-e postgres_data_dir="./data/pg" \
-e compose_start_containers=false \
-e dockerhub_base='docker.io/ansible' \
-e awx_image='docker.io/ansible/awx' \
-e awx_version='17.1.0' \
-e dockerhub_version='17.1.0' \
-e docker_deploy_base_path=$PWD/deploy \
-e docker_compose_dir=$PWD/awx17 \
-e awx_task_hostname=awx \
-e awx_web_hostname=awxweb \
-m include_role -a name=local_docker
cp awx17/docker-compose.yml awx17/docker-compose.yml.orig
sed -i -re "s#- \"$PWD/awx17/(.*):/#- \"./\1:/#" awx17/docker-compose.yml
cd awx17
podman-compose run --rm --service-ports task awx-manage migrate --no-input
podman-compose up -d
```

View File

@@ -0,0 +1,11 @@
---
dockerhub_version: "{{ lookup('file', playbook_dir + '/../VERSION') }}"
awx_image: "awx"
redis_image: "redis"
postgresql_version: "12"
postgresql_image: "postgres:{{postgresql_version}}"
compose_start_containers: true
upgrade_postgres: false

View File

@@ -0,0 +1,74 @@
---
- name: Create {{ docker_compose_dir }} directory
file:
path: "{{ docker_compose_dir }}"
state: directory
- name: Create Redis socket directory
file:
path: "{{ docker_compose_dir }}/redis_socket"
state: directory
mode: 0777
- name: Create Docker Compose Configuration
template:
src: "{{ item.file }}.j2"
dest: "{{ docker_compose_dir }}/{{ item.file }}"
mode: "{{ item.mode }}"
loop:
- file: environment.sh
mode: "0600"
- file: credentials.py
mode: "0600"
- file: docker-compose.yml
mode: "0600"
- file: nginx.conf
mode: "0600"
- file: redis.conf
mode: "0664"
register: awx_compose_config
- name: Render SECRET_KEY file
copy:
content: "{{ secret_key }}"
dest: "{{ docker_compose_dir }}/SECRET_KEY"
mode: 0600
register: awx_secret_key
- block:
- name: Remove AWX containers before migrating postgres so that the old postgres container does not get used
docker_compose:
project_src: "{{ docker_compose_dir }}"
state: absent
ignore_errors: true
- name: Run migrations in task container
shell: docker-compose run --rm --service-ports task awx-manage migrate --no-input
args:
chdir: "{{ docker_compose_dir }}"
- name: Start the containers
docker_compose:
project_src: "{{ docker_compose_dir }}"
restarted: "{{ awx_compose_config is changed or awx_secret_key is changed }}"
register: awx_compose_start
- name: Update CA trust in awx_web container
command: docker exec awx_web '/usr/bin/update-ca-trust'
when: awx_compose_config.changed or awx_compose_start.changed
- name: Update CA trust in awx_task container
command: docker exec awx_task '/usr/bin/update-ca-trust'
when: awx_compose_config.changed or awx_compose_start.changed
- name: Wait for launch script to create user
wait_for:
timeout: 10
delegate_to: localhost
- name: Create Preload data
command: docker exec awx_task bash -c "/usr/bin/awx-manage create_preload_data"
when: create_preload_data|bool
register: cdo
changed_when: "'added' in cdo.stdout"
when: compose_start_containers|bool

View File

@@ -0,0 +1,15 @@
---
- name: Generate broadcast websocket secret
set_fact:
broadcast_websocket_secret: "{{ lookup('password', '/dev/null length=128') }}"
run_once: true
no_log: true
when: broadcast_websocket_secret is not defined
- import_tasks: upgrade_postgres.yml
when:
- postgres_data_dir is defined
- pg_hostname is not defined
- import_tasks: set_image.yml
- import_tasks: compose.yml

View File

@@ -0,0 +1,46 @@
---
- name: Manage AWX Container Images
block:
- name: Export Docker awx image if it isn't local and there isn't a registry defined
docker_image:
name: "{{ awx_image }}"
tag: "{{ awx_version }}"
archive_path: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_image }}_{{ awx_version }}.tar"
when: inventory_hostname != "localhost" and docker_registry is not defined
delegate_to: localhost
- name: Set docker base path
set_fact:
docker_deploy_base_path: "{{ awx_base_path|default('/tmp') }}/docker_deploy"
when: ansible_connection != "local" and docker_registry is not defined
- name: Ensure directory exists
file:
path: "{{ docker_deploy_base_path }}"
state: directory
when: ansible_connection != "local" and docker_registry is not defined
- name: Copy awx image to docker execution
copy:
src: "{{ awx_local_base_config_path|default('/tmp') }}/{{ awx_image }}_{{ awx_version }}.tar"
dest: "{{ docker_deploy_base_path }}/{{ awx_image }}_{{ awx_version }}.tar"
when: ansible_connection != "local" and docker_registry is not defined
- name: Load awx image
docker_image:
name: "{{ awx_image }}"
tag: "{{ awx_version }}"
load_path: "{{ docker_deploy_base_path }}/{{ awx_image }}_{{ awx_version }}.tar"
timeout: 300
when: ansible_connection != "local" and docker_registry is not defined
- name: Set full image path for local install
set_fact:
awx_docker_actual_image: "{{ awx_image }}:{{ awx_version }}"
when: docker_registry is not defined
when: dockerhub_base is not defined
- name: Set DockerHub Image Paths
set_fact:
awx_docker_actual_image: "{{ dockerhub_base }}/awx:{{ dockerhub_version }}"
when: dockerhub_base is defined

View File

@@ -0,0 +1,64 @@
---
- name: Create {{ postgres_data_dir }} directory
file:
path: "{{ postgres_data_dir }}"
state: directory
- name: Get full path of postgres data dir
shell: "echo {{ postgres_data_dir }}"
register: fq_postgres_data_dir
- name: Register temporary docker container
set_fact:
container_command: "docker run --rm -v '{{ fq_postgres_data_dir.stdout }}:/var/lib/postgresql' centos:8 bash -c "
- name: Check for existing Postgres data (run from inside the container for access to file)
shell:
cmd: |
{{ container_command }} "[[ -f /var/lib/postgresql/10/data/PG_VERSION ]] && echo 'exists'"
register: pg_version_file
ignore_errors: true
- name: Record Postgres version
shell: |
{{ container_command }} "cat /var/lib/postgresql/10/data/PG_VERSION"
register: old_pg_version
when: pg_version_file is defined and pg_version_file.stdout == 'exists'
- name: Determine whether to upgrade postgres
set_fact:
upgrade_postgres: "{{ old_pg_version.stdout == '10' }}"
when: old_pg_version.changed
- name: Set up new postgres paths pre-upgrade
shell: |
{{ container_command }} "mkdir -p /var/lib/postgresql/12/data/"
when: upgrade_postgres | bool
- name: Stop AWX before upgrading postgres
docker_compose:
project_src: "{{ docker_compose_dir }}"
stopped: true
when: upgrade_postgres | bool
- name: Upgrade Postgres
shell: |
docker run --rm \
-v {{ postgres_data_dir }}/10/data:/var/lib/postgresql/10/data \
-v {{ postgres_data_dir }}/12/data:/var/lib/postgresql/12/data \
-e PGUSER={{ pg_username }} -e POSTGRES_INITDB_ARGS="-U {{ pg_username }}" \
tianon/postgres-upgrade:10-to-12 --username={{ pg_username }}
when: upgrade_postgres | bool
- name: Copy old pg_hba.conf
shell: |
{{ container_command }} "cp /var/lib/postgresql/10/data/pg_hba.conf /var/lib/postgresql/12/data/pg_hba.conf"
when: upgrade_postgres | bool
- name: Remove old data directory
shell: |
{{ container_command }} "rm -rf /var/lib/postgresql/10/data"
when:
- upgrade_postgres | bool
- compose_start_containers|bool

View File

@@ -0,0 +1,13 @@
DATABASES = {
'default': {
'ATOMIC_REQUESTS': True,
'ENGINE': 'django.db.backends.postgresql',
'NAME': "{{ pg_database }}",
'USER': "{{ pg_username }}",
'PASSWORD': "{{ pg_password }}",
'HOST': "{{ pg_hostname | default('postgres') }}",
'PORT': "{{ pg_port }}",
}
}
BROADCAST_WEBSOCKET_SECRET = "{{ broadcast_websocket_secret | b64encode }}"

View File

@@ -0,0 +1,208 @@
#jinja2: lstrip_blocks: True
version: '2'
services:
web:
image: {{ awx_docker_actual_image }}
container_name: awx_web
depends_on:
- redis
{% if pg_hostname is not defined %}
- postgres
{% endif %}
{% if (host_port is defined) or (host_port_ssl is defined) %}
ports:
{% if (host_port_ssl is defined) and (ssl_certificate is defined) %}
- "{{ host_port_ssl }}:8053"
{% endif %}
{% if host_port is defined %}
- "{{ host_port }}:8052"
{% endif %}
{% endif %}
hostname: {{ awx_web_hostname }}
user: root
restart: unless-stopped
{% if (awx_web_container_labels is defined) and (',' in awx_web_container_labels) %}
{% set awx_web_container_labels_list = awx_web_container_labels.split(',') %}
labels:
{% for awx_web_container_label in awx_web_container_labels_list %}
- {{ awx_web_container_label }}
{% endfor %}
{% elif awx_web_container_labels is defined %}
labels:
- {{ awx_web_container_labels }}
{% endif %}
volumes:
- supervisor-socket:/var/run/supervisor
- rsyslog-socket:/var/run/awx-rsyslog/
- rsyslog-config:/var/lib/awx/rsyslog/
- "{{ docker_compose_dir }}/SECRET_KEY:/etc/tower/SECRET_KEY"
- "{{ docker_compose_dir }}/environment.sh:/etc/tower/conf.d/environment.sh"
- "{{ docker_compose_dir }}/credentials.py:/etc/tower/conf.d/credentials.py"
- "{{ docker_compose_dir }}/nginx.conf:/etc/nginx/nginx.conf:ro"
- "{{ docker_compose_dir }}/redis_socket:/var/run/redis/:rw"
{% if project_data_dir is defined %}
- "{{ project_data_dir +':/var/lib/awx/projects:rw' }}"
{% endif %}
{% if custom_venv_dir is defined %}
- "{{ custom_venv_dir +':'+ custom_venv_dir +':rw' }}"
{% endif %}
{% if ca_trust_dir is defined %}
- "{{ ca_trust_dir +':/etc/pki/ca-trust/source/anchors:ro' }}"
{% endif %}
{% if (ssl_certificate is defined) and (ssl_certificate_key is defined) %}
- "{{ ssl_certificate +':/etc/nginx/awxweb.pem:ro' }}"
- "{{ ssl_certificate_key +':/etc/nginx/awxweb_key.pem:ro' }}"
{% elif (ssl_certificate is defined) and (ssl_certificate_key is not defined) %}
- "{{ ssl_certificate +':/etc/nginx/awxweb.pem:ro' }}"
{% endif %}
{% if (awx_container_search_domains is defined) and (',' in awx_container_search_domains) %}
{% set awx_container_search_domains_list = awx_container_search_domains.split(',') %}
dns_search:
{% for awx_container_search_domain in awx_container_search_domains_list %}
- {{ awx_container_search_domain }}
{% endfor %}
{% elif awx_container_search_domains is defined %}
dns_search: "{{ awx_container_search_domains }}"
{% endif %}
{% if (awx_alternate_dns_servers is defined) and (',' in awx_alternate_dns_servers) %}
{% set awx_alternate_dns_servers_list = awx_alternate_dns_servers.split(',') %}
dns:
{% for awx_alternate_dns_server in awx_alternate_dns_servers_list %}
- {{ awx_alternate_dns_server }}
{% endfor %}
{% elif awx_alternate_dns_servers is defined %}
dns: "{{ awx_alternate_dns_servers }}"
{% endif %}
{% if (docker_compose_extra_hosts is defined) and (':' in docker_compose_extra_hosts) %}
{% set docker_compose_extra_hosts_list = docker_compose_extra_hosts.split(',') %}
extra_hosts:
{% for docker_compose_extra_host in docker_compose_extra_hosts_list %}
- "{{ docker_compose_extra_host }}"
{% endfor %}
{% endif %}
environment:
http_proxy: {{ http_proxy | default('') }}
https_proxy: {{ https_proxy | default('') }}
no_proxy: {{ no_proxy | default('') }}
{% if docker_logger is defined %}
logging:
driver: {{ docker_logger }}
{% endif %}
task:
image: {{ awx_docker_actual_image }}
container_name: awx_task
depends_on:
- redis
- web
{% if pg_hostname is not defined %}
- postgres
{% endif %}
command: /usr/bin/launch_awx_task.sh
hostname: {{ awx_task_hostname }}
user: root
restart: unless-stopped
volumes:
- supervisor-socket:/var/run/supervisor
- rsyslog-socket:/var/run/awx-rsyslog/
- rsyslog-config:/var/lib/awx/rsyslog/
- "{{ docker_compose_dir }}/SECRET_KEY:/etc/tower/SECRET_KEY"
- "{{ docker_compose_dir }}/environment.sh:/etc/tower/conf.d/environment.sh"
- "{{ docker_compose_dir }}/credentials.py:/etc/tower/conf.d/credentials.py"
- "{{ docker_compose_dir }}/redis_socket:/var/run/redis/:rw"
{% if project_data_dir is defined %}
- "{{ project_data_dir +':/var/lib/awx/projects:rw' }}"
{% endif %}
{% if custom_venv_dir is defined %}
- "{{ custom_venv_dir +':'+ custom_venv_dir +':rw' }}"
{% endif %}
{% if ca_trust_dir is defined %}
- "{{ ca_trust_dir +':/etc/pki/ca-trust/source/anchors:ro' }}"
{% endif %}
{% if ssl_certificate is defined %}
- "{{ ssl_certificate +':/etc/nginx/awxweb.pem:ro' }}"
{% endif %}
{% if (awx_container_search_domains is defined) and (',' in awx_container_search_domains) %}
{% set awx_container_search_domains_list = awx_container_search_domains.split(',') %}
dns_search:
{% for awx_container_search_domain in awx_container_search_domains_list %}
- {{ awx_container_search_domain }}
{% endfor %}
{% elif awx_container_search_domains is defined %}
dns_search: "{{ awx_container_search_domains }}"
{% endif %}
{% if (awx_alternate_dns_servers is defined) and (',' in awx_alternate_dns_servers) %}
{% set awx_alternate_dns_servers_list = awx_alternate_dns_servers.split(',') %}
dns:
{% for awx_alternate_dns_server in awx_alternate_dns_servers_list %}
- {{ awx_alternate_dns_server }}
{% endfor %}
{% elif awx_alternate_dns_servers is defined %}
dns: "{{ awx_alternate_dns_servers }}"
{% endif %}
{% if (docker_compose_extra_hosts is defined) and (':' in docker_compose_extra_hosts) %}
{% set docker_compose_extra_hosts_list = docker_compose_extra_hosts.split(',') %}
extra_hosts:
{% for docker_compose_extra_host in docker_compose_extra_hosts_list %}
- "{{ docker_compose_extra_host }}"
{% endfor %}
{% endif %}
environment:
AWX_SKIP_MIGRATIONS: "1"
http_proxy: {{ http_proxy | default('') }}
https_proxy: {{ https_proxy | default('') }}
no_proxy: {{ no_proxy | default('') }}
SUPERVISOR_WEB_CONFIG_PATH: '/etc/supervisord.conf'
redis:
image: {{ redis_image }}
container_name: awx_redis
restart: unless-stopped
environment:
http_proxy: {{ http_proxy | default('') }}
https_proxy: {{ https_proxy | default('') }}
no_proxy: {{ no_proxy | default('') }}
command: ["/usr/local/etc/redis/redis.conf"]
volumes:
- "{{ docker_compose_dir }}/redis.conf:/usr/local/etc/redis/redis.conf:ro"
- "{{ docker_compose_dir }}/redis_socket:/var/run/redis/:rw"
{% if docker_logger is defined %}
logging:
driver: {{ docker_logger }}
{% endif %}
{% if pg_hostname is not defined %}
postgres:
image: {{ postgresql_image }}
container_name: awx_postgres
restart: unless-stopped
volumes:
- "{{ postgres_data_dir }}/12/data/:/var/lib/postgresql/data:Z"
environment:
POSTGRES_USER: {{ pg_username }}
POSTGRES_PASSWORD: {{ pg_password }}
POSTGRES_DB: {{ pg_database }}
http_proxy: {{ http_proxy | default('') }}
https_proxy: {{ https_proxy | default('') }}
no_proxy: {{ no_proxy | default('') }}
{% if docker_logger is defined %}
logging:
driver: {{ docker_logger }}
{% endif %}
{% endif %}
{% if docker_compose_subnet is defined %}
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: {{ docker_compose_subnet }}
{% endif %}
volumes:
supervisor-socket:
rsyslog-socket:
rsyslog-config:

View File

@@ -0,0 +1,10 @@
DATABASE_USER={{ pg_username|quote }}
DATABASE_NAME={{ pg_database|quote }}
DATABASE_HOST={{ pg_hostname|default('postgres')|quote }}
DATABASE_PORT={{ pg_port|default('5432')|quote }}
DATABASE_PASSWORD={{ pg_password|default('awxpass')|quote }}
{% if pg_admin_password is defined %}
DATABASE_ADMIN_PASSWORD={{ pg_admin_password|quote }}
{% endif %}
AWX_ADMIN_USER={{ admin_user|quote }}
AWX_ADMIN_PASSWORD={{ admin_password|quote }}

View File

@@ -0,0 +1,122 @@
#user awx;
worker_processes 1;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
sendfile on;
#tcp_nopush on;
#gzip on;
upstream uwsgi {
server 127.0.0.1:8050;
}
upstream daphne {
server 127.0.0.1:8051;
}
{% if ssl_certificate is defined %}
server {
listen 8052 default_server;
server_name _;
# Redirect all HTTP links to the matching HTTPS page
return 301 https://$host$request_uri;
}
{%endif %}
server {
{% if (ssl_certificate is defined) and (ssl_certificate_key is defined) %}
listen 8053 ssl;
ssl_certificate /etc/nginx/awxweb.pem;
ssl_certificate_key /etc/nginx/awxweb_key.pem;
{% elif (ssl_certificate is defined) and (ssl_certificate_key is not defined) %}
listen 8053 ssl;
ssl_certificate /etc/nginx/awxweb.pem;
ssl_certificate_key /etc/nginx/awxweb.pem;
{% else %}
listen 8052 default_server;
{% endif %}
# If you have a domain name, this is where to add it
server_name _;
keepalive_timeout 65;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# Protect against click-jacking https://www.owasp.org/index.php/Testing_for_Clickjacking_(OTG-CLIENT-009)
add_header X-Frame-Options "DENY";
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
location /static/ {
alias /var/lib/awx/public/static/;
}
location /favicon.ico { alias /var/lib/awx/public/static/favicon.ico; }
location /websocket {
# Pass request to the upstream alias
proxy_pass http://daphne;
# Require http version 1.1 to allow for upgrade requests
proxy_http_version 1.1;
# We want proxy_buffering off for proxying to websockets.
proxy_buffering off;
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if you use HTTPS:
proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client for the sake of redirects
proxy_set_header Host $http_host;
# We've set the Host header, so we don't need Nginx to muddle
# about with redirects
proxy_redirect off;
# Depending on the request value, set the Upgrade and
# connection headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location / {
# Add trailing / if missing
rewrite ^(.*)$http_host(.*[^/])$ $1$http_host$2/ permanent;
uwsgi_read_timeout 120s;
uwsgi_pass uwsgi;
include /etc/nginx/uwsgi_params;
{%- if extra_nginx_include is defined %}
include {{ extra_nginx_include }};
{%- endif %}
proxy_set_header X-Forwarded-Port 443;
uwsgi_param HTTP_X_FORWARDED_PORT 443;
}
}
}

View File

@@ -0,0 +1,4 @@
unixsocket /var/run/redis/redis.sock
unixsocketperm 660
port 0
bind 127.0.0.1

View File

@@ -0,0 +1,17 @@
# Azure Vote Example
This example have two containers:
* backend: `redis` used as storage
* frontend: having supervisord, nginx, uwsgi/python
```
echo "HOST_PORT=8080" > .env
podman-compose up
```
after typing the commands above open your browser on the host port you picked above like
[http://localhost:8080/](http://localhost:8080/)

View File

@@ -0,0 +1,16 @@
---
# from https://github.com/Azure-Samples/azure-voting-app-redis/blob/master/docker-compose.yaml
version: '3'
services:
azure-vote-back:
image: mcr.microsoft.com/oss/bitnami/redis:6.0.8
container_name: azure-vote-back
environment:
ALLOW_EMPTY_PASSWORD: "yes"
azure-vote-front:
image: mcr.microsoft.com/azuredocs/azure-vote-front:v1
environment:
REDIS: azure-vote-back
ports:
- "${HOST_PORT:-8080}:80"

31
examples/echo/README.md Normal file
View File

@@ -0,0 +1,31 @@
# Echo Service example
```
podman-compose up
```
Test the service with `curl like this`
```
$ curl -X POST -d "foobar" http://localhost:8080/; echo
CLIENT VALUES:
client_address=10.89.31.2
command=POST
real path=/
query=nil
request_version=1.1
request_uri=http://localhost:8080/
SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001
HEADERS RECEIVED:
accept=*/*
content-length=6
content-type=application/x-www-form-urlencoded
host=localhost:8080
user-agent=curl/7.76.1
BODY:
foobar
```

View File

@@ -0,0 +1,8 @@
---
version: '3'
services:
web:
image: k8s.gcr.io/echoserver:1.4
ports:
- "${HOST_PORT:-8080}:8080"

View File

@@ -0,0 +1,12 @@
# GCR Hello App Redis
A 6-node redis cluster using [Bitnami](https://github.com/bitnami/bitnami-docker-redis-cluster)
with a [simple hit counter](https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/tree/main/hello-app-redis) that persists on that redis cluster
```
podman-compose up
```
then open your browser on [http://localhost:8080/](http://localhost:8080/)

View File

@@ -0,0 +1,67 @@
---
version: '3'
volumes:
redis-node1-data:
redis-node2-data:
redis-node3-data:
redis-node4-data:
redis-node5-data:
redis-data:
services:
web:
image: gcr.io/google-samples/hello-app-redis:1.0
depends_on:
- redis-cluster
ports:
- "${HOST_PORT:-8080}:8080"
redis-node1:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-node1-data:/bitnami/redis/data
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
redis-node2:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-node2-data:/bitnami/redis/data
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
redis-node3:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-node3-data:/bitnami/redis/data
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
redis-node4:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-node4-data:/bitnami/redis/data
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
redis-node5:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-node5-data:/bitnami/redis/data
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
redis-cluster:
image: docker.io/bitnami/redis-cluster:6.2
volumes:
- redis-data:/bitnami/redis/data
depends_on:
- redis-node1
- redis-node2
- redis-node3
- redis-node4
- redis-node5
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_NODES=redis-node1 redis-node2 redis-node3 redis-node4 redis-node5 redis-cluster
- REDIS_CLUSTER_CREATOR=yes

View File

@@ -0,0 +1,10 @@
# GCR Hello App
A small ~2MB image, type
```
podman-compose up
```
then open your browser on [http://localhost:8080/](http://localhost:8080/)

View File

@@ -0,0 +1,8 @@
---
version: '3'
services:
web:
image: gcr.io/google-samples/hello-app:1.0
ports:
- "${HOST_PORT:-8080}:8080"

View File

@@ -0,0 +1,12 @@
FROM python:3.9-alpine
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "-m", "app.web" ]
EXPOSE 8080

View File

@@ -0,0 +1,8 @@
# Simple Python Demo
## A Redis counter
```
podman-compose up -d
curl localhost:8080/
curl localhost:8080/hello.json
```

View File

View File

@@ -0,0 +1,39 @@
# pylint: disable=import-error
# pylint: disable=unused-import
import os
import asyncio # noqa: F401
import aioredis
from aiohttp import web
REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
REDIS_PORT = int(os.environ.get("REDIS_PORT", "6379"))
REDIS_DB = int(os.environ.get("REDIS_DB", "0"))
redis = aioredis.from_url(f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}")
app = web.Application()
routes = web.RouteTableDef()
@routes.get("/")
async def hello(request): # pylint: disable=unused-argument
counter = await redis.incr("mycounter")
return web.Response(text=f"counter={counter}")
@routes.get("/hello.json")
async def hello_json(request): # pylint: disable=unused-argument
counter = await redis.incr("mycounter")
data = {"counter": counter}
return web.json_response(data)
app.add_routes(routes)
def main():
web.run_app(app, port=8080)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,21 @@
---
version: '3'
volumes:
redis:
services:
redis:
read_only: true
image: docker.io/redis:alpine
command: ["redis-server", "--appendonly", "yes", "--notify-keyspace-events", "Ex"]
volumes:
- redis:/data
web:
read_only: true
build:
context: .
image: hello-py-aioweb
ports:
- 8080:8080
environment:
REDIS_HOST: redis

View File

@@ -0,0 +1,3 @@
aiohttp
aioredis
# aioredis[hiredis]

View File

@@ -0,0 +1,71 @@
{
"env": {
"node": true,
"es6": true
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".mjs", ".ts", ".cjs"]
}
}
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"allowImportExportEverywhere": true
},
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:promise/recommended",
"google",
"plugin:security/recommended"
],
"plugins": ["promise", "security", "import"],
"overrides": [
{
"files": "public/**/*.min.js",
"env": {
"browser": true,
"node": false,
"es6": false
},
"parserOptions": {
"sourceType": "script"
},
"extends": ["plugin:compat/recommended"],
"plugins": [],
"rules": {
"no-var": ["off"]
}
}
],
"rules": {
"security/detect-non-literal-fs-filename":["off"],
"security/detect-object-injection":["off"],
"camelcase": ["off"],
"no-console": ["off"],
"require-jsdoc": ["off"],
"one-var": ["off"],
"guard-for-in": ["off"],
"max-len": [
"warn",
{
"ignoreComments": true,
"ignoreTrailingComments": true,
"ignoreUrls": true,
"code": 200
}
],
"indent": ["warn", 4],
"no-unused-vars": ["warn"],
"no-extra-semi": ["warn"],
"linebreak-style": ["error", "unix"],
"quotes": ["warn", "double"],
"semi": ["error", "always"]
}
}

5
examples/nodeproj/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
local.env
.env
*.pid
node_modules

1
examples/nodeproj/.home/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*

View File

@@ -0,0 +1,16 @@
# How to run example
```
cp example.local.env local.env
cp example.env .env
cat local.env
cat .env
echo "UID=$UID" >> .env
cat .env
podman-compose build
podman-compose run --rm --no-deps init
podman-compose up
```

View File

@@ -0,0 +1,12 @@
FROM registry.fedoraproject.org/fedora-minimal:35
ARG NODE_VER=16
# microdnf -y module enable nodejs:${NODE_VER}
RUN \
echo -e "[nodejs]\nname=nodejs\nstream=${NODE_VER}\nprofiles=\nstate=enabled\n" > /etc/dnf/modules.d/nodejs.module && \
microdnf -y install shadow-utils nodejs zopfli findutils busybox && \
microdnf clean all
RUN adduser -d /app app && mkdir -p /app/code/.home && chown app:app -R /app/code && chmod 711 /app /app/code/.home && usermod -d /app/code/.home app
ENV XDG_CONFIG_HOME=/app/code/.home
ENV HOME=/app/code/.home
WORKDIR /app/code

View File

@@ -0,0 +1,48 @@
version: '3'
volumes:
redis:
services:
redis:
read_only: true
image: docker.io/redis:alpine
command: ["redis-server", "--appendonly", "yes", "--notify-keyspace-events", "Ex"]
volumes:
- redis:/data
tmpfs:
- /tmp
- /var/run
- /run
init:
read_only: true
#userns_mode: keep-id
user: ${UID:-1000}
build:
context: ./containers/${NODE_IMG:-node16-runtime}
image: ${NODE_IMG:-node16-runtime}
env_file:
- local.env
volumes:
- .:/app/code
command: ["/bin/sh", "-c", "mkdir -p ~/; [ -d ./node_modules ] && echo '** node_modules exists' || npm install"]
tmpfs:
- /tmp
- /run
task:
extends:
service: init
command: ["npm", "run", "cli", "--", "task"]
links:
- redis
depends_on:
- redis
web:
extends:
service: init
command: ["npm", "run", "cli", "--", "web"]
ports:
- ${WEB_LISTEN_PORT:-3000}:3000
depends_on:
- redis
links:
- mongo

View File

@@ -0,0 +1,3 @@
WEB_LISTEN_PORT=3000
# pass UID= your IDE user

View File

@@ -0,0 +1,2 @@
REDIS_HOST=redis

View File

@@ -0,0 +1,6 @@
#! /usr/bin/env node
"use strict";
import {start} from "./lib";
start();

View File

@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
},
"files": [
"index.js"
],
"include": [
"lib/**/*.js"
]
}

View File

@@ -0,0 +1,31 @@
"use strict";
import {proj} from "../proj";
async function loop() {
const poped = await proj.predis.blpop("queue", 5);
const task_desc_s = poped[1];
let task_desc;
try {
task_desc = JSON.parse(task_desc_s);
} catch (e) {
console.exception(e);
}
console.info("got task "+task_desc.func);
const func = task_desc.func;
const args = task_desc.args;
if (typeof(proj.tasks[func])!="function") {
console.log(`task ${func} not found`);
process.exit(-1)
}
try {
await ((this.tasks[func])(...args));
} catch (e) {
console.exception(e);
}
}
export async function start() {
while(true) {
loop();
}
}

View File

@@ -0,0 +1,21 @@
"use strict";
import {proj} from "../proj";
import http from "http";
import express from "express";
export async function start() {
const app = express();
const server = http.createServer(app);
// Routing
app.use(express.static(proj.config.basedir + "/public"));
app.get("/healthz", function(req, res) {
res.send("ok@"+Date.now());
});
server.listen(proj.config.LISTEN_PORT, proj.config.LISTEN_HOST, function() {
console.warn(`listening at port ${proj.config.LISTEN_PORT}`);
});
}

View File

@@ -0,0 +1,24 @@
{
"name": "nodeproj",
"version": "0.0.1",
"description": "nodejs example project",
"exports": {
".": "./index.js",
"./lib": "./lib"
},
"main": "index.js",
"type": "module",
"scripts": {
"cli": "nodemon -w lib -w index.js --es-module-specifier-resolution=node ./index.js"
},
"dependencies": {
"express": "~4.16.4",
"redis": "^3.1.2"
},
"private": true,
"author": "",
"license": "proprietary",
"devDependencies": {
"nodemon": "^2.0.14"
}
}

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Vote</title>
<link rel="stylesheet" href="https://unpkg.com/browse/normalize.css@8.0.1/normalize.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
<script type="text/javascript" src="main.css"></script>
<script type="text/javascript">
//<![CDATA[
console.log("loaded");
//]]>
</script>
</html>

View File

@@ -0,0 +1,24 @@
---
volumes:
db_data:
services:
wordpress:
image: docker.io/library/wordpress:latest
ports:
- 8080:80
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=password
- WORDPRESS_DB_NAME=wordpress
db:
image: docker.io/library/mariadb:10.6.4-focal
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=password

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
import copy
import os
import argparse
import yaml
from podman_compose import normalize_service, PodmanCompose
test_cases_simple = [
({"test": "test"}, {"test": "test"}),
({"build": "."}, {"build": {"context": "."}}),
({"build": "./dir-1"}, {"build": {"context": "./dir-1"}}),
({"build": {"context": "./dir-1"}}, {"build": {"context": "./dir-1"}}),
(
{"build": {"dockerfile": "dockerfile-1"}},
{"build": {"dockerfile": "dockerfile-1"}},
),
(
{"build": {"context": "./dir-1", "dockerfile": "dockerfile-1"}},
{"build": {"context": "./dir-1", "dockerfile": "dockerfile-1"}},
),
]
def test_normalize_service_simple():
for test_case, expected in copy.deepcopy(test_cases_simple):
test_original = copy.deepcopy(test_case)
test_case = normalize_service(test_case)
test_result = expected == test_case
if not test_result:
print("test: ", test_original)
print("expected: ", expected)
print("actual: ", test_case)
assert test_result
test_cases_sub_dir = [
({"test": "test"}, {"test": "test"}),
({"build": "."}, {"build": {"context": "./sub_dir/."}}),
({"build": "./dir-1"}, {"build": {"context": "./sub_dir/dir-1"}}),
({"build": {"context": "./dir-1"}}, {"build": {"context": "./sub_dir/dir-1"}}),
(
{"build": {"dockerfile": "dockerfile-1"}},
{"build": {"context": "./sub_dir", "dockerfile": "dockerfile-1"}},
),
(
{"build": {"context": "./dir-1", "dockerfile": "dockerfile-1"}},
{"build": {"context": "./sub_dir/dir-1", "dockerfile": "dockerfile-1"}},
),
]
def test_normalize_service_with_sub_dir():
for test_case, expected in copy.deepcopy(test_cases_sub_dir):
test_original = copy.deepcopy(test_case)
test_case = normalize_service(test_case, sub_dir="./sub_dir")
test_result = expected == test_case
if not test_result:
print("test: ", test_original)
print("expected: ", expected)
print("actual: ", test_case)
assert test_result
test_cases_merges = [
({}, {}, {}),
({}, {"test": "test"}, {"test": "test"}),
({"test": "test"}, {}, {"test": "test"}),
({"test": "test-1"}, {"test": "test-2"}, {"test": "test-2"}),
({}, {"build": "."}, {"build": {"context": "."}}),
({"build": "."}, {}, {"build": {"context": "."}}),
({"build": "./dir-1"}, {"build": "./dir-2"}, {"build": {"context": "./dir-2"}}),
({}, {"build": {"context": "./dir-1"}}, {"build": {"context": "./dir-1"}}),
({"build": {"context": "./dir-1"}}, {}, {"build": {"context": "./dir-1"}}),
(
{"build": {"context": "./dir-1"}},
{"build": {"context": "./dir-2"}},
{"build": {"context": "./dir-2"}},
),
(
{},
{"build": {"dockerfile": "dockerfile-1"}},
{"build": {"dockerfile": "dockerfile-1"}},
),
(
{"build": {"dockerfile": "dockerfile-1"}},
{},
{"build": {"dockerfile": "dockerfile-1"}},
),
(
{"build": {"dockerfile": "./dockerfile-1"}},
{"build": {"dockerfile": "./dockerfile-2"}},
{"build": {"dockerfile": "./dockerfile-2"}},
),
(
{"build": {"dockerfile": "./dockerfile-1"}},
{"build": {"context": "./dir-2"}},
{"build": {"dockerfile": "./dockerfile-1", "context": "./dir-2"}},
),
(
{"build": {"dockerfile": "./dockerfile-1", "context": "./dir-1"}},
{"build": {"dockerfile": "./dockerfile-2", "context": "./dir-2"}},
{"build": {"dockerfile": "./dockerfile-2", "context": "./dir-2"}},
),
(
{"build": {"dockerfile": "./dockerfile-1"}},
{"build": {"dockerfile": "./dockerfile-2", "args": ["ENV1=1"]}},
{"build": {"dockerfile": "./dockerfile-2", "args": ["ENV1=1"]}},
),
(
{"build": {"dockerfile": "./dockerfile-2", "args": ["ENV1=1"]}},
{"build": {"dockerfile": "./dockerfile-1"}},
{"build": {"dockerfile": "./dockerfile-1", "args": ["ENV1=1"]}},
),
(
{"build": {"dockerfile": "./dockerfile-2", "args": ["ENV1=1"]}},
{"build": {"dockerfile": "./dockerfile-1", "args": ["ENV2=2"]}},
{"build": {"dockerfile": "./dockerfile-1", "args": ["ENV1=1", "ENV2=2"]}},
),
]
def test__parse_compose_file_when_multiple_composes() -> None:
for test_input, test_override, expected_result in copy.deepcopy(test_cases_merges):
compose_test_1 = {"services": {"test-service": test_input}}
compose_test_2 = {"services": {"test-service": test_override}}
dump_yaml(compose_test_1, "test-compose-1.yaml")
dump_yaml(compose_test_2, "test-compose-2.yaml")
podman_compose = PodmanCompose()
set_args(podman_compose, ["test-compose-1.yaml", "test-compose-2.yaml"])
podman_compose._parse_compose_file() # pylint: disable=protected-access
actual_compose = {}
if podman_compose.services:
podman_compose.services["test-service"].pop("_deps")
actual_compose = podman_compose.services["test-service"]
if actual_compose != expected_result:
print("compose: ", test_input)
print("override: ", test_override)
print("expected: ", expected_result)
print("actual: ", actual_compose)
compose_expected = expected_result
assert compose_expected == actual_compose
def set_args(podman_compose: PodmanCompose, file_names: list[str]) -> None:
podman_compose.global_args = argparse.Namespace()
podman_compose.global_args.file = file_names
podman_compose.global_args.project_name = None
podman_compose.global_args.env_file = None
podman_compose.global_args.profile = []
podman_compose.global_args.in_pod = True
podman_compose.global_args.no_normalize = True
def dump_yaml(compose: dict, name: str) -> None:
with open(name, "w", encoding="utf-8") as outfile:
yaml.safe_dump(compose, outfile, default_flow_style=False)
def test_clean_test_yamls() -> None:
test_files = ["test-compose-1.yaml", "test-compose-2.yaml"]
for file in test_files:
if os.path.exists(file):
os.remove(file)

View File

@@ -0,0 +1,122 @@
import copy
import os
import argparse
import yaml
from podman_compose import normalize_service, PodmanCompose
test_keys = ["command", "entrypoint"]
test_cases_normalise_pre_merge = [
({"$$$": []}, {"$$$": []}),
({"$$$": ["sh"]}, {"$$$": ["sh"]}),
({"$$$": ["sh", "-c", "date"]}, {"$$$": ["sh", "-c", "date"]}),
({"$$$": "sh"}, {"$$$": ["sh"]}),
({"$$$": "sleep infinity"}, {"$$$": ["sleep", "infinity"]}),
(
{"$$$": "bash -c 'sleep infinity'"},
{"$$$": ["bash", "-c", "sleep infinity"]},
),
]
test_cases_merges = [
({}, {"$$$": []}, {"$$$": []}),
({"$$$": []}, {}, {"$$$": []}),
({"$$$": []}, {"$$$": "sh-2"}, {"$$$": ["sh-2"]}),
({"$$$": "sh-2"}, {"$$$": []}, {"$$$": []}),
({}, {"$$$": "sh"}, {"$$$": ["sh"]}),
({"$$$": "sh"}, {}, {"$$$": ["sh"]}),
({"$$$": "sh-1"}, {"$$$": "sh-2"}, {"$$$": ["sh-2"]}),
({"$$$": ["sh-1"]}, {"$$$": "sh-2"}, {"$$$": ["sh-2"]}),
({"$$$": "sh-1"}, {"$$$": ["sh-2"]}, {"$$$": ["sh-2"]}),
({"$$$": "sh-1"}, {"$$$": ["sh-2", "sh-3"]}, {"$$$": ["sh-2", "sh-3"]}),
({"$$$": ["sh-1"]}, {"$$$": ["sh-2", "sh-3"]}, {"$$$": ["sh-2", "sh-3"]}),
({"$$$": ["sh-1", "sh-2"]}, {"$$$": ["sh-3", "sh-4"]}, {"$$$": ["sh-3", "sh-4"]}),
({}, {"$$$": ["sh-3", "sh 4"]}, {"$$$": ["sh-3", "sh 4"]}),
({"$$$": "sleep infinity"}, {"$$$": "sh"}, {"$$$": ["sh"]}),
({"$$$": "sh"}, {"$$$": "sleep infinity"}, {"$$$": ["sleep", "infinity"]}),
(
{},
{"$$$": "bash -c 'sleep infinity'"},
{"$$$": ["bash", "-c", "sleep infinity"]},
),
]
def template_to_expression(base, override, expected, key):
base_copy = copy.deepcopy(base)
override_copy = copy.deepcopy(override)
expected_copy = copy.deepcopy(expected)
expected_copy[key] = expected_copy.pop("$$$")
if "$$$" in base:
base_copy[key] = base_copy.pop("$$$")
if "$$$" in override:
override_copy[key] = override_copy.pop("$$$")
return base_copy, override_copy, expected_copy
def test_normalize_service():
for test_input_template, expected_template in test_cases_normalise_pre_merge:
for key in test_keys:
test_input, _, expected = template_to_expression(
test_input_template, {}, expected_template, key
)
test_input = normalize_service(test_input)
test_result = expected == test_input
if not test_result:
print("base_template: ", test_input_template)
print("expected: ", expected)
print("actual: ", test_input)
assert test_result
def test__parse_compose_file_when_multiple_composes() -> None:
for base_template, override_template, expected_template in copy.deepcopy(
test_cases_merges
):
for key in test_keys:
base, override, expected = template_to_expression(
base_template, override_template, expected_template, key
)
compose_test_1 = {"services": {"test-service": base}}
compose_test_2 = {"services": {"test-service": override}}
dump_yaml(compose_test_1, "test-compose-1.yaml")
dump_yaml(compose_test_2, "test-compose-2.yaml")
podman_compose = PodmanCompose()
set_args(podman_compose, ["test-compose-1.yaml", "test-compose-2.yaml"])
podman_compose._parse_compose_file() # pylint: disable=protected-access
actual = {}
if podman_compose.services:
podman_compose.services["test-service"].pop("_deps")
actual = podman_compose.services["test-service"]
if actual != expected:
print("compose: ", base)
print("override: ", override)
print("result: ", expected)
assert expected == actual
def set_args(podman_compose: PodmanCompose, file_names: list[str]) -> None:
podman_compose.global_args = argparse.Namespace()
podman_compose.global_args.file = file_names
podman_compose.global_args.project_name = None
podman_compose.global_args.env_file = None
podman_compose.global_args.profile = []
podman_compose.global_args.in_pod = True
podman_compose.global_args.no_normalize = None
def dump_yaml(compose: dict, name: str) -> None:
with open(name, "w", encoding="utf-8") as outfile:
yaml.safe_dump(compose, outfile, default_flow_style=False)
def test_clean_test_yamls() -> None:
test_files = ["test-compose-1.yaml", "test-compose-2.yaml"]
for file in test_files:
if os.path.exists(file):
os.remove(file)

View File

@@ -0,0 +1,298 @@
# pylint: disable=protected-access
import argparse
import copy
import os
import yaml
from podman_compose import (
normalize_service,
normalize,
normalize_final,
normalize_service_final,
PodmanCompose,
)
cwd = os.path.abspath(".")
test_cases_simple_normalization = [
({"image": "test-image"}, {"image": "test-image"}),
(
{"build": "."},
{
"build": {"context": cwd, "dockerfile": "Dockerfile"},
},
),
(
{"build": "../relative"},
{
"build": {
"context": os.path.normpath(os.path.join(cwd, "../relative")),
"dockerfile": "Dockerfile",
},
},
),
(
{"build": "./relative"},
{
"build": {
"context": os.path.normpath(os.path.join(cwd, "./relative")),
"dockerfile": "Dockerfile",
},
},
),
(
{"build": "/workspace/absolute"},
{
"build": {
"context": "/workspace/absolute",
"dockerfile": "Dockerfile",
},
},
),
(
{
"build": {
"dockerfile": "Dockerfile",
},
},
{
"build": {
"context": cwd,
"dockerfile": "Dockerfile",
},
},
),
(
{
"build": {
"context": ".",
},
},
{
"build": {
"context": cwd,
"dockerfile": "Dockerfile",
},
},
),
(
{
"build": {"context": "../", "dockerfile": "test-dockerfile"},
},
{
"build": {
"context": os.path.normpath(os.path.join(cwd, "../")),
"dockerfile": "test-dockerfile",
},
},
),
(
{
"build": {"context": ".", "dockerfile": "./dev/test-dockerfile"},
},
{
"build": {
"context": cwd,
"dockerfile": "./dev/test-dockerfile",
},
},
),
]
#
# [service.build] is normalised after merges
#
def test_normalize_service_final_returns_absolute_path_in_context() -> None:
project_dir = cwd
for test_input, expected_service in copy.deepcopy(test_cases_simple_normalization):
actual_service = normalize_service_final(test_input, project_dir)
assert expected_service == actual_service
def test_normalize_returns_absolute_path_in_context() -> None:
project_dir = cwd
for test_input, expected_result in copy.deepcopy(test_cases_simple_normalization):
compose_test = {"services": {"test-service": test_input}}
compose_expected = {"services": {"test-service": expected_result}}
actual_compose = normalize_final(compose_test, project_dir)
assert compose_expected == actual_compose
#
# running full parse over single compose files
#
def test__parse_compose_file_when_single_compose() -> None:
for test_input, expected_result in copy.deepcopy(test_cases_simple_normalization):
compose_test = {"services": {"test-service": test_input}}
dump_yaml(compose_test, "test-compose.yaml")
podman_compose = PodmanCompose()
set_args(podman_compose, ["test-compose.yaml"], no_normalize=None)
podman_compose._parse_compose_file()
actual_compose = {}
if podman_compose.services:
podman_compose.services["test-service"].pop("_deps")
actual_compose = podman_compose.services["test-service"]
if actual_compose != expected_result:
print("compose: ", test_input)
print("result: ", expected_result)
assert expected_result == actual_compose
test_cases_with_merges = [
(
{},
{"build": "."},
{"build": {"context": cwd, "dockerfile": "Dockerfile"}},
),
(
{"build": "."},
{},
{"build": {"context": cwd, "dockerfile": "Dockerfile"}},
),
(
{"build": "/workspace/absolute"},
{"build": "./relative"},
{
"build": {
"context": os.path.normpath(os.path.join(cwd, "./relative")),
"dockerfile": "Dockerfile",
}
},
),
(
{"build": "./relative"},
{"build": "/workspace/absolute"},
{"build": {"context": "/workspace/absolute", "dockerfile": "Dockerfile"}},
),
(
{"build": "./relative"},
{"build": "/workspace/absolute"},
{"build": {"context": "/workspace/absolute", "dockerfile": "Dockerfile"}},
),
(
{"build": {"dockerfile": "test-dockerfile"}},
{},
{"build": {"context": cwd, "dockerfile": "test-dockerfile"}},
),
(
{},
{"build": {"dockerfile": "test-dockerfile"}},
{"build": {"context": cwd, "dockerfile": "test-dockerfile"}},
),
(
{},
{"build": {"dockerfile": "test-dockerfile"}},
{"build": {"context": cwd, "dockerfile": "test-dockerfile"}},
),
(
{"build": {"dockerfile": "test-dockerfile-1"}},
{"build": {"dockerfile": "test-dockerfile-2"}},
{"build": {"context": cwd, "dockerfile": "test-dockerfile-2"}},
),
(
{"build": "/workspace/absolute"},
{"build": {"dockerfile": "test-dockerfile"}},
{"build": {"context": "/workspace/absolute", "dockerfile": "test-dockerfile"}},
),
(
{"build": {"dockerfile": "test-dockerfile"}},
{"build": "/workspace/absolute"},
{"build": {"context": "/workspace/absolute", "dockerfile": "test-dockerfile"}},
),
(
{"build": {"dockerfile": "./test-dockerfile-1"}},
{"build": {"dockerfile": "./test-dockerfile-2", "args": ["ENV1=1"]}},
{
"build": {
"context": cwd,
"dockerfile": "./test-dockerfile-2",
"args": ["ENV1=1"],
}
},
),
(
{"build": {"dockerfile": "./test-dockerfile-1", "args": ["ENV1=1"]}},
{"build": {"dockerfile": "./test-dockerfile-2"}},
{
"build": {
"context": cwd,
"dockerfile": "./test-dockerfile-2",
"args": ["ENV1=1"],
}
},
),
(
{"build": {"dockerfile": "./test-dockerfile-1", "args": ["ENV1=1"]}},
{"build": {"dockerfile": "./test-dockerfile-2", "args": ["ENV2=2"]}},
{
"build": {
"context": cwd,
"dockerfile": "./test-dockerfile-2",
"args": ["ENV1=1", "ENV2=2"],
}
},
),
]
#
# running full parse over merged
#
def test__parse_compose_file_when_multiple_composes() -> None:
for test_input, test_override, expected_result in copy.deepcopy(
test_cases_with_merges
):
compose_test_1 = {"services": {"test-service": test_input}}
compose_test_2 = {"services": {"test-service": test_override}}
dump_yaml(compose_test_1, "test-compose-1.yaml")
dump_yaml(compose_test_2, "test-compose-2.yaml")
podman_compose = PodmanCompose()
set_args(
podman_compose,
["test-compose-1.yaml", "test-compose-2.yaml"],
no_normalize=None,
)
podman_compose._parse_compose_file()
actual_compose = {}
if podman_compose.services:
podman_compose.services["test-service"].pop("_deps")
actual_compose = podman_compose.services["test-service"]
if actual_compose != expected_result:
print("compose: ", test_input)
print("override: ", test_override)
print("result: ", expected_result)
compose_expected = expected_result
assert compose_expected == actual_compose
def set_args(
podman_compose: PodmanCompose, file_names: list[str], no_normalize: bool
) -> None:
podman_compose.global_args = argparse.Namespace()
podman_compose.global_args.file = file_names
podman_compose.global_args.project_name = None
podman_compose.global_args.env_file = None
podman_compose.global_args.profile = []
podman_compose.global_args.in_pod = True
podman_compose.global_args.no_normalize = no_normalize
def dump_yaml(compose: dict, name: str) -> None:
# Path(Path.cwd()/"subdirectory").mkdir(parents=True, exist_ok=True)
with open(name, "w", encoding="utf-8") as outfile:
yaml.safe_dump(compose, outfile, default_flow_style=False)
def test_clean_test_yamls() -> None:
test_files = ["test-compose-1.yaml", "test-compose-2.yaml", "test-compose.yaml"]
for file in test_files:
if os.path.exists(file):
os.remove(file)

21
pytests/test_volumes.py Normal file
View File

@@ -0,0 +1,21 @@
# pylint: disable=redefined-outer-name
import pytest
from podman_compose import parse_short_mount
@pytest.fixture
def multi_propagation_mount_str():
return "/foo/bar:/baz:U,Z"
def test_parse_short_mount_multi_propagation(multi_propagation_mount_str):
expected = {
"type": "bind",
"source": "/foo/bar",
"target": "/baz",
"bind": {
"propagation": "U,Z",
},
}
assert parse_short_mount(multi_propagation_mount_str, "/") == expected

7
requirements.txt Normal file
View File

@@ -0,0 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pyyaml
python-dotenv

View File

@@ -1,2 +1,9 @@
[bdist_wheel]
universal = 1
[metadata]
version = attr: podman_compose.__version__
[flake8]
# The GitHub editor is 127 chars wide
max-line-length=127

View File

@@ -1,48 +1,53 @@
import os
from setuptools import setup, find_packages
from setuptools import setup
try:
readme = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
except:
readme = ''
from podman_compose import __version__ as podman_compose_version
README = open(
os.path.join(os.path.dirname(__file__), "README.md"), encoding="utf-8"
).read()
except: # noqa: E722 # pylint: disable=bare-except
README = ""
setup(
name='podman-compose',
version=podman_compose_version,
name="podman-compose",
description="A script to run docker-compose.yml using podman",
long_description=readme,
long_description_content_type='text/markdown',
long_description=README,
long_description_content_type="text/markdown",
classifiers=[
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Development Status :: 3 - Alpha",
"Topic :: Software Development :: Build Tools",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
],
keywords='podman, podman-compose',
author='Muayyad Alsadi',
author_email='alsadi@gmail.com',
url='https://github.com/containers/podman-compose',
py_modules=['podman_compose'],
entry_points={
'console_scripts': [
'podman-compose = podman_compose:main'
]
},
keywords="podman, podman-compose",
author="Muayyad Alsadi",
author_email="alsadi@gmail.com",
url="https://github.com/containers/podman-compose",
py_modules=["podman_compose"],
entry_points={"console_scripts": ["podman-compose = podman_compose:main"]},
include_package_data=True,
license='GPL-2.0-only',
license="GPL-2.0-only",
install_requires=[
'pyyaml'
"pyyaml",
"python-dotenv",
],
extras_require={
"devel": [
"flake8",
"black",
"pylint",
"pre-commit",
"coverage"
]
}
# test_suite='tests',
# tests_require=[
# 'coverage',

9
test-requirements.txt Normal file
View File

@@ -0,0 +1,9 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
coverage
pytest
tox
black
flake8

View File

@@ -1,7 +1,9 @@
FROM busybox
ARG buildno=1
ARG httpd_port=80
ARG other_variable=not_set
ENV httpd_port ${httpd_port}
ENV other_variable ${other_variable}
RUN mkdir -p /var/www/html/ && \
echo "ALT buildno=$buildno port=$httpd_port `date -Iseconds`" > /var/www/html/index.txt
CMD httpd -f -p "$httpd_port" -h /var/www/html

View File

@@ -17,3 +17,9 @@ services:
image: my-busybox-httpd2
ports:
- 8000:8000
test_build_arg_argument:
build:
context: ./context
dockerfile: Dockerfile-alt
image: my-busybox-httpd2
command: env

View File

@@ -0,0 +1,22 @@
# Test podman-compose with build (fail scenario)
```shell
podman-compose build || echo $?
```
expected output would be something like
```
STEP 1/3: FROM busybox
STEP 2/3: RUN this_command_does_not_exist
/bin/sh: this_command_does_not_exist: not found
Error: building at STEP "RUN this_command_does_not_exist": while running runtime: exit status 127
exit code: 127
```
Expected `podman-compose` exit code:
```shell
echo $?
127
```

View File

@@ -0,0 +1,3 @@
FROM busybox
RUN this_command_does_not_exist
CMD ["sh"]

View File

@@ -0,0 +1,5 @@
version: "3"
services:
test:
build: ./context
image: build-fail-img

26
tests/conftest.py Normal file
View File

@@ -0,0 +1,26 @@
"""conftest.py
Defines global pytest fixtures available to all tests.
"""
# pylint: disable=redefined-outer-name
from pathlib import Path
import os
import pytest
@pytest.fixture
def base_path():
"""Returns the base path for the project"""
return Path(__file__).parent.parent
@pytest.fixture
def test_path(base_path):
"""Returns the path to the tests directory"""
return os.path.join(base_path, "tests")
@pytest.fixture
def podman_compose_path(base_path):
"""Returns the path to the podman compose script"""
return os.path.join(base_path, "podman_compose.py")

4
tests/deps/README.md Normal file
View File

@@ -0,0 +1,4 @@
```
podman-compose run --rm sleep /bin/sh -c 'wget -O - http://web:8000/hosts'
```

View File

@@ -0,0 +1,25 @@
version: "3.7"
services:
web:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/etc/", "-p", "8000"]
tmpfs:
- /run
- /tmp
sleep:
image: busybox
command: ["/bin/busybox", "sh", "-c", "sleep 3600"]
depends_on:
- "web"
tmpfs:
- /run
- /tmp
sleep2:
image: busybox
command: ["/bin/busybox", "sh", "-c", "sleep 3600"]
depends_on:
- sleep
tmpfs:
- /run
- /tmp

View File

@@ -0,0 +1,9 @@
running the following commands should always give podman-rocks-123
```
podman-compose -f project/container-compose.yaml --env-file env-files/project-1.env up
```
```
podman-compose -f $(pwd)/project/container-compose.yaml --env-file $(pwd)/env-files/project-1.env up
```

View File

@@ -0,0 +1 @@
ZZVAR1=podman-rocks-123

View File

@@ -0,0 +1,9 @@
services:
app:
image: busybox
command: ["/bin/busybox", "sh", "-c", "env | grep ZZ"]
tmpfs:
- /run
- /tmp
environment:
ZZVAR1: $ZZVAR1

View File

@@ -0,0 +1,5 @@
running the following command should give myval2
```
podman_compose run -l monkey -e ZZVAR1=myval2 env-test
```

View File

@@ -0,0 +1,9 @@
version: '3'
services:
env-test:
image: busybox
command: sh -c "export | grep ZZ"
environment:
- ZZVAR1=myval1

15
tests/exit-from/README.md Normal file
View File

@@ -0,0 +1,15 @@
We have service named sh1 that exits with code 1 and sh2 that exists with code 2
```
podman-compose up --exit-code-from=sh1
echo $?
```
the above should give 1.
```
podman-compose up --exit-code-from=sh2
echo $?
```
the above should give 2.

View File

@@ -0,0 +1,21 @@
version: "3"
services:
too_long:
image: busybox
command: ["/bin/busybox", "sh", "-c", "sleep 3600; exit 0"]
tmpfs:
- /run
- /tmp
sh1:
image: busybox
command: ["/bin/busybox", "sh", "-c", "sleep 5; exit 1"]
tmpfs:
- /run
- /tmp
sh2:
image: busybox
command: ["/bin/busybox", "sh", "-c", "sleep 5; exit 2"]
tmpfs:
- /run
- /tmp

View File

@@ -0,0 +1,29 @@
version: "3"
services:
echo:
image: busybox
command: ["/bin/busybox", "echo", "Zero"]
ports:
- '1234:1234'
environment:
- FOO=original
- BAR=original
# volumes:
# - ./original:/foo
# - ./original:/bar
echo1:
extends:
service: echo
command: ["/bin/busybox", "echo", "One"]
ports:
- '12345:12345'
# volumes:
# - ./local:/bar
# - ./local:/baz
env1:
extends:
service: echo
command: ["/bin/busybox", "env"]
environment:
- BAR=local
- BAZ=local

View File

@@ -0,0 +1,7 @@
services:
webapp_default:
webapp_special:
image: busybox
volumes:
- "/data"

View File

@@ -0,0 +1,10 @@
version: "3"
services:
web:
image: busybox
extends:
file: common-services.yml
service: webapp_default
environment:
- DEBUG=1
cpu_shares: 5

View File

@@ -0,0 +1,7 @@
webapp:
build: .
ports:
- "8000:8000"
volumes:
- "/data"

View File

@@ -0,0 +1,14 @@
version: "3"
services:
web:
extends:
file: common-services.yml
service: webapp
environment:
- DEBUG=1
cpu_shares: 5
important_web:
extends: web
cpu_shares: 10

View File

@@ -0,0 +1,8 @@
version: "3"
services:
web:
extends:
file: sub/docker-compose.yml
service: webapp
environment:
- DEBUG=1

View File

@@ -0,0 +1,12 @@
version: "3"
services:
webapp:
build:
context: docker/example
dockerfile: Dockerfile
image: localhost/subdir_test:me
ports:
- "8000:8000"
volumes:
- "/data"

View File

@@ -0,0 +1 @@
FROM busybox as base

View File

@@ -0,0 +1,7 @@
version: '3.6'
services:
web:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", ".", "-p", "8003"]

View File

@@ -0,0 +1,4 @@
version: '3.6'
include:
- docker-compose.base.yaml

1
tests/interpolation/.env Normal file
View File

@@ -0,0 +1 @@
DOT_ENV_VARIABLE=This value is from the .env file

View File

@@ -0,0 +1,8 @@
version: "3.7"
services:
variables:
image: busybox
command: ["/bin/busybox", "sh", "-c", "export | grep EXAMPLE"]
environment:
EXAMPLE_COLON_QUESTION_ERROR: ${NOT_A_VARIABLE:?Missing variable}

View File

@@ -0,0 +1,8 @@
version: "3.7"
services:
variables:
image: busybox
command: ["/bin/busybox", "sh", "-c", "export | grep EXAMPLE"]
environment:
EXAMPLE_QUESTION_ERROR: ${NOT_A_VARIABLE?Missing variable}

View File

@@ -0,0 +1,14 @@
version: "3.7"
services:
variables:
image: busybox
command: ["/bin/busybox", "sh", "-c", "export | grep EXAMPLE"]
environment:
EXAMPLE_VARIABLE: "Host user: $USER"
EXAMPLE_BRACES: "Host user: ${USER}"
EXAMPLE_COLON_DASH_DEFAULT: ${NOT_A_VARIABLE:-My default}
EXAMPLE_DASH_DEFAULT: ${NOT_A_VARIABLE-My other default}
EXAMPLE_DOT_ENV: $DOT_ENV_VARIABLE
EXAMPLE_LITERAL: This is a $$literal
EXAMPLE_EMPTY: $NOT_A_VARIABLE

View File

@@ -0,0 +1,19 @@
# Multiple compose files
to make sure we get results similar to
```
docker-compose -f d1/docker-compose.yml -f d2/docker-compose.yml up -d
docker exec -ti d1_web1_1 sh -c 'set'
docker exec -ti d1_web2_1 sh -c 'set'
curl http://${d1_web1_1}:8001/index.txt
curl http://${d1_web1_1}:8002/index.txt
```
we need to verify
- project base directory and project name is `d1`
- `var12='d1/12.env'` which means `enf_file` was appended not replaced (which means that we normalize to array before merge)
- `var2='d1/2.env'` which means that paths inside `d2/docker-compose.yml` directory are relative to `d1`

View File

@@ -0,0 +1 @@
var1=d1/1.env

View File

@@ -0,0 +1 @@
var12=d1/12.env

View File

@@ -0,0 +1 @@
var2=d1/2.env

View File

@@ -0,0 +1,13 @@
version: '3'
services:
web1:
image: busybox
command: busybox httpd -h /var/www/html/ -f -p 8001
volumes:
- ./1.env:/var/www/html/index.txt:z
env_file: ./1.env
labels:
l1: v1
environment:
- mykey1=myval1

View File

@@ -0,0 +1 @@
var12=d2/12.env

View File

@@ -0,0 +1 @@
var2=d2/2.env

View File

@@ -0,0 +1,19 @@
version: '3'
services:
web1:
image: busybox
env_file: ./12.env
labels:
- l1=v2
- l2=v2
environment:
mykey1: myval2
mykey2: myval2
web2:
image: busybox
command: busybox httpd -h /var/www/html/ -f -p 8002
volumes:
- ./2.env:/var/www/html/index.txt:z
env_file: ./2.env

View File

@@ -0,0 +1,7 @@
version: '3'
services:
web:
image: busybox
command: httpd -f -p 8123 -h /etc/
network_mode: host

Some files were not shown because too many files have changed in this diff Show More