215 Commits

Author SHA1 Message Date
Muayyad Alsadi
1f4a4d2184 Revert "Use SELinux mount flag for secrets"
This reverts commit 874192568f.
2023-04-10 12:26:42 +03:00
Muayyad Alsadi
08a453d643 Revert "Use more lenient SELinux mount flag for secrets"
This reverts commit 75de39c239.
2023-04-10 12:26:42 +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
76 changed files with 3795 additions and 952 deletions

View File

@@ -35,7 +35,7 @@ What is the behavior you actually got and that should not happen.
``` ```
$ podman-compose version $ podman-compose version
using podman version: 3.4.0 using podman version: 3.4.0
podman-composer version 0.1.7dev podman-compose version 0.1.7dev
podman --version podman --version
podman version 3.4.0 podman version 3.4.0

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.8", "3.9", "3.10"]
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')

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

@@ -0,0 +1,36 @@
# 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: |
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r 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: |
python -m pytest ./pytests

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

@@ -0,0 +1,29 @@
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]
- 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] [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 _ for ignored variables
# allow generic names like a,b,c and i,j,k,l,m,n and x,y,z # 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 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 w,h for width, height
# allow op for operation/operator/opcode # allow op for operation/operator/opcode
# allow t, t0, t1, t2, and t3 for time # allow t, t0, t1, t2, and t3 for time
# allow dt for delta time # allow dt for delta time
# allow db for database # allow db for database
# allow ls for list # 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

View File

@@ -1,5 +1,49 @@
# Contributing to podman-compose # 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. 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 ## Adding new commands
To add a command you need to add a function that is decorated To add a command you need to add a function that is decorated
@@ -60,15 +104,11 @@ def compose_up(compose, args):
create Create services create Create services
events Receive real time events from containers events Receive real time events from containers
images List images images List images
kill Kill containers
logs View output from containers logs View output from containers
pause Pause services
port Print the public port for a port binding port Print the public port for a port binding
ps List containers ps List containers
rm Remove stopped containers rm Remove stopped containers
run Run a one-off command run Run a one-off command
scale Set number of containers for a service scale Set number of containers for a service
top Display the running processes top Display the running processes
unpause Unpause services
version Show the Docker-Compose version information
``` ```

View File

@@ -1,44 +1,55 @@
# Podman Compose # 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 An implementation of [Compose Spec](https://compose-spec.io/) with [Podman](https://podman.io/) backend.
- no daemon, no setup. This project focuses on:
- can be used by developers to run single-machine containerized stacks using single familiar YAML file
This project only depend on: * rootless
* daemon-less process model, we directly execute podman, no running daemon.
This project only depends on:
* `podman` * `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 * Python3
* [PyYAML](https://pyyaml.org/) * [PyYAML](https://pyyaml.org/)
* [python-dotenv](https://pypi.org/project/python-dotenv/) * [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. 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 For production-like single-machine containerized environment consider
- [k3s](https://k3s.io) | [k3s github](https://github.com/rancher/k3s) - [k3s](https://k3s.io) | [k3s github](https://github.com/rancher/k3s)
- [MiniKube](https://minikube.sigs.k8s.io/) - [MiniKube](https://minikube.sigs.k8s.io/)
- [MiniShift](https://www.okd.io/minishift/)
For the real thing (multi-node clusters) check any production 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/).
## Versions ## Versions
If you have legacy version of `podman` (before 3.x) you might need to stick with legacy `podman-compose` `0.1.x` branch. 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. 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. 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.
## Installation ## Installation
Install latest stable version from PyPI: Install the latest stable version from PyPI:
``` ```
pip3 install podman-compose pip3 install podman-compose
@@ -52,19 +63,6 @@ Or latest development version from GitHub:
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz
``` ```
or
```
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
```
or install from Fedora (starting from f31) repositories: or install from Fedora (starting from f31) repositories:
@@ -75,6 +73,8 @@ sudo dnf install podman-compose
## Basic Usage ## Basic Usage
We have included fully functional sample stacks inside `examples/` directory. 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 A quick example would be
@@ -95,19 +95,21 @@ which have
- a django tasks - 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 ## Tests
Inside `tests/` directory we have many useless docker-compose stacks 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 ```shell
its network namespace so that all containers talk via localhost. python -m pytest pytests
For more information see [docs/Mappings.md](docs/Mappings.md). ```
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

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

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

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

View File

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

View File

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

View File

@@ -6,3 +6,4 @@ coverage
pytest-cov pytest-cov
pytest pytest
tox tox
black

25
tests/conftest.py Normal file
View File

@@ -0,0 +1,25 @@
"""conftest.py
Defines global pytest fixtures available to all tests.
"""
import pytest
from pathlib import Path
import os
@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")

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

@@ -4,7 +4,7 @@ services:
image: busybox image: busybox
command: busybox httpd -h /var/www/html/ -f -p 8001 command: busybox httpd -h /var/www/html/ -f -p 8001
volumes: volumes:
- ./1.env:/var/www/html/index.txt - ./1.env:/var/www/html/index.txt:z
env_file: ./1.env env_file: ./1.env
labels: labels:
l1: v1 l1: v1

View File

@@ -1,10 +1,11 @@
version: '3' version: '3'
services: services:
web1: web1:
image: busybox
env_file: ./12.env env_file: ./12.env
labels: labels:
- l1=v2 - l1=v2
- l2=v2 - l2=v2
environment: environment:
mykey1: myval2 mykey1: myval2
mykey2: myval2 mykey2: myval2
@@ -13,6 +14,6 @@ services:
image: busybox image: busybox
command: busybox httpd -h /var/www/html/ -f -p 8002 command: busybox httpd -h /var/www/html/ -f -p 8002
volumes: volumes:
- ./2.env:/var/www/html/index.txt - ./2.env:/var/www/html/index.txt:z
env_file: ./2.env 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

View File

@@ -0,0 +1,16 @@
---
# https://github.com/compose-spec/compose-spec/blob/master/spec.md#priority
services:
app:
image: busybox
command: top
networks:
app_net_1:
app_net_2:
priority: 1000
app_net_3:
priority: 100
networks:
app_net_1:
app_net_2:
app_net_3:

View File

@@ -0,0 +1,21 @@
version: "3"
services:
web1:
image: busybox
hostname: web1
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
ports:
- 8001:8001
volumes:
- ./test1.txt:/var/www/html/index.txt:ro,z
web2:
image: busybox
hostname: web2
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
ports:
- 8002:8001
volumes:
- ./test2.txt:/var/www/html/index.txt:ro,z

View File

@@ -0,0 +1 @@
test1

View File

@@ -0,0 +1 @@
test2

View File

@@ -0,0 +1,23 @@
version: "3"
networks:
mystack:
services:
web1:
image: busybox
hostname: web1
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
ports:
- 8001:8001
volumes:
- ./test1.txt:/var/www/html/index.txt:ro,z
web2:
image: busybox
hostname: web2
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
ports:
- 8002:8001
volumes:
- ./test2.txt:/var/www/html/index.txt:ro,z

View File

@@ -0,0 +1 @@
test1

View File

@@ -0,0 +1 @@
test2

View File

@@ -0,0 +1,45 @@
version: "3"
networks:
net1:
net2:
services:
web1:
image: busybox
#container_name: web1
hostname: web1
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
networks:
- net1
ports:
- 8001:8001
volumes:
- ./test1.txt:/var/www/html/index.txt:ro,z
web2:
image: busybox
#container_name: web2
hostname: web2
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
networks:
- net1
- net2
ports:
- 8002:8001
volumes:
- ./test2.txt:/var/www/html/index.txt:ro,z
web3:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html
networks:
net1:
aliases:
- alias11
- alias12
net2:
aliases:
- alias21
volumes:
- ./test2.txt:/var/www/html/index.txt:ro,z

View File

@@ -0,0 +1 @@
test1

View File

@@ -0,0 +1 @@
test2

View File

@@ -2,32 +2,34 @@ version: "3"
services: services:
web1: web1:
image: busybox image: busybox
hostname: web1
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html working_dir: /var/www/html
ports: ports:
- 8001:8001 - 8001:8001
volumes: volumes:
- ./test1.txt:/var/www/html/index.txt:ro - ./test1.txt:/var/www/html/index.txt:ro,z
web2: web2:
image: busybox image: busybox
hostname: web2
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"]
working_dir: /var/www/html working_dir: /var/www/html
ports: ports:
- 8002:8002 - 8002:8002
- target: 8003 - target: 8003
host_ip: 127.0.0.1 host_ip: 127.0.0.1
published: 8003 published: 8003
protocol: udp protocol: udp
- target: 8004 - target: 8004
host_ip: 127.0.0.1 host_ip: 127.0.0.1
published: 8004 published: 8004
protocol: tcp protocol: tcp
- target: 8005 - target: 8005
published: 8005 published: 8005
- target: 8006 - target: 8006
protocol: udp protocol: udp
- target: 8007 - target: 8007
host_ip: 127.0.0.1 host_ip: 127.0.0.1
volumes: volumes:
- ./test2.txt:/var/www/html/index.txt:ro - ./test2.txt:/var/www/html/index.txt:ro,z

View File

@@ -0,0 +1,24 @@
version: "3"
services:
default-service:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/etc/", "-p", "8000"]
tmpfs:
- /run
- /tmp
service-1:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/etc/", "-p", "8000"]
tmpfs:
- /run
- /tmp
profiles:
- profile-1
service-2:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/etc/", "-p", "8000"]
tmpfs:
- /run
- /tmp
profiles:
- profile-2

View File

@@ -1,3 +1,7 @@
---
# echo "sec" | podman secret create my_secret -
# echo "sec2" | podman secret create my_secret_2 -
# echo "sec3" | podman secret create my_secret_3 -
version: "3.8" version: "3.8"
services: services:
test: test:
@@ -8,7 +12,7 @@ services:
- /run - /run
- /tmp - /tmp
volumes: volumes:
- ./print_secrets.sh:/tmp/print_secrets.sh - ./print_secrets.sh:/tmp/print_secrets.sh:z
secrets: secrets:
- my_secret - my_secret
- my_secret_2 - my_secret_2

View File

View File

View File

@@ -4,7 +4,7 @@ services:
image: redis:alpine image: redis:alpine
command: ["redis-server", "--appendonly yes", "--notify-keyspace-events", "Ex"] command: ["redis-server", "--appendonly yes", "--notify-keyspace-events", "Ex"]
volumes: volumes:
- ./data/redis:/data - ./data/redis:/data:z
tmpfs: /run1 tmpfs: /run1
ports: ports:
- "6379" - "6379"
@@ -25,16 +25,16 @@ services:
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
working_dir: /var/www/html working_dir: /var/www/html
volumes: volumes:
- ./data/web:/var/www/html:ro - ./data/web:/var/www/html:ro,z
web2: web2:
image: busybox image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"]
working_dir: /var/www/html working_dir: /var/www/html
volumes: volumes:
- ~/Downloads/www:/var/www/html:ro - ~/Downloads/www:/var/www/html:ro,z
web3: web3:
image: busybox image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8003"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8003"]
working_dir: /var/www/html working_dir: /var/www/html
volumes: volumes:
- /var/www/html:/var/www/html:ro - /var/www/html:/var/www/html:ro,z

View File

@@ -0,0 +1,61 @@
from pathlib import Path
import subprocess
def capture(command):
proc = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
out, err = proc.communicate()
return out, err, proc.returncode
def test_podman_compose_extends_w_file_subdir():
"""
Test that podman-compose can execute podman-compose -f <file> up with extended File which
includes a build context
:return:
"""
main_path = Path(__file__).parent.parent
command_up = [
"python3",
str(main_path.joinpath("podman_compose.py")),
"-f",
str(main_path.joinpath("tests", "extends_w_file_subdir", "docker-compose.yml")),
"up",
"-d",
]
command_check_container = [
"podman",
"container",
"ps",
"--all",
"--format",
'"{{.Image}}"',
]
command_down = [
"podman",
"rmi",
"--force",
"localhost/subdir_test:me",
"docker.io/library/busybox",
]
out, _, returncode = capture(command_up)
assert 0 == returncode
# check container was created and exists
out, _, returncode = capture(command_check_container)
assert 0 == returncode
assert out == b'"localhost/subdir_test:me"\n'
out, _, returncode = capture(command_down)
# cleanup test image(tags)
assert 0 == returncode
# check container did not exists anymore
out, _, returncode = capture(command_check_container)
assert 0 == returncode
assert out == b""

View File

@@ -0,0 +1,77 @@
"""
test_podman_compose_config.py
Tests the podman-compose config command which is used to return defined compose services.
"""
import pytest
import os
from test_podman_compose import capture
@pytest.fixture
def profile_compose_file(test_path):
""" "Returns the path to the `profile` compose file used for this test module"""
return os.path.join(test_path, "profile", "docker-compose.yml")
def test_config_no_profiles(podman_compose_path, profile_compose_file):
"""
Tests podman-compose config command without profile enablement.
:param podman_compose_path: The fixture used to specify the path to the podman compose file.
:param profile_compose_file: The fixtued used to specify the path to the "profile" compose used in the test.
"""
config_cmd = ["python3", podman_compose_path, "-f", profile_compose_file, "config"]
out, err, return_code = capture(config_cmd)
assert return_code == 0
string_output = out.decode("utf-8")
assert "default-service" in string_output
assert "service-1" not in string_output
assert "service-2" not in string_output
@pytest.mark.parametrize(
"profiles, expected_services",
[
(
["--profile", "profile-1", "config"],
{"default-service": True, "service-1": True, "service-2": False},
),
(
["--profile", "profile-2", "config"],
{"default-service": True, "service-1": False, "service-2": True},
),
(
["--profile", "profile-1", "--profile", "profile-2", "config"],
{"default-service": True, "service-1": True, "service-2": True},
),
],
)
def test_config_profiles(
podman_compose_path, profile_compose_file, profiles, expected_services
):
"""
Tests podman-compose
:param podman_compose_path: The fixture used to specify the path to the podman compose file.
:param profile_compose_file: The fixtued used to specify the path to the "profile" compose used in the test.
:param profiles: The enabled profiles for the parameterized test.
:param expected_services: Dictionary used to model the expected "enabled" services in the profile.
Key = service name, Value = True if the service is enabled, otherwise False.
"""
config_cmd = ["python3", podman_compose_path, "-f", profile_compose_file]
config_cmd.extend(profiles)
out, err, return_code = capture(config_cmd)
assert return_code == 0
actual_output = out.decode("utf-8")
assert len(expected_services) == 3
actual_services = {}
for service, expected_check in expected_services.items():
actual_services[service] = service in actual_output
assert expected_services == actual_services

View File

@@ -0,0 +1,88 @@
"""
test_podman_compose_up_down.py
Tests the podman compose up and down commands used to create and remove services.
"""
import pytest
import os
from test_podman_compose import capture
@pytest.fixture
def profile_compose_file(test_path):
""" "Returns the path to the `profile` compose file used for this test module"""
return os.path.join(test_path, "profile", "docker-compose.yml")
@pytest.fixture(autouse=True)
def teardown(podman_compose_path, profile_compose_file):
"""
Ensures that the services within the "profile compose file" are removed between each test case.
:param podman_compose_path: The path to the podman compose script.
:param profile_compose_file: The path to the compose file used for this test module.
"""
# run the test case
yield
down_cmd = [
"python3",
podman_compose_path,
"--profile",
"profile-1",
"--profile",
"profile-2",
"-f",
profile_compose_file,
"down",
]
capture(down_cmd)
@pytest.mark.parametrize(
"profiles, expected_services",
[
(
["--profile", "profile-1", "up", "-d"],
{"default-service": True, "service-1": True, "service-2": False},
),
(
["--profile", "profile-2", "up", "-d"],
{"default-service": True, "service-1": False, "service-2": True},
),
(
["--profile", "profile-1", "--profile", "profile-2", "up", "-d"],
{"default-service": True, "service-1": True, "service-2": True},
),
],
)
def test_up(podman_compose_path, profile_compose_file, profiles, expected_services):
up_cmd = [
"python3",
podman_compose_path,
"-f",
profile_compose_file,
]
up_cmd.extend(profiles)
out, err, return_code = capture(up_cmd)
assert return_code == 0
check_cmd = [
"podman",
"container",
"ps",
"--format",
'"{{.Names}}"',
]
out, err, return_code = capture(check_cmd)
assert return_code == 0
assert len(expected_services) == 3
actual_output = out.decode("utf-8")
actual_services = {}
for service, expected_check in expected_services.items():
actual_services[service] = service in actual_output
assert expected_services == actual_services

View File

@@ -0,0 +1,9 @@
version: "3"
services:
loop1:
image: busybox
command: ["/bin/sh", "-c", "for i in `seq 1 10000`; do echo \"loop1: $$i\"; sleep 1; done"]
loop2:
image: busybox
command: ["/bin/sh", "-c", "for i in `seq 1 10000`; do echo \"loop2: $$i\"; sleep 3; done"]

View File

@@ -0,0 +1,15 @@
version: "3.7"
services:
touch:
image: busybox
command: 'touch /mnt/test'
volumes:
- ./:/mnt
user: 999:999
x-podman:
uidmaps:
- "0:1:1"
- "999:0:1"
gidmaps:
- "0:1:1"
- "999:0:1"

View File

@@ -4,6 +4,7 @@ services:
image: busybox image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8000"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8000"]
working_dir: /var/www/html working_dir: /var/www/html
restart: always
volumes: volumes:
- /var/www/html - /var/www/html
tmpfs: tmpfs:
@@ -12,9 +13,10 @@ services:
web1: web1:
image: busybox image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8001"]
restart: unless-stopped
working_dir: /var/www/html working_dir: /var/www/html
volumes: volumes:
- myvol1:/var/www/html:ro - myvol1:/var/www/html:ro,z
web2: web2:
image: busybox image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"] command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8002"]
@@ -32,6 +34,7 @@ services:
- data3:/var/www/html_data3 - data3:/var/www/html_data3
volumes: volumes:
myvol1:
myvol2: myvol2:
labels: labels:
mylabel: myval mylabel: myval

View File

@@ -0,0 +1,7 @@
version: "3"
services:
web:
volumes:
- ./override.txt:/var/www/html/index.html:ro,z
- ./override.txt:/var/www/html/index2.html:z
- ./override.txt:/var/www/html/index3.html

View File

@@ -0,0 +1,11 @@
version: "3"
services:
web:
image: busybox
command: ["/bin/busybox", "httpd", "-f", "-h", "/var/www/html", "-p", "8080"]
ports:
- 8080:8080
volumes:
- ./index.txt:/var/www/html/index.html:ro,z
- ./index.txt:/var/www/html/index2.html
- ./index.txt:/var/www/html/index3.html:ro

View File

@@ -0,0 +1 @@
The file from docker-compose.yaml

View File

@@ -0,0 +1 @@
The file from docker-compose.override.yaml