Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Containers
Podman Compose
提交
d1f5ac9e
P
Podman Compose
项目概览
镜像
/
Containers
/
Podman Compose
10 个月 前同步成功
通知
9
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Podman Compose
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
d1f5ac9e
编写于
4月 30, 2023
作者:
S
Sergei Biriukov
提交者:
Muayyad Alsadi
8月 02, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
convert build context path to absolute during final normalisation
Signed-off-by:
N
Sergei Biriukov
<
svbiriukov@gmail.com
>
上级
0164c1db
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
303 addition
and
1 deletion
+303
-1
podman_compose.py
podman_compose.py
+25
-1
pytests/test_normalize_final_build.py
pytests/test_normalize_final_build.py
+278
-0
未找到文件。
podman_compose.py
浏览文件 @
d1f5ac9e
#!
/usr/bin/
python3
#!
/usr/bin/env
python3
# -*- coding: utf-8 -*-
# https://docs.docker.com/compose/compose-file/#service-configuration-reference
...
...
@@ -24,6 +24,7 @@ import json
import
glob
from
threading
import
Thread
from
pathlib
import
Path
import
shlex
...
...
@@ -1297,6 +1298,28 @@ def normalize(compose):
return
compose
def
normalize_service_final
(
service
:
dict
,
project_dir
:
str
)
->
dict
:
if
"build"
in
service
:
build
=
service
[
"build"
]
context
=
build
if
is_str
(
build
)
else
build
.
get
(
"context"
,
"."
)
context
=
str
((
Path
(
project_dir
)
/
context
).
resolve
())
dockerfile
=
"Dockerfile"
if
"dockerfile"
in
service
[
"build"
]:
dockerfile
=
service
[
"build"
][
"dockerfile"
]
if
not
is_dict
(
service
[
"build"
]):
service
[
"build"
]
=
{}
service
[
"build"
][
"dockerfile"
]
=
dockerfile
service
[
"build"
][
"context"
]
=
context
return
service
def
normalize_final
(
compose
:
dict
,
project_dir
:
str
)
->
dict
:
services
=
compose
.
get
(
"services"
,
None
)
or
{}
for
service
in
services
.
values
():
normalize_service_final
(
service
,
project_dir
)
return
compose
def
clone
(
value
):
return
value
.
copy
()
if
is_list
(
value
)
or
is_dict
(
value
)
else
value
...
...
@@ -1603,6 +1626,7 @@ class PodmanCompose:
compose
.
get
(
"services"
,
{}),
set
(
args
.
profile
)
)
compose
[
"services"
]
=
resolved_services
compose
=
normalize_final
(
compose
,
self
.
dirname
)
self
.
merged_yaml
=
yaml
.
safe_dump
(
compose
)
merged_json_b
=
json
.
dumps
(
compose
,
separators
=
(
","
,
":"
)).
encode
(
"utf-8"
)
self
.
yaml_hash
=
hashlib
.
sha256
(
merged_json_b
).
hexdigest
()
...
...
pytests/test_normalize_final_build.py
0 → 100644
浏览文件 @
d1f5ac9e
# pylint: disable=protected-access
import
argparse
import
copy
import
os
from
pathlib
import
Path
import
yaml
from
podman_compose
import
(
normalize_service
,
normalize
,
normalize_final
,
normalize_service_final
,
PodmanCompose
,
)
test_cases_simple_normalization
=
[
({
"image"
:
"test-image"
},
{
"image"
:
"test-image"
}),
(
{
"build"
:
"."
},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"Dockerfile"
},
},
),
(
{
"build"
:
"../relative"
},
{
"build"
:
{
"context"
:
str
((
Path
.
cwd
()
/
"../relative"
).
resolve
()),
"dockerfile"
:
"Dockerfile"
,
},
},
),
(
{
"build"
:
"./relative"
},
{
"build"
:
{
"context"
:
str
((
Path
.
cwd
()
/
"./relative"
).
resolve
()),
"dockerfile"
:
"Dockerfile"
,
},
},
),
(
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
{
"context"
:
"/workspace/absolute"
,
"dockerfile"
:
"Dockerfile"
,
},
},
),
(
{
"build"
:
{
"dockerfile"
:
"Dockerfile"
,
},
},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"Dockerfile"
,
},
},
),
(
{
"build"
:
{
"context"
:
"."
,
},
},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"Dockerfile"
,
},
},
),
(
{
"build"
:
{
"context"
:
"../"
,
"dockerfile"
:
"test-dockerfile"
},
},
{
"build"
:
{
"context"
:
str
((
Path
.
cwd
()
/
"../"
).
resolve
()),
"dockerfile"
:
"test-dockerfile"
,
},
},
),
(
{
"build"
:
{
"context"
:
"."
,
"dockerfile"
:
"./dev/test-dockerfile"
},
},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"./dev/test-dockerfile"
,
},
},
),
]
#
# [service.build] is not normalised before coompose files are merged
#
def
test_pre_merge_normalize_service_does_not_affect_build_section
()
->
None
:
for
test_input
,
_
in
copy
.
deepcopy
(
test_cases_simple_normalization
):
expected_service
=
copy
.
deepcopy
(
test_input
)
actual_service
=
normalize_service
(
test_input
)
assert
expected_service
==
actual_service
def
test_pre_merge_normalize_does_not_affect_build_section
()
->
None
:
for
test_input
,
_
in
copy
.
deepcopy
(
test_cases_simple_normalization
):
expected_result
=
copy
.
deepcopy
(
test_input
)
compose_test
=
{
"services"
:
{
"test-service"
:
test_input
}}
compose_expected
=
{
"services"
:
{
"test-service"
:
expected_result
}}
actual_compose
=
normalize
(
compose_test
)
assert
compose_expected
==
actual_compose
#
# [service.build] is normalised after merges
#
def
test_normalize_service_final_returns_absolute_path_in_context
()
->
None
:
project_dir
=
str
(
Path
.
cwd
().
resolve
())
for
test_input
,
expected_service
in
copy
.
deepcopy
(
test_cases_simple_normalization
):
actual_service
=
normalize_service_final
(
test_input
,
project_dir
)
assert
expected_service
==
actual_service
def
test_normalize_returns_absolute_path_in_context
()
->
None
:
project_dir
=
str
(
Path
.
cwd
().
resolve
())
for
test_input
,
expected_result
in
copy
.
deepcopy
(
test_cases_simple_normalization
):
compose_test
=
{
"services"
:
{
"test-service"
:
test_input
}}
compose_expected
=
{
"services"
:
{
"test-service"
:
expected_result
}}
actual_compose
=
normalize_final
(
compose_test
,
project_dir
)
assert
compose_expected
==
actual_compose
#
# running full parse over single compose files
#
def
test__parse_compose_file_when_single_compose
()
->
None
:
for
test_input
,
expected_result
in
copy
.
deepcopy
(
test_cases_simple_normalization
):
compose_test
=
{
"services"
:
{
"test-service"
:
test_input
}}
dump_yaml
(
compose_test
,
"test-compose.yaml"
)
podman_compose
=
PodmanCompose
()
set_args
(
podman_compose
,
[
"test-compose.yaml"
])
podman_compose
.
_parse_compose_file
()
actual_compose
=
{}
if
podman_compose
.
services
:
podman_compose
.
services
[
"test-service"
].
pop
(
"_deps"
)
actual_compose
=
podman_compose
.
services
[
"test-service"
]
if
actual_compose
!=
expected_result
:
print
(
"compose: "
,
test_input
)
print
(
"result: "
,
expected_result
)
assert
expected_result
==
actual_compose
test_cases_with_merges
=
[
(
{},
{
"build"
:
"."
},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"Dockerfile"
}},
),
(
{
"build"
:
"."
},
{},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"Dockerfile"
}},
),
(
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
"./relative"
},
{
"build"
:
{
"context"
:
str
((
Path
.
cwd
()
/
"./relative"
).
resolve
()),
"dockerfile"
:
"Dockerfile"
,
}
},
),
(
{
"build"
:
"./relative"
},
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
{
"context"
:
"/workspace/absolute"
,
"dockerfile"
:
"Dockerfile"
}},
),
(
{
"build"
:
"./relative"
},
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
{
"context"
:
"/workspace/absolute"
,
"dockerfile"
:
"Dockerfile"
}},
),
(
{
"build"
:
{
"dockerfile"
:
"test-dockerfile"
}},
{},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"test-dockerfile"
}},
),
(
{},
{
"build"
:
{
"dockerfile"
:
"test-dockerfile"
}},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"test-dockerfile"
}},
),
(
{},
{
"build"
:
{
"dockerfile"
:
"test-dockerfile"
}},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"test-dockerfile"
}},
),
(
{
"build"
:
{
"dockerfile"
:
"test-dockerfile-1"
}},
{
"build"
:
{
"dockerfile"
:
"test-dockerfile-2"
}},
{
"build"
:
{
"context"
:
str
(
Path
.
cwd
()),
"dockerfile"
:
"test-dockerfile-2"
}},
),
(
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
{
"dockerfile"
:
"test-dockerfile"
}},
{
"build"
:
{
"context"
:
"/workspace/absolute"
,
"dockerfile"
:
"test-dockerfile"
}},
),
(
{
"build"
:
{
"dockerfile"
:
"test-dockerfile"
}},
{
"build"
:
"/workspace/absolute"
},
{
"build"
:
{
"context"
:
"/workspace/absolute"
,
"dockerfile"
:
"test-dockerfile"
}},
),
]
#
# running full parse over merged and extended compose files
#
def
test__parse_compose_file_when_multiple_composes
()
->
None
:
for
test_input
,
test_override
,
expected_result
in
copy
.
deepcopy
(
test_cases_with_merges
):
compose_test_1
=
{
"services"
:
{
"test-service"
:
test_input
}}
compose_test_2
=
{
"services"
:
{
"test-service"
:
test_override
}}
dump_yaml
(
compose_test_1
,
"test-compose-1.yaml"
)
dump_yaml
(
compose_test_2
,
"test-compose-2.yaml"
)
podman_compose
=
PodmanCompose
()
set_args
(
podman_compose
,
[
"test-compose-1.yaml"
,
"test-compose-2.yaml"
])
podman_compose
.
_parse_compose_file
()
actual_compose
=
{}
if
podman_compose
.
services
:
podman_compose
.
services
[
"test-service"
].
pop
(
"_deps"
)
actual_compose
=
podman_compose
.
services
[
"test-service"
]
if
actual_compose
!=
expected_result
:
print
(
"compose: "
,
test_input
)
print
(
"override: "
,
test_override
)
print
(
"result: "
,
expected_result
)
compose_expected
=
expected_result
assert
compose_expected
==
actual_compose
def
set_args
(
podman_compose
:
PodmanCompose
,
file_names
:
list
[
str
])
->
None
:
podman_compose
.
global_args
=
argparse
.
Namespace
()
podman_compose
.
global_args
.
file
=
file_names
podman_compose
.
global_args
.
project_name
=
None
podman_compose
.
global_args
.
env_file
=
None
podman_compose
.
global_args
.
profile
=
[]
podman_compose
.
global_args
.
in_pod
=
True
def
dump_yaml
(
compose
:
dict
,
name
:
str
)
->
None
:
# Path(Path.cwd()/"subdirectory").mkdir(parents=True, exist_ok=True)
with
open
(
name
,
"w"
,
encoding
=
"utf-8"
)
as
outfile
:
yaml
.
safe_dump
(
compose
,
outfile
,
default_flow_style
=
False
)
def
test_clean_test_yamls
()
->
None
:
test_files
=
[
"test-compose-1.yaml"
,
"test-compose-2.yaml"
,
"test-compose.yaml"
]
for
file
in
test_files
:
if
Path
(
file
).
exists
():
os
.
remove
(
file
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录