From b8e1450a352fba5ce852ec9134569240a8ffe307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hozza?= Date: Mon, 16 Jan 2023 13:05:26 +0100 Subject: [PATCH] stages/mkdir: add `exist_ok` option to not fail if directory exists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new optional stage option to not fail if the specified directory already exists. This will make it easier to support creation of custom repositories via customizations in osbuild-composer. The reason is that if a specified directory exists in an image, because it was created by an RPM, then creating it would fail. However, the user may have specified different mode for the directory, than it already has. Since there is no way to know for sure if the directory already exists on the image, without building the image itself, it is desired to handle this case gracefully as valid in specific use cases. The default behavior stays the same - specifying an existing directory path will lead to an error. Signed-off-by: Tomáš Hozza --- stages/org.osbuild.mkdir | 16 ++++++++++++---- test/data/stages/mkdir/a.json | 4 ++++ test/data/stages/mkdir/a.mpp.json | 4 ++++ test/data/stages/mkdir/b.json | 9 +++++++++ test/data/stages/mkdir/b.mpp.json | 9 +++++++++ test/data/stages/mkdir/diff.json | 2 +- 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/stages/org.osbuild.mkdir b/stages/org.osbuild.mkdir index 4e3d7436..4ea309b4 100755 --- a/stages/org.osbuild.mkdir +++ b/stages/org.osbuild.mkdir @@ -36,8 +36,12 @@ SCHEMA_2 = r""" "type": "boolean", "description": "Create intermediate directories", "default": false + }, + "exist_ok": { + "type": "boolean", + "description": "Do not fail if the directory already exists", + "default": false } - } } } @@ -50,17 +54,21 @@ def main(tree, options): for item in options["paths"]: path = item["path"] mode = item.get("mode", 0o777) - parents = item.get("parents", False) + exist_ok = item.get("exist_ok", False) target = os.path.join(tree, path.lstrip("/")) if not in_tree(target, tree): raise ValueError(f"path {path} not in tree") if parents: - os.makedirs(target, mode=mode) + os.makedirs(target, mode=mode, exist_ok=exist_ok) else: - os.mkdir(target, mode) + try: + os.mkdir(target, mode) + except FileExistsError: + if not exist_ok: + raise # Documentation for os.mkdir() says that the mode is # ignored on some systems. Also umask value may affect diff --git a/test/data/stages/mkdir/a.json b/test/data/stages/mkdir/a.json index 4a532826..0fd0bd22 100644 --- a/test/data/stages/mkdir/a.json +++ b/test/data/stages/mkdir/a.json @@ -362,6 +362,10 @@ "paths": [ { "path": "a" + }, + { + "path": "c/d", + "parents": true } ] } diff --git a/test/data/stages/mkdir/a.mpp.json b/test/data/stages/mkdir/a.mpp.json index 67bc1982..086f1cc7 100644 --- a/test/data/stages/mkdir/a.mpp.json +++ b/test/data/stages/mkdir/a.mpp.json @@ -18,6 +18,10 @@ "paths": [ { "path": "a" + }, + { + "path": "c/d", + "parents": true } ] } diff --git a/test/data/stages/mkdir/b.json b/test/data/stages/mkdir/b.json index c687c933..aac6de2d 100644 --- a/test/data/stages/mkdir/b.json +++ b/test/data/stages/mkdir/b.json @@ -363,6 +363,10 @@ { "path": "a" }, + { + "path": "c/d", + "parents": true + }, { "path": "a/b", "mode": 448 @@ -370,6 +374,11 @@ { "path": "b/c/d", "parents": true + }, + { + "path": "c", + "mode": 448, + "exist_ok": true } ] } diff --git a/test/data/stages/mkdir/b.mpp.json b/test/data/stages/mkdir/b.mpp.json index 22a75791..3dedb7fc 100644 --- a/test/data/stages/mkdir/b.mpp.json +++ b/test/data/stages/mkdir/b.mpp.json @@ -19,6 +19,10 @@ { "path": "a" }, + { + "path": "c/d", + "parents": true + }, { "path": "a/b", "mode": 448 @@ -26,6 +30,11 @@ { "path": "b/c/d", "parents": true + }, + { + "path": "c", + "mode": 448, + "exist_ok": true } ] } diff --git a/test/data/stages/mkdir/diff.json b/test/data/stages/mkdir/diff.json index 6e2264ff..e50ee99f 100644 --- a/test/data/stages/mkdir/diff.json +++ b/test/data/stages/mkdir/diff.json @@ -6,5 +6,5 @@ "/b/c/d" ], "deleted_files": [], - "differences": {} + "differences": {"/c": {"mode": [16877, 16832]}} }