2
2
Docker container engine for repo2docker
3
3
"""
4
4
5
+ import os
5
6
import shutil
7
+ import subprocess
6
8
import tarfile
7
9
import tempfile
10
+ from contextlib import contextmanager
11
+ from pathlib import Path
8
12
9
13
from iso8601 import parse_date
10
14
from traitlets import Dict , List , Unicode
@@ -58,7 +62,7 @@ class DockerEngine(ContainerEngine):
58
62
https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
59
63
"""
60
64
61
- string_output = False
65
+ string_output = True
62
66
63
67
extra_init_args = Dict (
64
68
{},
@@ -141,18 +145,12 @@ def build(
141
145
142
146
args += [d ]
143
147
144
- for line in execute_cmd (args , True ):
145
- # Simulate structured JSON output from buildx build, since we
146
- # do get structured json output from pushing and running
147
- yield {"stream" : line }
148
+ yield from execute_cmd (args , True )
148
149
else :
149
150
# Assume 'path' is passed in
150
151
args += [path ]
151
152
152
- for line in execute_cmd (args , True ):
153
- # Simulate structured JSON output from buildx build, since we
154
- # do get structured json output from pushing and running
155
- yield {"stream" : line }
153
+ yield from execute_cmd (args , True )
156
154
157
155
def images (self ):
158
156
images = self ._apiclient .images ()
@@ -162,10 +160,42 @@ def inspect_image(self, image):
162
160
image = self ._apiclient .inspect_image (image )
163
161
return Image (tags = image ["RepoTags" ], config = image ["Config" ])
164
162
163
+ @contextmanager
164
+ def docker_login (self , username , password , registry ):
165
+ # Determine existing DOCKER_CONFIG
166
+ dc_path = Path (
167
+ os .environ .get ("DOCKER_CONFIG" , os .path .expanduser ("~/.docker/config.json" ))
168
+ )
169
+
170
+ with tempfile .TemporaryDirectory () as d :
171
+ new_dc_path = Path (d ) / "config.json"
172
+ if dc_path .exists ():
173
+ # If there is an existing DOCKER_CONFIG, copy it to new location so we inherit
174
+ # whatever configuration the user has already set
175
+ shutil .copy2 (dc_path , new_dc_path )
176
+
177
+ env = os .environ .copy ()
178
+ subprocess .check_call (
179
+ # FIXME: This should be using --password-stdin instead
180
+ [
181
+ "docker" ,
182
+ "login" ,
183
+ "--username" ,
184
+ username ,
185
+ "--password" ,
186
+ password ,
187
+ registry ,
188
+ ],
189
+ env = env ,
190
+ )
191
+ yield
192
+
165
193
def push (self , image_spec ):
166
194
if self .registry_credentials :
167
- self ._apiclient .login (** self .registry_credentials )
168
- return self ._apiclient .push (image_spec , stream = True )
195
+ with self .docker_login (** self .registry_credentials ):
196
+ yield from execute_cmd (["docker" , "push" , image_spec ], capture = True )
197
+ else :
198
+ yield from execute_cmd (["docker" , "push" , image_spec ], capture = True )
169
199
170
200
def run (
171
201
self ,
0 commit comments