summaryrefslogtreecommitdiffstats
path: root/dockerfile-parse-0.0.5-parent_env.patch
blob: 37e48ccf6c1b952cd5b9709ed15e52fca6dc84d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
diff --git a/dockerfile_parse/parser.py b/dockerfile_parse/parser.py
index 615d7a8..25b6536 100644
--- a/dockerfile_parse/parser.py
+++ b/dockerfile_parse/parser.py
@@ -66,11 +66,12 @@ class Envs(dict):


 class DockerfileParser(object):
-    def __init__(self, path=None, cache_content=False, env_replace=True):
+    def __init__(self, path=None, cache_content=False, env_replace=True, parent_env=None):
         """
         Initialize path to Dockerfile
         :param path: path to (directory with) Dockerfile
         :param cache_content: cache Dockerfile content inside DockerfileParser
+        :param parent_env: python dict of inherited env vars from parent image
         """
         path = path or '.'
         if path.endswith(DOCKERFILE_FILENAME):
@@ -91,6 +92,14 @@ class DockerfileParser(object):

         self.env_replace = env_replace

+        if isinstance(parent_env, dict):
+            logger.debug("Setting inherited parent image ENV vars: %s", parent_env)
+            self.parent_env = parent_env
+        elif parent_env != None:
+            assert isinstance(parent_env, dict)
+        else:
+            self.parent_env = {}
+
     @property
     def lines(self):
         """
@@ -106,7 +115,7 @@ class DockerfileParser(object):
                     self.cached_content = ''.join(lines)
                 return lines
         except (IOError, OSError) as ex:
-            logger.error("Couldn't retrieve lines from dockerfile: %s" % repr(ex))
+            logger.error("Couldn't retrieve lines from dockerfile: %r", ex)
             raise

     @lines.setter
@@ -122,7 +131,7 @@ class DockerfileParser(object):
             with open(self.dockerfile_path, 'w') as dockerfile:
                 dockerfile.writelines([u2b(l) for l in lines])
         except (IOError, OSError) as ex:
-            logger.error("Couldn't write lines to dockerfile: %s" % repr(ex))
+            logger.error("Couldn't write lines to dockerfile: %r", ex)
             raise

     @property
@@ -140,7 +149,7 @@ class DockerfileParser(object):
                     self.cached_content = content
                 return content
         except (IOError, OSError) as ex:
-            logger.error("Couldn't retrieve content of dockerfile: %s" % repr(ex))
+            logger.error("Couldn't retrieve content of dockerfile: %r", ex)
             raise

     @content.setter
@@ -156,7 +165,7 @@ class DockerfileParser(object):
             with open(self.dockerfile_path, 'w') as dockerfile:
                 dockerfile.write(u2b(content))
         except (IOError, OSError) as ex:
-            logger.error("Couldn't write content to dockerfile: %s" % repr(ex))
+            logger.error("Couldn't write content to dockerfile: %r", ex)
             raise

     @property
@@ -290,7 +299,7 @@ class DockerfileParser(object):
         if name != 'LABEL' and name != 'ENV':
             raise ValueError("Unsupported instruction '%s'", name)
         instructions = {}
-        envs = {}
+        envs = self.parent_env.copy()
         for insndesc in self.structure:
             this_insn = insndesc['instruction']
             if this_insn in (name, 'ENV'):
@@ -354,7 +363,7 @@ class DockerfileParser(object):
         elif name == 'ENV':
             existing = self.envs

-        logger.debug("setting %s instructions: %r" % (name, instructions))
+        logger.debug("setting %s instructions: %r", name, instructions)

         to_delete = [k for k in existing if k not in instructions]
         for key in to_delete:

diff --git a/tests/test_parser.py b/tests/test_parser.py
index 8f63a04..e47fefe 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -86,6 +86,35 @@ USER  {0}""".format(NON_ASCII)
         base_img = dfparser.baseimage
         assert base_img.startswith('fedora')

+    def test_get_parent_env(self, tmpdir):
+        tmpdir_path = str(tmpdir.realpath())
+        p_env = {"bar": "baz"}
+        df1 = DockerfileParser(tmpdir_path, env_replace=True, parent_env=p_env)
+        df1.lines = [
+            "FROM parent\n",
+            "ENV foo=\"$bar\"\n",
+            "LABEL label=\"$foo $bar\"\n"
+        ]
+
+        # Even though we inherit an ENV, this .envs count should only be for the
+        # ENVs defined in *this* Dockerfile as we're parsing the Dockerfile and
+        # the parent_env is only to satisfy use of inhereted ENVs.
+        assert len(df1.envs) == 1
+        assert df1.envs.get('foo') == 'baz'
+        assert len(df1.labels) == 1
+        assert df1.labels.get('label') == 'baz baz'
+
+    def test_get_parent_env_from_scratch(self, tmpdir):
+        tmpdir_path = str(tmpdir.realpath())
+        p_env = {"bar": "baz"}
+        df1 = DockerfileParser(tmpdir_path, env_replace=True, parent_env=p_env)
+        df1.lines = [
+            "FROM scratch\n",
+        ]
+
+        assert not df1.envs
+
+
     def test_get_instructions_from_df(self, dfparser, instruction):
         dfparser.content = ""
         lines = []