Repository: sql-machine-learning/elasticdl

Issue:
Parameter model_zoo cannot take a path end with `/`
If the parameter `model_zoo` is a path end with slash, the following exception will show up:
```
[2019-10-10 13:15:47,574] [INFO] [image_builder.py:227:_print_docker_progress]

Traceback (most recent call last):
  File "/miniconda2/envs/elasticdl-rc0/bin/elasticdl", line 10, in <module>
    sys.exit(main())
  File "/miniconda2/envs/elasticdl-rc0/lib/python3.7/site-packages/elasticdl/python/elasticdl/client.py", line 46, in main
    args.func(args)
  File "/miniconda2/envs/elasticdl-rc0/lib/python3.7/site-packages/elasticdl/python/elasticdl/api.py", line 24, in train
    docker_tlskey=args.docker_tlskey,
  File "/miniconda2/envs/elasticdl-rc0/lib/python3.7/site-packages/elasticdl/python/elasticdl/image_builder.py", line 74, in build_and_push_docker_image
    _build_docker_image(client, ctx_dir, df.name, image_name)
  File "/miniconda2/envs/elasticdl-rc0/lib/python3.7/site-packages/elasticdl/python/elasticdl/image_builder.py", line 241, in _build_docker_image
    _print_docker_progress(line)
  File "/miniconda2/envs/elasticdl-rc0/lib/python3.7/site-packages/elasticdl/python/elasticdl/image_builder.py", line 224, in _print_docker_progress
    raise RuntimeError("Docker image build: " + error)
RuntimeError: Docker image build: COPY failed: stat /var/lib/docker/tmp/docker-builder531748767/model_zoo: no such file or directory
```


Discussion:

Resolving patch:
diff --git a/elasticdl/python/elasticdl/api.py b/elasticdl/python/elasticdl/api.py
--- a/elasticdl/python/elasticdl/api.py
+++ b/elasticdl/python/elasticdl/api.py
@@ -13,8 +13,10 @@
 
 
 def train(args):
+    model_zoo = os.path.normpath(args.model_zoo)
+
     image_name = build_and_push_docker_image(
-        model_zoo=args.model_zoo,
+        model_zoo=model_zoo,
         base_image=args.image_base,
         docker_image_repository=args.docker_image_repository,
         extra_pypi=args.extra_pypi_index,
@@ -30,7 +32,7 @@ def train(args):
         "--worker_image",
         image_name,
         "--model_zoo",
-        _model_zoo_in_docker(args.model_zoo),
+        _model_zoo_in_docker(model_zoo),
         "--cluster_spec",
         _cluster_spec_def_in_docker(args.cluster_spec),
     ]
@@ -45,8 +47,10 @@ def train(args):
 
 
 def evaluate(args):
+    model_zoo = os.path.normpath(args.model_zoo)
+
     image_name = build_and_push_docker_image(
-        model_zoo=args.model_zoo,
+        model_zoo=model_zoo,
         base_image=args.image_base,
         docker_image_repository=args.docker_image_repository,
         extra_pypi=args.extra_pypi_index,
@@ -61,7 +65,7 @@ def evaluate(args):
         "--worker_image",
         image_name,
         "--model_zoo",
-        _model_zoo_in_docker(args.model_zoo),
+        _model_zoo_in_docker(model_zoo),
         "--cluster_spec",
         _cluster_spec_def_in_docker(args.cluster_spec),
     ]
@@ -75,8 +79,10 @@ def evaluate(args):
 
 
 def predict(args):
+    model_zoo = os.path.normpath(args.model_zoo)
+
     image_name = build_and_push_docker_image(
-        model_zoo=args.model_zoo,
+        model_zoo=model_zoo,
         base_image=args.image_base,
         docker_image_repository=args.docker_image_repository,
         extra_pypi=args.extra_pypi_index,
@@ -91,7 +97,7 @@ def predict(args):
         "--worker_image",
         image_name,
         "--model_zoo",
-        _model_zoo_in_docker(args.model_zoo),
+        _model_zoo_in_docker(model_zoo),
         "--cluster_spec",
         _cluster_spec_def_in_docker(args.cluster_spec),
     ]


Test patch: