Merge branch '8333-docker-repo-tag'
authorTom Clegg <tclegg@veritasgenetics.com>
Tue, 3 Oct 2017 14:56:39 +0000 (10:56 -0400)
committerTom Clegg <tclegg@veritasgenetics.com>
Tue, 3 Oct 2017 14:56:39 +0000 (10:56 -0400)
closes #8333

Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

sdk/python/arvados/commands/keepdocker.py
sdk/python/tests/test_arv_keepdocker.py

index 2c1ec738d1b797415532a6d7f88e9974a758294d..ea85b35fc5cbd4d528f1c69507ffaae9fb2717b0 100644 (file)
@@ -62,10 +62,10 @@ _group.add_argument(
 
 keepdocker_parser.add_argument(
     'image', nargs='?',
-    help="Docker image to upload, as a repository name or hash")
+    help="Docker image to upload: repo, repo:tag, or hash")
 keepdocker_parser.add_argument(
-    'tag', nargs='?', default='latest',
-    help="Tag of the Docker image to upload (default 'latest')")
+    'tag', nargs='?',
+    help="Tag of the Docker image to upload (default 'latest'), if image is given as an untagged repo name")
 
 # Combine keepdocker options listed above with run_opts options of arv-put.
 # The options inherited from arv-put include --name, --project-uuid,
@@ -358,6 +358,18 @@ def main(arguments=None, stdout=sys.stdout):
                 raise
         sys.exit(0)
 
+    if re.search(r':\w[-.\w]{0,127}$', args.image):
+        # image ends with :valid-tag
+        if args.tag is not None:
+            logger.error(
+                "image %r already includes a tag, cannot add tag argument %r",
+                args.image, args.tag)
+            sys.exit(1)
+        # rsplit() accommodates "myrepo.example:8888/repo/image:tag"
+        args.image, args.tag = args.image.rsplit(':', 1)
+    elif args.tag is None:
+        args.tag = 'latest'
+
     # Pull the image if requested, unless the image is specified as a hash
     # that we already have.
     if args.pull and not find_image_hashes(args.image):
index 36b4954e515bda07b272b1d33e7fe9df4c3c17aa..695a0389dd8a81675ab3595bf232c7f7e2d48cb8 100644 (file)
@@ -33,8 +33,11 @@ class ArvKeepdockerTestCase(unittest.TestCase, tutil.VersionChecker):
             arv_keepdocker.logger.removeHandler(log_handler)
 
     def test_unsupported_arg(self):
-        with self.assertRaises(SystemExit):
+        out = tutil.StringIO()
+        with tutil.redirected_streams(stdout=out, stderr=out), \
+             self.assertRaises(SystemExit):
             self.run_arv_keepdocker(['-x=unknown'], sys.stderr)
+        self.assertRegex(out.getvalue(), 'unrecognized arguments')
 
     def test_version_argument(self):
         with tutil.redirected_streams(
@@ -114,3 +117,35 @@ class ArvKeepdockerTestCase(unittest.TestCase, tutil.VersionChecker):
             self.run_arv_keepdocker(
                 ['--force', '--force-image-format', 'testimage'], err)
         self.assertRegex(err.getvalue(), "forcing incompatible image")
+
+    def test_tag_given_twice(self):
+        with tutil.redirected_streams(stdout=tutil.StringIO, stderr=tutil.StringIO) as (out, err):
+            with self.assertRaises(SystemExit):
+                self.run_arv_keepdocker(['myrepo:mytag', 'extratag'], sys.stderr)
+            self.assertRegex(err.getvalue(), "cannot add tag argument 'extratag'")
+
+    def test_image_given_as_repo_colon_tag(self):
+        with self.assertRaises(StopTest), \
+             mock.patch('arvados.commands.keepdocker.find_one_image_hash',
+                        side_effect=StopTest) as find_image_mock:
+            self.run_arv_keepdocker(['repo:tag'], sys.stderr)
+        find_image_mock.assert_called_with('repo', 'tag')
+
+        with self.assertRaises(StopTest), \
+             mock.patch('arvados.commands.keepdocker.find_one_image_hash',
+                        side_effect=StopTest) as find_image_mock:
+            self.run_arv_keepdocker(['myreg.example:8888/repo/img:tag'], sys.stderr)
+        find_image_mock.assert_called_with('myreg.example:8888/repo/img', 'tag')
+
+    def test_image_has_colons(self):
+        with self.assertRaises(StopTest), \
+             mock.patch('arvados.commands.keepdocker.find_one_image_hash',
+                        side_effect=StopTest) as find_image_mock:
+            self.run_arv_keepdocker(['[::1]:8888/repo/img'], sys.stderr)
+        find_image_mock.assert_called_with('[::1]:8888/repo/img', 'latest')
+
+        with self.assertRaises(StopTest), \
+             mock.patch('arvados.commands.keepdocker.find_one_image_hash',
+                        side_effect=StopTest) as find_image_mock:
+            self.run_arv_keepdocker(['[::1]/repo/img'], sys.stderr)
+        find_image_mock.assert_called_with('[::1]/repo/img', 'latest')