Latest docker v2 registry uses OAuth for creating tokens,
identified by the "Bearer" method in the 'WWW-Authenticate'
header. Add a DockerAuthBearer impl to deal with this.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
libvirt-sandbox/image/sources/docker.py | 54 +++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/libvirt-sandbox/image/sources/docker.py
b/libvirt-sandbox/image/sources/docker.py
index 3cc321b..cc8d05b 100644
--- a/libvirt-sandbox/image/sources/docker.py
+++ b/libvirt-sandbox/image/sources/docker.py
@@ -153,6 +153,60 @@ class DockerAuthToken(DockerAuth):
return False
+class DockerAuthBearer(DockerAuth):
+
+ def __init__(self):
+ self.token = None
+
+ def prepare_req(self, req):
+ if self.token is not None:
+ debug("Adding token %s" % self.token)
+ req.add_header("Authorization", "Bearer %s" %
self.token)
+ else:
+ debug("No token")
+
+ def process_res(self, res):
+ pass
+
+ def process_err(self, err):
+ method = err.headers.get("WWW-Authenticate", None)
+ if method is None:
+ return False
+
+ if not method.startswith("Bearer "):
+ return False
+
+ challenge = method[7:]
+
+ bits = challenge.split(",")
+ attrs = {}
+ for bit in bits:
+ subbit = bit.split("=")
+ attrs[subbit[0]] = subbit[1][1:-1]
+
+ url = attrs["realm"]
+ del attrs["realm"]
+ if "error" in attrs:
+ del attrs["error"]
+
+ params = "&".join([
+ "%s=%s" % (attr, attrs[attr])
+ for attr in attrs.keys()
+ ])
+ if params != "":
+ url = url + "?" + params
+
+ debug("Requesting auth at %s\n" % url)
+ req = urllib2.Request(url=url)
+ req.add_header("Accept", "application/json")
+
+ res = urllib2.urlopen(req)
+ data = json.loads(res.read())
+ self.token = data["token"]
+ debug("Saved %s" % self.token)
+ return True
+
+
class DockerRegistry():
def __init__(self, uri_base):
--
2.7.4