16 Commits

Author SHA1 Message Date
e6accb0eb7 release 0.1.11 2021-12-21 23:09:44 +02:00
b5e47230ef add awx 17 example 2021-12-21 22:54:27 +02:00
18876d2c09 FIXES #377: down -v 2021-12-21 22:44:34 +02:00
1fcf4fe6e1 FIXES #: U mount propagation option 2021-12-21 22:13:40 +02:00
544fd7fe12 #365: 'Namespace' object has no attribute 'volumes' 2021-12-21 22:02:59 +02:00
e9b103eb23 release v0.1.10 2021-12-11 02:02:59 +02:00
bbaa786739 Fixes #199: seccomp:unconfined 2021-12-11 02:02:09 +02:00
d1d0f9e452 FIXES #371: respect COMPOSE_FILE env 2021-12-11 02:02:00 +02:00
d8dba61e08 FIXES #185: creates dirs 2021-12-11 02:01:44 +02:00
3343910763 resolve 2021-12-11 02:01:19 +02:00
34ec4b3cb9 #222: normalize basedir using os.path.realpath 2021-12-11 01:54:22 +02:00
f4a78ae812 FIXES #333: when volumes are merged, remove duplicates 2021-12-11 01:54:09 +02:00
00b9ce1ee4 FIXES #368: parse depends_on of type dict 2021-12-11 01:53:27 +02:00
749d188321 fix AttributeError when running a one-off command
Without this, I get errors when running "podman-compose -p podname run".
2021-12-04 00:47:09 +02:00
e879529976 Remove named volumes during "down -v"
Fixes containers#105

Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
2021-11-23 08:02:10 +02:00
1555417958 FIXES #361: key error _service 2021-11-21 15:55:19 +02:00
350 changed files with 1421 additions and 14777 deletions

View File

@ -1 +0,0 @@
assertIn

View File

@ -1,4 +0,0 @@
[codespell]
skip = .git,*.pdf,*.svg,requirements.txt,test-requirements.txt
# poped - loved variable name
ignore-words-list = poped

View File

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

View File

@ -1,19 +0,0 @@
root = true
[*]
indent_style = space
indent_size = tab
tab_width = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.py]
indent_style = space

View File

@ -13,6 +13,8 @@ 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.)
@ -33,7 +35,7 @@ What is the behavior you actually got and that should not happen.
```
$ podman-compose version
using podman version: 3.4.0
podman-compose version 0.1.7dev
podman-composer version 0.1.7dev
podman --version
podman version 3.4.0

View File

@ -1,10 +0,0 @@
## Contributor Checklist:
If this PR adds a new feature that improves compatibility with docker-compose, please add a link
to the exact part of compose spec that the PR touches.
For any user-visible change please add a release note to newsfragments directory, e.g.
newsfragments/my_feature.feature. See newsfragments/README.md for more details.
All changes require additional unit tests.

View File

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

View File

@ -1,22 +0,0 @@
---
name: Codespell
on:
push:
pull_request:
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Codespell
uses: codespell-project/actions-codespell@v2
with:
ignore_words_file: .codespellignore

View File

@ -1,27 +0,0 @@
name: Build and Release
on:
push:
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build binary
run: |
mkdir -p release/
docker build -t podman-compose-bin -v "$PWD/release:/result" .
mv "$PWD/release/podman-compose" "$PWD/release/podman-compose-linux-x86"
- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: ./release/podman-compose-linux-x86
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,25 +0,0 @@
name: Static checks
on:
- push
- pull_request
jobs:
static-checks:
runs-on: ubuntu-latest
container:
image: docker.io/library/python:3.11-bookworm
# cgroupns needed to address the following error:
# write /sys/fs/cgroup/cgroup.subtree_control: operation not supported
options: --privileged --cgroupns=host
steps:
- uses: actions/checkout@v4
- name: Analysing the code with ruff
run: |
set -e
pip install -r test-requirements.txt
ruff format --check
ruff check
- name: Analysing the code with pylint
run: |
pylint podman_compose.py

View File

@ -1,40 +0,0 @@
name: Tests
on:
push:
pull_request:
jobs:
test:
strategy:
fail-fast: false
matrix:
python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
runs-on: ubuntu-latest
container:
image: "docker.io/library/python:${{ matrix.python-version }}-bookworm"
# cgroupns needed to address the following error:
# write /sys/fs/cgroup/cgroup.subtree_control: operation not supported
options: --privileged --cgroupns=host
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
set -e
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y podman
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r test-requirements.txt
- name: Run integration tests
run: |
python -m unittest discover -v tests/integration
env:
TESTS_DEBUG: 1
- name: Run unit tests
run: |
coverage run --source podman_compose -m unittest discover tests/unit
- name: Report coverage
run: |
coverage combine
coverage report --format=markdown | tee -a $GITHUB_STEP_SUMMARY

5
.gitignore vendored
View File

@ -47,8 +47,6 @@ coverage.xml
*.cover
.hypothesis/
.pytest_cache/
test-compose.yaml
test-compose-?.yaml
# Translations
*.mo
@ -105,6 +103,3 @@ venv.bak/
# mypy
.mypy_cache/
.vscode

View File

@ -1,34 +0,0 @@
default_install_hook_types: [pre-commit, commit-msg]
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.6
hooks:
- id: ruff
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
]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
hooks:
- id: codespell
- repo: https://github.com/gklein/check_signoff
rev: v1.0.5
hooks:
- id: check-signoff

View File

@ -1,18 +1,13 @@
[MESSAGES CONTROL]
# 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,broad-exception-caught
disable=W0614,C0410,C0321,C0111,I0011,C0103
# 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, ix for index
# allow ip for ip address
# allow e for exceptions, it for iterator
# 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
# 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
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

View File

@ -1,135 +1,74 @@
# Contributing to podman-compose
## Who can contribute?
- Users that found a bug,
- Users that want 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.
## Development environment setup
Note: Some steps are OPTIONAL but all are RECOMMENDED.
1. Fork the project repository and clone it:
```shell
$ git clone https://github.com/USERNAME/podman-compose.git
$ cd podman-compose
```
2. (OPTIONAL) Create a Python virtual environment. Example using
[virtualenv wrapper](https://virtualenvwrapper.readthedocs.io/en/latest/):
```shell
$ mkvirtualenv podman-compose
```
3. Install the project runtime and development requirements:
```shell
$ pip install '.[devel]'
```
4. (OPTIONAL) Install `pre-commit` git hook scripts
(https://pre-commit.com/#3-install-the-git-hook-scripts):
```shell
$ pre-commit install
```
5. Create a new branch, develop and add tests when possible.
6. Run linting and testing before committing code. Ensure all the hooks are passing.
```shell
$ pre-commit run --all-files
```
7. Run code coverage:
```shell
$ coverage run --source podman_compose -m unittest discover tests/unit
$ python3 -m unittest discover tests/integration
$ coverage combine
$ coverage report
$ coverage html
```
8. Commit your code to your fork's branch.
- Make sure you include a `Signed-off-by` message in your commits.
Read [this guide](https://github.com/containers/common/blob/main/CONTRIBUTING.md#sign-your-prs)
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`
9. Open a pull request to `containers/podman-compose` 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`.
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
The decorated function must be declared `async` and should accept two arguments: The compose
instance and the command-specific arguments (resulted from the Python's `argparse` package).
In this function, you can run Podman (e.g. `await compose.podman.run(['inspect', 'something'])`),
access `compose.pods`, `compose.containers` etc.
Here is an example:
```python
```
@cmd_run(podman_compose, 'build', 'build images defined in the stack')
async def compose_build(compose, args):
await compose.podman.run(['build', 'something'])
def compose_build(compose, args):
compose.podman.run(['build', 'something'])
```
## Command arguments parsing
To add arguments to be parsed by a command, you need to add a function that is decorated with
`@cmd_parse` which accepts the compose instance and the command's name (as a string list or as a
single string).
Add a function that accept `parser` which is an instance from `argparse`.
In side that function you can call `parser.add_argument()`.
The function decorated with `@cmd_parse` accepting the compose instance,
and command names (as a list or as a string).
You can do this multiple times.
The decorated function should accept a single argument: An instance of `argparse`.
Here is an example
In this function, you can call `parser.add_argument()` to add a new argument to the command.
Note you can add such a function multiple times.
Here is an example:
```python
```
@cmd_parse(podman_compose, 'build')
def compose_build_parse(parser):
parser.add_argument("--pull",
help="attempt to pull a newer version of the image", action='store_true')
parser.add_argument("--pull-always",
help="Attempt to pull a newer version of the image, "
"raise an error even if the image is present locally.",
action='store_true')
help="attempt to pull a newer version of the image, Raise an error even if the image is present locally.", action='store_true')
```
NOTE: `@cmd_parse` should be after `@cmd_run`.
NOTE: `@cmd_parse` should be after `@cmd_run`
## Calling a command from another one
## Calling a command from inside another
If you need to call `podman-compose down` from `podman-compose up`, do something like:
If you need to call `podman-compose down` from inside `podman-compose up`
do something like:
```python
```
@cmd_run(podman_compose, 'up', 'up desc')
async def compose_up(compose, args):
await compose.commands['down'](compose, args)
def compose_up(compose, args):
compose.commands['down'](compose, args)
# or
await compose.commands['down'](argparse.Namespace(foo=123))
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
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,30 +0,0 @@
# Use a base image with necessary build tools
FROM python:3.11-slim AS builder
# Install required packages for building
RUN apt-get update && apt-get install -y \
gcc \
musl-dev \
build-essential \
python3-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set the working directory
WORKDIR /app
# Copy the application code
COPY . .
# Install PyInstaller
RUN pip install pyinstaller
RUN pip install -r requirements.txt
# Create a binary with PyInstaller
RUN pyinstaller --onefile --clean podman_compose.py
# Create /result dir in case it is not mounted
RUN mkdir -p /result
# Export binary
RUN cp /app/dist/podman_compose /result/podman-compose

View File

@ -1,62 +1,46 @@
# Podman Compose
## [![Tests](https://github.com/containers/podman-compose/actions/workflows/test.yml/badge.svg)](https://github.com/containers/podman-compose/actions/workflows/test.yml)
An implementation of [Compose Spec](https://compose-spec.io/) with [Podman](https://podman.io/) backend.
This project focuses on:
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:
* rootless
* daemon-less process model, we directly execute podman, no running daemon.
- can run rootless
- no daemon, no setup.
- can be used by developers to run single-machine containerized stacks using single familiar YAML file
This project only depends on:
This project only depend 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. This is not necessary when podman is using
netavark as a network backend.
* 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.
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/).
OpenShift/Kubernetes distribution like [OKD](https://www.okd.io/minishift/).
## 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.
If you have legacy version of `podman` (before 3.x) 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.
Modern podman versions (>=3.4) do not have those limitations and thus you can use latest and stable 1.x branch.
## Installation
### Pip
Install latest stable version from PyPI:
Install the latest stable version from PyPI:
```bash
```
pip3 install podman-compose
```
@ -64,50 +48,37 @@ pass `--user` to install inside regular user home without being root.
Or latest development version from GitHub:
```bash
pip3 install https://github.com/containers/podman-compose/archive/main.tar.gz
```
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz
```
### Homebrew
or
```bash
brew install podman-compose
```
### Generate binary using docker/podman locally
This script will download the repo, generate the binary using [this Dockerfile](https://github.com/containers/podman-compose/blob/main/Dockerfile), and place the binary in the directory where you called this script.
```bash
sh -c "$(curl -sSL https://raw.githubusercontent.com/containers/podman-compose/main/scripts/download_and_build_podman-compose.sh)"
```
### Manual
```bash
curl -o /usr/local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/main/podman_compose.py
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 inside your home
or
```bash
curl -o ~/.local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/main/podman_compose.py
```
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:
```bash
```
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
```bash
```
cd examples/busybox
podman-compose --help
podman-compose up --help
@ -124,21 +95,19 @@ which have
- a django tasks
When testing the `AWX3` example, if you got errors, just wait for db migrations to end.
There is also AWX 17.1.0
When testing the `AWX3` example, if you got errors just wait for db migrations to end.
## Tests
Inside `tests/` directory we have many useless docker-compose stacks
that are meant to test as many cases as we can to make sure we are compatible
that are meant to test as much cases as we can to make sure we are compatible
### Unit tests with unittest
run a unittest with following command
## How it works
```shell
python3 -m unittest discover tests/unit
```
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).
# Contributing guide
If you are running as root, you might use identity mapping.
If you are a user or a developer and want to contribute please check the [CONTRIBUTING](CONTRIBUTING.md) section

View File

@ -1,47 +0,0 @@
Creating a release
==================
This file contains instructions for maintainers on how to release new versions of podman-compose.
Step 1: Initialize variables for subsequent steps
-------------------------------------------------
```
export VERSION=1.2.3
```
Step 2: Release notes PR
------------------------
Open a new branch (e.g. `release`) and run the following:
```
./scripts/make_release_notes.sh $VERSION
```
This collects the release notes using the `towncrier` tool and then commits the result.
This step is done as a PR so that CI can check for spelling errors and similar issues.
Certain file names are not properly supported by the `towncrier` tool and it ignores them.
Check `newsfragments` directory for any forgotten release notes
Step 3: Merge the release notes PR
----------------------------------
Step 4: Perform actual release
------------------------------
Pull the merge commit created on the `main` branch during the step 2.
Then run:
```
./scripts/make_release.sh $VERSION
```
This will create release commit, tag and push everything.
Step 5: Create a release on Github
----------------------------------
The release notes must be added manually by drafting a release on the GitHub UI at
https://github.com/containers/podman-compose/releases.

View File

@ -1,411 +0,0 @@
# 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

@ -1,33 +0,0 @@
Version v1.1.0 (2024-04-17)
===========================
Bug fixes
---------
- Fixed support for values with equals sign in `-e` argument of `run` and `exec` commands.
- Fixed duplicate arguments being emitted in `stop` and `restart` commands.
- Removed extraneous debug output. `--verbose` flag has been added to preserve verbose output.
- Links aliases are now added to service aliases.
- Fixed image build process to use defined environmental variables.
- Empty list is now allowed to be `COMMAND` and `ENTRYPOINT`.
- Environment files are now resolved relative to current working directory.
- Exit code of container build is now preserved as return code of `build` command.
New features
------------
- Added support for `uidmap`, `gidmap`, `http_proxy` and `runtime` service configuration keys.
- Added support for `enable_ipv6` network configuration key.
- Added `--parallel` option to support parallel pulling and building of images.
- Implemented support for maps in `sysctls` container configuration key.
- Implemented `stats` command.
- Added `--no-normalize` flag to `config` command.
- Added support for `include` global configuration key.
- Added support for `build` command.
- Added support to start containers with multiple networks.
- Added support for `profile` argument.
- Added support for starting podman in existing network namespace.
- Added IPAM driver support.
- Added support for file secrets being passed to `podman build` via `--secret` argument.
- Added support for multiple networks with separately specified IP and MAC address.
- Added support for `service.build.ulimits` when building image.

View File

@ -1,40 +0,0 @@
Version v1.2.0 (2024-06-26)
===========================
Bug fixes
---------
- Fixed handling of `--in-pod` argument. Previously it was hard to provide false value to it.
- podman-compose no longer creates pods when registering systemd unit.
- Fixed warning `RuntimeWarning: coroutine 'create_pods' was never awaited`
- Fixed error when setting up IPAM network with default driver.
- Fixed support for having list and dictionary `depends_on` sections in related compose files.
- Fixed logging of failed build message.
- Fixed support for multiple entries in `include` section.
- Fixed environment variable precedence order.
Changes
-------
- `x-podman` dictionary in container root has been migrated to `x-podman.*` fields in container root.
New features
------------
- Added support for `--publish` in `podman-compose run`.
- Added support for Podman external root filesystem management (`--rootfs` option).
- Added support for `podman-compose images` command.
- Added support for `env_file` being configured via dictionaries.
- Added support for enabling GPU access.
- Added support for selinux in verbose mount specification.
- Added support for `additional_contexts` section.
- Added support for multi-line environment files.
- Added support for passing contents of `podman-compose.yml` via stdin.
- Added support for specifying the value for `--in-pod` setting in `podman-compose.yml` file.
- Added support for environmental secrets.
Documentation
-------------
- Added instructions on how to install podman-compose on Homebrew.
- Added explanation that netavark is an alternative to dnsname plugin

View File

@ -1,38 +0,0 @@
Version 1.3.0 (2025-01-07)
==========================
Bug fixes
---------
- Fixed support for de-facto alternative `Dockerfile` names (e.g. `Containerfile`)
- Fixed a bug that caused attempts to create already existing pods multiple times.
- Fixed compatibility with docker-compose in how symlinks to docker-compose.yml are handled.
- Fixed freeze caused by too long log lines without a newline.
- Fixed support for `network_mode: none`.
- Improved error detection by rejecting service definitions that contain both `network_mode` and
`networks` keys, which is not allowed.
Features
--------
- Added support for build labels.
- Added support for "platform" property in the build command.
- Added support for "ssh" property in the build command.
- Added support for cache_from and cache_to fields in build section.
- Added support for honoring the condition in the depends_on section of the service, if stated.
- Added `x-podman.no_hosts` setting to pass `--no-hosts` to podman run
- Added support for compatibility with docker compose for default network behavior when no network
defined in service. This is controlled via `default_net_behavior_compat` feature flag.
- Added a way to get compatibility of default network names with docker compose.
This is selected by setting `default_net_name_compat: true` on `x-podman` global dictionary.
- Added support for the `device_cgroup_rules` property in services.
- Added support for removing networks in `podman-compose down`.
- Added support for network scoped service aliases.
- Added support for network level `mac_address` attribute.
- Added ability to substitute variables with the environment of the service.
Misc
----
- Declared compatibility with Python 3.13.

View File

@ -1,39 +0,0 @@
Version 1.4.0 (2025-05-10)
==========================
Bug fixes
---------
- Fixed handling of relative includes and extends in compose files
- Fixed error when merging arguments in list and dictionary syntax
- Fixed issue where short-lived containers could execute twice when using `up` in detached mode
- Fixed `up` command hanging on Podman versions earlier than 4.6.0
- Fixed issue where `service_healthy` conditions weren't enforced during `up` command
- Fixed support for the `--scale` flag
- Fixed bug causing dependent containers to start despite `--no-deps` flag
- Fixed port command behavior for dynamic host ports
- Fixed interpolation of `COMPOSE_PROJECT_NAME` when set from top-level `name` in compose file
- Fixed project name evaluation order to match compose spec
- Fixed build context when using git URLs
- Fixed `KeyError` when `down` is called with non-existent service
- Skip `down` during `up` when no active containers exist
- Fixed non-zero exit code on failure when using `up -d`
- Fixed SIGINT handling during `up` command for graceful shutdown
- Fixed `NotImplementedError` when interrupted on Windows
Features
--------
- Added `--quiet` flag to `config` command to suppress output
- Added support for `pids_limit` and `deploy.resources.limits.pids`
- Added `--abort-on-container-failure` option
- Added `--rmi` argument to `down` command for image removal
- Added support for `x-podman.disable-dns` to disable DNS plugin on defined networks
- Added support for `x-podman.dns` to set DNS nameservers for defined networks
- Improved file descriptor handling - no longer closes externally created descriptors.
This allows descriptors created e.g. via systemd socket activation to be passed to
containers.
- Added support for `cpuset` configuration
- Added support for `reset` and `override` tags when merging compose files
- Added support for `x-podman.interface_name` to set network interface names
- Added support for `x-podman.pod_args` to override default `--pod-args`

View File

@ -1,7 +0,0 @@
Version 1.4.1 (2025-06-05)
==========================
Bug fixes
---------
- Fixed relative host path resolution for volume bind mount source

View File

@ -1,194 +0,0 @@
# Podman specific extensions to the docker-compose format
Podman-compose supports the following extension to the docker-compose format. These extensions
are generally specified under fields with "x-podman" prefix in the compose file.
## Container management
The following extension keys are available under container configuration:
* `x-podman.uidmaps` - Run the container in a new user namespace using the supplied UID mapping.
* `x-podman.gidmaps` - Run the container in a new user namespace using the supplied GID mapping.
* `x-podman.rootfs` - Run the container without requiring any image management; the rootfs of the
container is assumed to be managed externally.
* `x-podman.no_hosts` - Run the container without creating /etc/hosts file
For example, the following docker-compose.yml allows running a podman container with externally managed rootfs.
```yml
version: "3"
services:
my_service:
command: ["/bin/busybox"]
x-podman.rootfs: "/path/to/rootfs"
```
For explanations of these extensions, please refer to the [Podman Documentation](https://docs.podman.io/).
## Network management
The following extension keys are available under network configuration:
* `x-podman.disable-dns` - Disable the DNS plugin for the network when set to 'true'.
* `x-podman.dns` - Set nameservers for the network using supplied addresses (cannot be used with x-podman.disable-dns`).
For example, the following docker-compose.yml allows all containers on the same network to use the
specified nameservers:
```yml
version: "3"
network:
my_network:
x-podman.dns:
- "10.1.2.3"
- "10.1.2.4"
```
For explanations of these extensions, please refer to the
[Podman network create command Documentation](https://docs.podman.io/en/latest/markdown/podman-network-create.1.html).
## Per-network MAC-addresses
Generic docker-compose files support specification of the MAC address on the container level. If the
container has multiple network interfaces, the specified MAC address is applied to the first
specified network.
Podman-compose in addition supports the specification of MAC addresses on a per-network basis. This
is done by adding a `x-podman.mac_address` key to the network configuration in the container. The
value of the `x-podman.mac_address` key is the MAC address to be used for the network interface.
Note that the [compose spec](https://github.com/compose-spec/compose-spec/blob/main/05-services.md#mac_address)
now supports `mac_address` on the network level, so we recommend using
the standard `mac_address` key for setting the MAC address. The
`x-podman.mac_address` is still supported for backwards compatibility.
Specifying a MAC address for the container and for individual networks at the same time is not
supported.
Example:
```yaml
---
version: "3"
networks:
net0:
driver: "bridge"
ipam:
config:
- subnet: "192.168.0.0/24"
net1:
driver: "bridge"
ipam:
config:
- subnet: "192.168.1.0/24"
services:
webserver:
image: "busybox"
command: ["/bin/busybox", "httpd", "-f", "-h", "/etc", "-p", "8001"]
networks:
net0:
ipv4_address: "192.168.0.10"
x-podman.mac_address: "02:aa:aa:aa:aa:aa"
net1:
ipv4_address: "192.168.1.10"
mac_address: "02:bb:bb:bb:bb:bb" # mac_address is supported
```
## Per-network interface name
Using `x-podman.interface_name` within a containers network config you can specify the interface name inside the container.
## Podman-specific network modes
Generic docker-compose supports the following values for `network-mode` for a container:
- `bridge`
- `host`
- `none`
- `service`
- `container`
In addition, podman-compose supports the following podman-specific values for `network-mode`:
- `slirp4netns[:<options>,...]`
- `ns:<options>`
- `pasta[:<options>,...]`
- `private`
The options to the network modes are passed to the `--network` option of the `podman create` command
as-is.
## Compatibility of default network names between docker-compose and podman-compose
Current versions of podman-compose may produce different default external network names than
docker-compose under certain conditions. Specifically, docker-compose removes dashes (`-` character)
from project name.
To enable compatibility between docker-compose and podman-compose, specify
`default_net_name_compat: true` under global `x-podman` key:
```
x-podman:
default_net_name_compat: true
```
By default `default_net_name_compat` is `false`. This will change to `true` at some point and the
setting will be removed.
## Compatibility of default network behavior between docker-compose and podman-compose
When there is no network defined (neither network-mode nor networks) in service,
The behavior of default network in docker-compose and podman-compose are different.
| Top-level networks | podman-compose | docker-compose |
| ------------------------------ | -------------------------- | -------------- |
| No networks | default | default |
| One network named net0 | net0 | default |
| Two networks named net0, net1 | podman(`--network=bridge`) | default |
| Contains network named default | default | default |
To enable compatibility between docker-compose and podman-compose, specify
`default_net_behavior_compat: true` under global `x-podman` key:
```yaml
x-podman:
default_net_behavior_compat: true
```
## Custom pods management
Podman-compose can have containers in pods. This can be controlled by extension key x-podman in_pod.
It allows providing custom value for --in-pod and is especially relevant when --userns has to be set.
For example, the following docker-compose.yml allows using userns_mode by overriding the default
value of --in-pod (unless it was specifically provided by "--in-pod=True" in command line interface).
```yml
version: "3"
services:
cont:
image: nopush/podman-compose-test
userns_mode: keep-id:uid=1000
command: ["dumb-init", "/bin/busybox", "httpd", "-f", "-p", "8080"]
x-podman:
in_pod: false
```
It is also possible to override the default arguments for pod creation that are
used when --pod-args is not passed on the command line:
```yml
version: "3"
services:
cont:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "httpd", "-f", "-p", "8080"]
x-podman:
pod_args: ["--infra=false", "--share=", "--cpus=1"]
```
When not set in docker-compose.yml or on the command line, the pod args default
to `["--infra=false", "--share="]`.

View File

@ -1,7 +1,7 @@
---
- name: Manage AWX Container Images
block:
- name: Export Docker awx image if it isn't local and there isn't a registry defined
- name: Export Docker awx image if it isnt local and there isnt a registry defined
docker_image:
name: "{{ awx_image }}"
tag: "{{ awx_version }}"

View File

@ -1,17 +0,0 @@
# 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

@ -1,16 +0,0 @@
---
# 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"

View File

@ -1,9 +0,0 @@
---
version: '3'
services:
dummy:
build:
context: .
dockerfile_inline: |
FROM alpine
RUN echo "hello world"

View File

@ -1,31 +0,0 @@
# 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

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

View File

@ -1,12 +0,0 @@
# 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

@ -1,67 +0,0 @@
---
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

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

View File

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

View File

@ -1,12 +0,0 @@
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

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

View File

@ -1,39 +0,0 @@
# pylint: disable=import-error
# pylint: disable=unused-import
import asyncio # noqa: F401
import os
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

@ -1,21 +0,0 @@
---
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

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

View File

@ -1,71 +0,0 @@
{
"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"]
}
}

View File

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

View File

@ -1 +0,0 @@
*

View File

@ -1,16 +0,0 @@
# 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

@ -1,12 +0,0 @@
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

@ -1,48 +0,0 @@
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

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

View File

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

View File

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

View File

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

View File

@ -1,31 +0,0 @@
"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

@ -1,21 +0,0 @@
"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

@ -1,24 +0,0 @@
{
"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

@ -1,18 +0,0 @@
<!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

@ -1,11 +0,0 @@
services:
test:
image: nvidia/cuda:12.3.1-base-ubuntu20.04
command: nvidia-smi
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]

View File

@ -1,24 +0,0 @@
---
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

View File

@ -1,13 +0,0 @@
This is the directory for news fragments used by towncrier: https://github.com/hawkowl/towncrier
You create a news fragment in this directory when you make a change, and the file gets removed from
this directory when the news is published.
towncrier has a few standard types of news fragments, signified by the file extension. These are:
.feature: Signifying a new feature.
.bugfix: Signifying a bug fix.
.doc: Signifying a documentation improvement.
.removal: Signifying a deprecation or removal of public API.
.change: Signifying a change of behavior
.misc: Miscellaneous change

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
[tool.ruff]
line-length = 100
target-version = "py38"
[tool.ruff.lint]
select = ["W", "E", "F", "I"]
ignore = [
]
[tool.ruff.lint.isort]
force-single-line = true
[tool.ruff.format]
preview = true # needed for quote-style
quote-style = "preserve"
[tool.towncrier]
package = "podman_compose"
package_dir = "master"
directory = "newsfragments"
filename = "docs/Changelog-new.md"
template = "scripts/Changelog-template.jinja"
title_format = "Version {version} ({project_date})"
[[tool.towncrier.section]]
path = ""
[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true
[[tool.towncrier.type]]
directory = "change"
name = "Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "bugfix"
name = "Bug fixes"
showcontent = true
[[tool.towncrier.type]]
directory = "doc"
name = "Improved Documentation"
showcontent = true
[[tool.towncrier.type]]
directory = "removal"
name = "Deprecations and Removals"
showcontent = true
[[tool.towncrier.type]]
directory = "misc"
name = "Misc"
showcontent = true

View File

@ -1,33 +0,0 @@
{% for section, _ in sections|dictsort(by='key') %}
{% set underline = "-" %}
{% if section %}
{{section}}
{{ underline * section|length }}{% set underline = "~" %}
{% endif %}
{% if sections[section] %}
{% for category, val in definitions|dictsort if category in sections[section]%}
{{ definitions[category]['name'] }}
{{ underline * definitions[category]['name']|length }}
{% for text, values in sections[section][category]|dictsort(by='value') %}
- {{ text }}
{% endfor %}
{% if sections[section][category]|length == 0 %}
No significant changes.
{% else %}
{% endif %}
{% endfor %}
{% else %}
No significant changes.
{% endif %}
{% endfor %}
(venv) p12@exec-desktop:~/cod

View File

@ -1,16 +0,0 @@
#!/bin/sh
# Delete repository dir
rm -rf podman-compose-src
# Clone repository
git clone https://github.com/containers/podman-compose podman-compose-src
# Generate binary
sh podman-compose-src/scripts/generate_binary_using_dockerfile.sh
# Move binary outside repo's dir
mv podman-compose-src/podman-compose .
# Delete repository dir
rm -rf podman-compose-src

View File

@ -1,57 +0,0 @@
#!/bin/sh
# Find an available container tool (docker or podman)
find_container_tool() {
if command -v docker > /dev/null 2>&1; then
echo "sudo docker"
elif command -v podman > /dev/null 2>&1; then
echo "podman"
else
echo "Error: Neither docker nor podman is available." >&2
exit 1
fi
}
# Determine which container tool to use
CONTAINER_TOOL=$(find_container_tool)
# Locate the directory containing dockerfile (root)
PROJECT_ROOT_DIR="$(cd "$(dirname "$0")" && pwd)/.."
# Check SELinux status and set appropriate mount option
check_selinux() {
if command -v getenforce > /dev/null 2>&1; then
SELINUX_STATUS=$(getenforce)
if [ "$SELINUX_STATUS" = "Enforcing" ] || [ "$SELINUX_STATUS" = "Permissive" ]; then
echo ":z"
else
echo ""
fi
elif [ -f /sys/fs/selinux/enforce ]; then
if [ "$(cat /sys/fs/selinux/enforce)" = "1" ]; then
echo ":z"
else
echo ""
fi
else
echo ""
fi
}
# Get the SELinux option for volume mounts if SELinux is enforcing or permissive
SELINUX=$(check_selinux)
# Build binary
$CONTAINER_TOOL image rm build-podman-compose
if expr "$CONTAINER_TOOL" : '.*docker.*' >/dev/null; then
$CONTAINER_TOOL build -t build-podman-compose "$PROJECT_ROOT_DIR"
$CONTAINER_TOOL run --name build-podman-compose build-podman-compose
$CONTAINER_TOOL cp build-podman-compose:/result/podman-compose "$PROJECT_ROOT_DIR/podman-compose"
$CONTAINER_TOOL container stop build-podman-compose
$CONTAINER_TOOL container rm -f build-podman-compose
else
$CONTAINER_TOOL build -v "$PROJECT_ROOT_DIR:/result$SELINUX" -t build-podman-compose "$PROJECT_ROOT_DIR"
fi
$CONTAINER_TOOL image rm python:3.11-slim
$CONTAINER_TOOL image rm build-podman-compose

View File

@ -1,18 +1,6 @@
#!/bin/bash
set -e
if [ $# -ne 1 ]; then
echo "Usage: make_release.sh VERSION"
exit 1
fi
VERSION=$1
sed "s/__version__ = .*/__version__ = \"$VERSION\"/g" -i podman_compose.py
git add podman_compose.py
git commit -m "Release $VERSION"
git tag "v$VERSION" -m "v$VERSION" -s
git push ssh://github.com/containers/podman-compose main "v$VERSION"
#!/usr/bin/env bash
./scripts/uninstall.sh
./scripts/clean_up.sh
python3 setup.py register
python3 setup.py sdist bdist_wheel
twine upload dist/*

View File

@ -1,14 +0,0 @@
#!/bin/bash
set -e
if [ $# -ne 1 ]; then
echo "Usage: make_release_notes.sh VERSION"
exit 1
fi
VERSION=$1
towncrier build --version "$VERSION" --yes
git mv "docs/Changelog-new.md" "docs/Changelog-$VERSION.md"
git add "newsfragments/"
git commit -m "Release notes for $VERSION"

View File

@ -1,6 +0,0 @@
#!/usr/bin/env bash
./scripts/uninstall.sh
./scripts/clean_up.sh
python3 setup.py register
python3 setup.py sdist bdist_wheel
twine upload dist/*

View File

@ -3,9 +3,3 @@ universal = 1
[metadata]
version = attr: podman_compose.__version__
[flake8]
# The GitHub editor is 127 chars wide
max-line-length=127
# These are not being followed yet
ignore=E222,E231,E272,E713,W503

View File

@ -1,49 +1,49 @@
# SPDX-License-Identifier: GPL-2.0
import os
from setuptools import setup
try:
README = open(os.path.join(os.path.dirname(__file__), "README.md"), encoding="utf-8").read()
except: # noqa: E722 # pylint: disable=bare-except
README = ""
readme = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
except:
readme = ''
setup(
name="podman-compose",
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 :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"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",
"python-dotenv",
'pyyaml',
'python-dotenv',
],
extras_require={"devel": ["ruff", "pre-commit", "coverage", "parameterized"]},
# test_suite='tests',
# tests_require=[
# 'coverage',
# 'pytest-cov',
# 'pytest',
# 'tox',
# ]
)

View File

@ -1,34 +1,8 @@
-e .
coverage==7.4.3
parameterized==0.9.0
pytest==8.0.2
tox==4.13.0
ruff==0.3.1
pylint==3.1.0
# 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.
# The packages below are transitive dependencies of the packages above and are included here
# to make testing reproducible.
# To refresh, create a new virtualenv and do:
# pip install -r requirements.txt -r test-requirements.txt
# pip freeze > test-requirements.txt
# and edit test-requirements.txt to add this comment
astroid==3.1.0
cachetools==5.3.3
chardet==5.2.0
colorama==0.4.6
dill==0.3.8
distlib==0.3.8
filelock==3.13.1
iniconfig==2.0.0
isort==5.13.2
mccabe==0.7.0
packaging==23.2
platformdirs==4.2.0
pluggy==1.4.0
pyproject-api==1.6.1
python-dotenv==1.0.1
PyYAML==6.0.1
requests
tomlkit==0.12.4
virtualenv==20.26.6
coverage
pytest-cov
pytest
tox

25
tests/build/README.md Normal file
View File

@ -0,0 +1,25 @@
# Test podman-compose with build
```
podman-compose build
podman-compose up -d
curl http://localhost:8080/index.txt
curl http://localhost:8000/index.txt
podman inspect my-busybox-httpd2
podman-compose down
```
expected output would be something like
```
2019-09-03T15:16:38+0000
ALT buildno=2 port 8000 2019-09-03T15:16:38+0000
{
...
}
```
as you can see we were able to override buildno to be 2 instead of 1,
and httpd_port to 8000.
NOTE: build labels are not passed to `podman build`

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

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

View File

@ -0,0 +1,24 @@
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,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

@ -1,12 +0,0 @@
import os
import subprocess
def create_base_test_image():
subprocess.check_call(
['podman', 'build', '-t', 'nopush/podman-compose-test', '.'],
cwd=os.path.join(os.path.dirname(__file__), "base_image"),
)
create_base_test_image()

View File

@ -1,11 +0,0 @@
version: "3"
services:
sh1:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 1; exit 1"]
sh2:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 2; exit 0"]
sh3:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 3; exit 0"]

View File

@ -1,11 +0,0 @@
version: "3"
services:
sh1:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 1; exit 0"]
sh2:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 2; exit 0"]
sh3:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 3; exit 0"]

View File

@ -1,11 +0,0 @@
version: "3"
services:
sh1:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 1; exit 0"]
sh2:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 2; exit 1"]
sh3:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 3; exit 0"]

View File

@ -1,11 +0,0 @@
version: "3"
services:
sh1:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 1; exit 1"]
sh2:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 1; exit 0"]
sh3:
image: nopush/podman-compose-test
command: ["dumb-init", "/bin/busybox", "sh", "-c", "sleep 2; exit 0"]

View File

@ -1,46 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
import os
import unittest
from parameterized import parameterized
from tests.integration.test_utils import RunSubprocessMixin
from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path
def compose_yaml_path(failure_order):
return os.path.join(test_path(), "abort", f"docker-compose-fail-{failure_order}.yaml")
class TestComposeAbort(unittest.TestCase, RunSubprocessMixin):
@parameterized.expand([
("exit", "first", 0),
("failure", "first", 1),
("exit", "second", 0),
("failure", "second", 1),
("exit", "simultaneous", 0),
("failure", "simultaneous", 1),
("exit", "none", 0),
("failure", "none", 0),
])
def test_abort(self, abort_type, failure_order, expected_exit_code):
try:
self.run_subprocess_assert_returncode(
[
podman_compose_path(),
"-f",
compose_yaml_path(failure_order),
"up",
f"--abort-on-container-{abort_type}",
],
expected_exit_code,
)
finally:
self.run_subprocess_assert_returncode([
podman_compose_path(),
"-f",
compose_yaml_path(failure_order),
"down",
])

View File

@ -1,14 +0,0 @@
# Test podman-compose with build.additional_contexts
```
podman-compose build
podman-compose up
podman-compose down
```
expected output would be
```
[dict] | Data for dict
[list] | Data for list
```

View File

@ -1 +0,0 @@
Data for dict

View File

@ -1 +0,0 @@
Data for list

View File

@ -1,3 +0,0 @@
FROM busybox
COPY --from=data data.txt /data/data.txt
CMD ["busybox", "cat", "/data/data.txt"]

View File

@ -1,12 +0,0 @@
version: "3.7"
services:
dict:
build:
context: .
additional_contexts:
data: ../data_for_dict
list:
build:
context: .
additional_contexts:
- data=../data_for_list

View File

@ -1,44 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
"""Test how additional contexts are passed to podman."""
import os
import subprocess
import unittest
from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path
def compose_yaml_path():
""" "Returns the path to the compose file used for this test module"""
return os.path.join(test_path(), "additional_contexts", "project")
class TestComposeBuildAdditionalContexts(unittest.TestCase):
def test_build_additional_context(self):
"""podman build should receive additional contexts as --build-context
See additional_context/project/docker-compose.yaml for context paths
"""
cmd = (
"coverage",
"run",
podman_compose_path(),
"--dry-run",
"--verbose",
"-f",
os.path.join(compose_yaml_path(), "docker-compose.yml"),
"build",
)
p = subprocess.run(
cmd,
stdout=subprocess.PIPE,
check=False,
stderr=subprocess.STDOUT,
text=True,
)
self.assertEqual(p.returncode, 0)
self.assertIn("--build-context=data=../data_for_dict", p.stdout)
self.assertIn("--build-context=data=../data_for_list", p.stdout)

View File

@ -1,6 +0,0 @@
FROM docker.io/library/debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y \
dumb-init \
busybox \
wget

View File

@ -1 +0,0 @@

View File

@ -1,9 +0,0 @@
version: "3"
services:
test_context:
build:
context: https://github.com/mokibit/test-git-url-as-context.git
image: test-git-url-as-context
test_context_inline:
build: https://github.com/mokibit/test-git-url-as-context.git
image: test-git-url-as-context-inline

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