diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerImagesCommand.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerImagesCommand.java new file mode 100644 index 00000000000..87dfcd27f7a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerImagesCommand.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker; + +import com.google.common.base.Preconditions; + +/** + * Encapsulates the docker images command and its command + * line arguments. + */ +public class DockerImagesCommand extends DockerCommand { + private static final String IMAGES_COMMAND = "images"; + + public DockerImagesCommand() { + super(IMAGES_COMMAND); + } + + public DockerImagesCommand getSingleImageStatus(String imageName) { + Preconditions.checkNotNull(imageName, "imageName"); + super.addCommandArguments("image", imageName); + return this; + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.c index 6db5b5d9e05..59a39fafd43 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.c @@ -458,6 +458,8 @@ int get_docker_command(const char *command_file, const struct configuration *con ret = get_docker_start_command(command_file, conf, args); } else if (strcmp(DOCKER_EXEC_COMMAND, command) == 0) { ret = get_docker_exec_command(command_file, conf, args); + } else if (strcmp(DOCKER_IMAGES_COMMAND, command) == 0) { + ret = get_docker_images_command(command_file, conf, args); } else { ret = UNKNOWN_DOCKER_COMMAND; } @@ -1736,3 +1738,39 @@ free_and_exit: free_configuration(&command_config); return ret; } + +int get_docker_images_command(const char *command_file, const struct configuration *conf, args *args) { + int ret = 0; + char *image_name = NULL; + + struct configuration command_config = {0, NULL}; + ret = read_and_verify_command_file(command_file, DOCKER_IMAGES_COMMAND, &command_config); + if (ret != 0) { + goto free_and_exit; + } + + ret = add_to_args(args, DOCKER_IMAGES_COMMAND); + if (ret != 0) { + goto free_and_exit; + } + + image_name = get_configuration_value("image", DOCKER_COMMAND_FILE_SECTION, &command_config); + if (image_name) { + if (validate_docker_image_name(image_name) != 0) { + ret = INVALID_DOCKER_IMAGE_NAME; + goto free_and_exit; + } + ret = add_to_args(args, image_name); + if (ret != 0) { + goto free_and_exit; + } + } + + ret = add_to_args(args, "--format={{json .}}"); + ret = add_to_args(args, "--filter=dangling=false"); + + free_and_exit: + free(image_name); + free_configuration(&command_config); + return ret; +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.h index 3b8922def34..07da195629a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.h +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/utils/docker-util.h @@ -35,6 +35,7 @@ #define DOCKER_VOLUME_COMMAND "volume" #define DOCKER_START_COMMAND "start" #define DOCKER_EXEC_COMMAND "exec" +#define DOCKER_IMAGES_COMMAND "images" #define DOCKER_ARG_MAX 1024 #define ARGS_INITIAL_VALUE { 0 }; @@ -219,4 +220,15 @@ char** extract_execv_args(args *args); * @return value of max retries */ int get_max_retries(const struct configuration *conf); + +/** + * Get the Docker images command line string. The function will verify that the params file is meant for the images + * command. + * @param command_file File containing the params for the Docker images command + * @param conf Configuration struct containing the container-executor.cfg details + * @param args Buffer to construct argv + * @return Return code with 0 indicating success and non-zero codes indicating error + */ +int get_docker_images_command(const char* command_file, const struct configuration* conf, args *args); + #endif diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/utils/test_docker_util.cc b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/utils/test_docker_util.cc index 04018088dd7..a2f843dc321 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/utils/test_docker_util.cc +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/utils/test_docker_util.cc @@ -1962,4 +1962,28 @@ namespace ContainerExecutor { } free_configuration(&container_cfg); } + + TEST_F(TestDockerUtil, test_docker_images) { + std::vector > file_cmd_vec; + file_cmd_vec.push_back(std::make_pair( + "[docker-command-execution]\n docker-command=images", + "images --format={{json .}} --filter=dangling=false")); + + file_cmd_vec.push_back(std::make_pair( + "[docker-command-execution]\n docker-command=images\n image=image-id", + "images image-id --format={{json .}} --filter=dangling=false")); + + std::vector > bad_file_cmd_vec; + bad_file_cmd_vec.push_back(std::make_pair( + "[docker-command-execution]\n docker-command=run\n image=image-id", + static_cast(INCORRECT_COMMAND))); + bad_file_cmd_vec.push_back(std::make_pair( + "docker-command=images\n image=image-id", + static_cast(INCORRECT_COMMAND))); + + run_docker_command_test(file_cmd_vec, bad_file_cmd_vec, + get_docker_images_command); + free_configuration(&container_executor_cfg); + } + } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/TestDockerImagesCommand.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/TestDockerImagesCommand.java new file mode 100644 index 00000000000..7d302b66547 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/TestDockerImagesCommand.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker; + +import org.apache.hadoop.util.StringUtils; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Tests the docker images command and its command + * line arguments. + */ +public class TestDockerImagesCommand { + private DockerImagesCommand dockerImagesCommand; + + private static final String IMAGE_NAME = "foo"; + + @Before + public void setup() { + dockerImagesCommand = new DockerImagesCommand(); + } + + @Test + public void testGetCommandOption() { + assertEquals("images", dockerImagesCommand.getCommandOption()); + } + + @Test + public void testAllImages() { + assertEquals("images", StringUtils.join(",", + dockerImagesCommand.getDockerCommandWithArguments() + .get("docker-command"))); + assertEquals(1, dockerImagesCommand.getDockerCommandWithArguments().size()); + } + + @Test + public void testSingleImage() { + dockerImagesCommand = dockerImagesCommand.getSingleImageStatus(IMAGE_NAME); + assertEquals("images", StringUtils.join(",", + dockerImagesCommand.getDockerCommandWithArguments() + .get("docker-command"))); + assertEquals("image name", "foo", StringUtils.join(",", + dockerImagesCommand.getDockerCommandWithArguments().get("image"))); + assertEquals(2, dockerImagesCommand.getDockerCommandWithArguments().size()); + } +}