mirror of
https://github.com/containers/podman-compose.git
synced 2025-07-04 06:30:10 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
e6accb0eb7 | |||
b5e47230ef | |||
18876d2c09 | |||
1fcf4fe6e1 | |||
544fd7fe12 | |||
e9b103eb23 | |||
bbaa786739 | |||
d1d0f9e452 | |||
d8dba61e08 | |||
3343910763 | |||
34ec4b3cb9 | |||
f4a78ae812 | |||
00b9ce1ee4 | |||
749d188321 | |||
e879529976 | |||
1555417958 |
@ -1 +0,0 @@
|
|||||||
assertIn
|
|
@ -1,4 +0,0 @@
|
|||||||
[codespell]
|
|
||||||
skip = .git,*.pdf,*.svg,requirements.txt,test-requirements.txt
|
|
||||||
# poped - loved variable name
|
|
||||||
ignore-words-list = poped
|
|
@ -1,2 +0,0 @@
|
|||||||
[run]
|
|
||||||
parallel=True
|
|
@ -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
|
|
||||||
|
|
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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)
|
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)
|
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**
|
**To Reproduce**
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
1. what is the content of the current working directory (ex. `docker-compose.yml`, `.env`, `Dockerfile`, ...etc.)
|
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
|
$ podman-compose version
|
||||||
using podman version: 3.4.0
|
using podman version: 3.4.0
|
||||||
podman-compose version 0.1.7dev
|
podman-composer version 0.1.7dev
|
||||||
podman --version
|
podman --version
|
||||||
podman version 3.4.0
|
podman version 3.4.0
|
||||||
|
|
||||||
|
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
10
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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.
|
|
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@ -1,6 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
22
.github/workflows/codespell.yml
vendored
22
.github/workflows/codespell.yml
vendored
@ -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
|
|
27
.github/workflows/release.yml
vendored
27
.github/workflows/release.yml
vendored
@ -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 }}
|
|
25
.github/workflows/static-checks.yml
vendored
25
.github/workflows/static-checks.yml
vendored
@ -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
|
|
40
.github/workflows/test.yml
vendored
40
.github/workflows/test.yml
vendored
@ -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
5
.gitignore
vendored
@ -47,8 +47,6 @@ coverage.xml
|
|||||||
*.cover
|
*.cover
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
test-compose.yaml
|
|
||||||
test-compose-?.yaml
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
@ -105,6 +103,3 @@ venv.bak/
|
|||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
|
||||||
|
|
||||||
.vscode
|
|
||||||
|
@ -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
|
|
11
.pylintrc
11
.pylintrc
@ -1,18 +1,13 @@
|
|||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
# C0111 missing-docstring: missing-class-docstring, missing-function-docstring, missing-method-docstring, missing-module-docstrin
|
disable=W0614,C0410,C0321,C0111,I0011,C0103
|
||||||
# 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
|
|
||||||
# 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, ix for index
|
# allow e for exceptions, it for iterator
|
||||||
# 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
|
||||||
# allow p for pipe
|
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 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
|
|
||||||
|
137
CONTRIBUTING.md
137
CONTRIBUTING.md
@ -1,135 +1,74 @@
|
|||||||
# Contributing to podman-compose
|
# 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
|
## 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')
|
@cmd_run(podman_compose, 'build', 'build images defined in the stack')
|
||||||
async def compose_build(compose, args):
|
def compose_build(compose, args):
|
||||||
await compose.podman.run(['build', 'something'])
|
compose.podman.run(['build', 'something'])
|
||||||
```
|
```
|
||||||
|
|
||||||
## Command arguments parsing
|
## Command arguments parsing
|
||||||
|
|
||||||
To add arguments to be parsed by a command, you need to add a function that is decorated with
|
Add a function that accept `parser` which is an instance from `argparse`.
|
||||||
`@cmd_parse` which accepts the compose instance and the command's name (as a string list or as a
|
In side that function you can call `parser.add_argument()`.
|
||||||
single string).
|
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')
|
@cmd_parse(podman_compose, 'build')
|
||||||
def compose_build_parse(parser):
|
def compose_build_parse(parser):
|
||||||
parser.add_argument("--pull",
|
parser.add_argument("--pull",
|
||||||
help="attempt to pull a newer version of the image", action='store_true')
|
help="attempt to pull a newer version of the image", action='store_true')
|
||||||
parser.add_argument("--pull-always",
|
parser.add_argument("--pull-always",
|
||||||
help="Attempt to pull a newer version of the image, "
|
help="attempt to pull a newer version of the image, Raise an error even if the image is present locally.", action='store_true')
|
||||||
"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')
|
@cmd_run(podman_compose, 'up', 'up desc')
|
||||||
async def compose_up(compose, args):
|
def compose_up(compose, args):
|
||||||
await compose.commands['down'](compose, args)
|
compose.commands['down'](compose, args)
|
||||||
# or
|
# or
|
||||||
await compose.commands['down'](argparse.Namespace(foo=123))
|
compose.commands['down'](argparse.Namespace(foo=123))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Missing Commands (help needed)
|
## Missing Commands (help needed)
|
||||||
|
|
||||||
```
|
```
|
||||||
bundle Generate a Docker bundle from the Compose file
|
bundle Generate a Docker bundle from the Compose file
|
||||||
|
config Validate and view the Compose file
|
||||||
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
|
||||||
|
pause Pause services
|
||||||
|
port Print the public port for a port binding
|
||||||
|
ps List containers
|
||||||
rm Remove stopped containers
|
rm Remove stopped containers
|
||||||
|
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
|
||||||
```
|
```
|
||||||
|
30
Dockerfile
30
Dockerfile
@ -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
|
|
97
README.md
97
README.md
@ -1,62 +1,46 @@
|
|||||||
# Podman Compose
|
# Podman Compose
|
||||||
## [](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.
|
An implementation of `docker-compose` with [Podman](https://podman.io/) backend.
|
||||||
This project focuses on:
|
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
|
- can run rootless
|
||||||
* daemon-less process model, we directly execute podman, no running daemon.
|
- 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`
|
||||||
* [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
|
* 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/).
|
OpenShift/Kubernetes distribution like [OKD](https://www.okd.io/minishift/).
|
||||||
|
|
||||||
## Versions
|
## 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.
|
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
|
||||||
|
|
||||||
### Pip
|
Install latest stable version from PyPI:
|
||||||
|
|
||||||
Install the latest stable version from PyPI:
|
```
|
||||||
|
|
||||||
```bash
|
|
||||||
pip3 install podman-compose
|
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:
|
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
|
|
||||||
```
|
```
|
||||||
|
curl -o /usr/local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/devel/podman_compose.py
|
||||||
### 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
|
|
||||||
chmod +x /usr/local/bin/podman-compose
|
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
|
chmod +x ~/.local/bin/podman-compose
|
||||||
```
|
```
|
||||||
|
|
||||||
or install from Fedora (starting from f31) repositories:
|
or install from Fedora (starting from f31) repositories:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
sudo dnf install podman-compose
|
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
|
||||||
|
|
||||||
```bash
|
```
|
||||||
cd examples/busybox
|
cd examples/busybox
|
||||||
podman-compose --help
|
podman-compose --help
|
||||||
podman-compose up --help
|
podman-compose up --help
|
||||||
@ -124,21 +95,19 @@ 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 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
|
## How it works
|
||||||
run a unittest with following command
|
|
||||||
|
|
||||||
```shell
|
The default mapping `1podfw` creates a single pod and attach all containers to
|
||||||
python3 -m unittest discover tests/unit
|
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
|
|
||||||
|
47
RELEASING.md
47
RELEASING.md
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
|
@ -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`
|
|
@ -1,7 +0,0 @@
|
|||||||
Version 1.4.1 (2025-06-05)
|
|
||||||
==========================
|
|
||||||
|
|
||||||
Bug fixes
|
|
||||||
---------
|
|
||||||
|
|
||||||
- Fixed relative host path resolution for volume bind mount source
|
|
@ -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="]`.
|
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
- name: Manage AWX Container Images
|
- name: Manage AWX Container Images
|
||||||
block:
|
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:
|
docker_image:
|
||||||
name: "{{ awx_image }}"
|
name: "{{ awx_image }}"
|
||||||
tag: "{{ awx_version }}"
|
tag: "{{ awx_version }}"
|
||||||
|
@ -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/)
|
|
||||||
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
version: '3'
|
|
||||||
services:
|
|
||||||
dummy:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile_inline: |
|
|
||||||
FROM alpine
|
|
||||||
RUN echo "hello world"
|
|
@ -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
|
|
||||||
```
|
|
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
version: '3'
|
|
||||||
services:
|
|
||||||
web:
|
|
||||||
image: k8s.gcr.io/echoserver:1.4
|
|
||||||
ports:
|
|
||||||
- "${HOST_PORT:-8080}:8080"
|
|
||||||
|
|
@ -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/)
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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/)
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
version: '3'
|
|
||||||
services:
|
|
||||||
web:
|
|
||||||
image: gcr.io/google-samples/hello-app:1.0
|
|
||||||
ports:
|
|
||||||
- "${HOST_PORT:-8080}:8080"
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
# Simple Python Demo
|
|
||||||
## A Redis counter
|
|
||||||
|
|
||||||
```
|
|
||||||
podman-compose up -d
|
|
||||||
curl localhost:8080/
|
|
||||||
curl localhost:8080/hello.json
|
|
||||||
```
|
|
@ -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()
|
|
@ -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
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
aiohttp
|
|
||||||
aioredis
|
|
||||||
# aioredis[hiredis]
|
|
@ -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"]
|
|
||||||
}
|
|
||||||
}
|
|
5
examples/nodeproj/.gitignore
vendored
5
examples/nodeproj/.gitignore
vendored
@ -1,5 +0,0 @@
|
|||||||
local.env
|
|
||||||
.env
|
|
||||||
*.pid
|
|
||||||
node_modules
|
|
||||||
|
|
1
examples/nodeproj/.home/.gitignore
vendored
1
examples/nodeproj/.home/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*
|
|
@ -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
|
|
||||||
```
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
WEB_LISTEN_PORT=3000
|
|
||||||
# pass UID= your IDE user
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
REDIS_HOST=redis
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
#! /usr/bin/env node
|
|
||||||
"use strict";
|
|
||||||
import {start} from "./lib";
|
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es2020",
|
|
||||||
"module": "es2020",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"allowSyntheticDefaultImports": true
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.js"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"lib/**/*.js"
|
|
||||||
]
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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}`);
|
|
||||||
});
|
|
||||||
}
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
@ -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>
|
|
@ -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]
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
4216
podman_compose.py
4216
podman_compose.py
File diff suppressed because it is too large
Load Diff
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,18 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
./scripts/uninstall.sh
|
||||||
set -e
|
./scripts/clean_up.sh
|
||||||
|
python3 setup.py register
|
||||||
if [ $# -ne 1 ]; then
|
python3 setup.py sdist bdist_wheel
|
||||||
echo "Usage: make_release.sh VERSION"
|
twine upload dist/*
|
||||||
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"
|
|
||||||
|
@ -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"
|
|
@ -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/*
|
|
@ -3,9 +3,3 @@ 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
|
|
||||||
# These are not being followed yet
|
|
||||||
ignore=E222,E231,E272,E713,W503
|
|
48
setup.py
48
setup.py
@ -1,49 +1,49 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
try:
|
try:
|
||||||
README = open(os.path.join(os.path.dirname(__file__), "README.md"), encoding="utf-8").read()
|
readme = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
|
||||||
except: # noqa: E722 # pylint: disable=bare-except
|
except:
|
||||||
README = ""
|
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.9",
|
"Programming Language :: Python :: 3.5",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.6",
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.12",
|
|
||||||
"Programming Language :: Python :: 3.13",
|
|
||||||
"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={"console_scripts": ["podman-compose = podman_compose:main"]},
|
entry_points={
|
||||||
|
'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": ["ruff", "pre-commit", "coverage", "parameterized"]},
|
|
||||||
# test_suite='tests',
|
# test_suite='tests',
|
||||||
# tests_require=[
|
# tests_require=[
|
||||||
# 'coverage',
|
# 'coverage',
|
||||||
|
# 'pytest-cov',
|
||||||
|
# 'pytest',
|
||||||
# 'tox',
|
# 'tox',
|
||||||
# ]
|
# ]
|
||||||
)
|
)
|
||||||
|
@ -1,34 +1,8 @@
|
|||||||
-e .
|
# The order of packages is significant, because pip processes them in the order
|
||||||
coverage==7.4.3
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
parameterized==0.9.0
|
# process, which may cause wedges in the gate later.
|
||||||
pytest==8.0.2
|
|
||||||
tox==4.13.0
|
|
||||||
ruff==0.3.1
|
|
||||||
pylint==3.1.0
|
|
||||||
|
|
||||||
# The packages below are transitive dependencies of the packages above and are included here
|
coverage
|
||||||
# to make testing reproducible.
|
pytest-cov
|
||||||
# To refresh, create a new virtualenv and do:
|
pytest
|
||||||
# pip install -r requirements.txt -r test-requirements.txt
|
tox
|
||||||
# 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
|
|
||||||
|
25
tests/build/README.md
Normal file
25
tests/build/README.md
Normal 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
4
tests/deps/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
```
|
||||||
|
podman-compose run --rm sleep /bin/sh -c 'wget -O - http://localhost:8000/hosts'
|
||||||
|
```
|
24
tests/deps/docker-compose.yaml
Normal file
24
tests/deps/docker-compose.yaml
Normal 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
|
||||||
|
|
5
tests/env-tests/README.md
Normal file
5
tests/env-tests/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
running the following command should give myval2
|
||||||
|
|
||||||
|
```
|
||||||
|
podman_compose run -l monkey -e ZZVAR1=myval2 env-test
|
||||||
|
```
|
9
tests/env-tests/container-compose.yml
Normal file
9
tests/env-tests/container-compose.yml
Normal 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
15
tests/exit-from/README.md
Normal 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.
|
21
tests/exit-from/docker-compose.yaml
Normal file
21
tests/exit-from/docker-compose.yaml
Normal 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
|
||||||
|
|
@ -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()
|
|
@ -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"]
|
|
@ -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"]
|
|
@ -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"]
|
|
@ -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"]
|
|
@ -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",
|
|
||||||
])
|
|
@ -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
|
|
||||||
```
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -1 +0,0 @@
|
|||||||
Data for dict
|
|
@ -1 +0,0 @@
|
|||||||
Data for list
|
|
@ -1,3 +0,0 @@
|
|||||||
FROM busybox
|
|
||||||
COPY --from=data data.txt /data/data.txt
|
|
||||||
CMD ["busybox", "cat", "/data/data.txt"]
|
|
@ -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
|
|
@ -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)
|
|
@ -1,6 +0,0 @@
|
|||||||
FROM docker.io/library/debian:bookworm-slim
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get install -y \
|
|
||||||
dumb-init \
|
|
||||||
busybox \
|
|
||||||
wget
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -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
Reference in New Issue
Block a user