SLIDER-435. Slider client should accept target yarn queue as an input parameter
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/e3c49d59 Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/e3c49d59 Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/e3c49d59 Branch: refs/heads/feature/SLIDER-158_slider_diagnostic_option Commit: e3c49d59f6b847b7fc36b7acc9f531782d8336e9 Parents: 0d41051 Author: Sumit Mohanty <[email protected]> Authored: Sun Sep 21 17:23:18 2014 -0700 Committer: Sumit Mohanty <[email protected]> Committed: Sun Sep 21 17:23:18 2014 -0700 ---------------------------------------------------------------------- app-packages/hbase/resources.json | 2 +- .../org/apache/slider/api/InternalKeys.java | 4 + .../org/apache/slider/client/SliderClient.java | 7 +- .../common/SliderXMLConfKeysForTesting.java | 2 + .../AbstractClusterBuildingActionArgs.java | 4 + .../apache/slider/common/params/Arguments.java | 1 + .../slider/core/build/InstanceBuilder.java | 16 +++ .../resources_queue_labels.json | 17 +++ .../providers/agent/TestBuildBasicAgent.groovy | 39 ++++++- .../framework/AgentCommandTestBase.groovy | 36 ++++-- .../funtest/lifecycle/AppsThroughAgentIT.groovy | 1 - .../AppsThroughAgentQueueAndLabelsIT.groovy | 113 +++++++++++++++++++ .../clusters/remote/slider/slider-client.xml | 14 ++- 13 files changed, 244 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/app-packages/hbase/resources.json ---------------------------------------------------------------------- diff --git a/app-packages/hbase/resources.json b/app-packages/hbase/resources.json index d2fdbd8..c3fec68 100644 --- a/app-packages/hbase/resources.json +++ b/app-packages/hbase/resources.json @@ -24,7 +24,7 @@ }, "HBASE_THRIFT": { "yarn.role.priority": "4", - "yarn.component.instances": "1", + "yarn.component.instances": "0", "yarn.memory": "256" }, "HBASE_THRIFT2": { http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/api/InternalKeys.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/InternalKeys.java b/slider-core/src/main/java/org/apache/slider/api/InternalKeys.java index ffa3600..5f150e6 100644 --- a/slider-core/src/main/java/org/apache/slider/api/InternalKeys.java +++ b/slider-core/src/main/java/org/apache/slider/api/InternalKeys.java @@ -94,6 +94,10 @@ public interface InternalKeys { */ String KEYTAB_LOCATION = "internal.keytab.location"; + /** + * Queue used to deploy the app: {@value} + */ + String INTERNAL_QUEUE = "internal.queue"; /** * Flag to indicate whether or not the chaos monkey is enabled: http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/client/SliderClient.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java index 3df5b18..221fc43 100644 --- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java +++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java @@ -783,6 +783,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe builder.propagateFilename(); builder.propagatePrincipals(); builder.setImageDetailsIfAvailable(buildInfo.getImage(), buildInfo.getAppHomeDir()); + builder.setQueue(buildInfo.queue); String quorum = buildInfo.getZKhosts(); if (SliderUtils.isUnset(quorum)) { @@ -1262,7 +1263,11 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe // Set the queue to which this application is to be submitted in the RM // Queue for App master String amQueue = config.get(KEY_YARN_QUEUE, DEFAULT_YARN_QUEUE); - + String suppliedQueue = internalOperations.getGlobalOptions().get(InternalKeys.INTERNAL_QUEUE); + if(!SliderUtils.isUnset(suppliedQueue)) { + amQueue = suppliedQueue; + log.info("Using queue {} for the application instance.", amQueue); + } amLauncher.setQueue(amQueue); // Submit the application to the applications manager http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java b/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java index 2cb6594..4c56240 100644 --- a/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java +++ b/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java @@ -60,6 +60,8 @@ public interface SliderXMLConfKeysForTesting { int DEFAULT_ACCUMULO_LIVE_TIME_SECONDS = 90; String KEY_TEST_AGENT_ENABLED = "slider.test.agent.enabled"; + String KEY_AGENTTESTS_QUEUE_LABELED_DEFINED = "slider.test.agent.labeled.queue.enabled"; + String KEY_AGENTTESTS_LABELS_RED_BLUE_DEFINED = "slider.test.agent.labels.defined"; int DEFAULT_AGENT_LAUNCH_TIME_SECONDS = 60 * 3; http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java index fa71677..56e01c3 100644 --- a/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java +++ b/slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java @@ -93,6 +93,10 @@ public abstract class AbstractClusterBuildingActionArgs extends description = "Template application configuration") public File template; + @Parameter(names = {ARG_QUEUE}, + description = "Queue to submit the application") + public String queue; + @ParametersDelegate public ComponentArgsDelegate componentDelegate = new ComponentArgsDelegate(); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java index 7f8aa83..b119245 100644 --- a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java +++ b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java @@ -78,6 +78,7 @@ public interface Arguments { String ARG_ZKPORT = "--zkport"; String ARG_ZKHOSTS = "--zkhosts"; String ARG_REPLACE_PKG = "--replacepkg"; + String ARG_QUEUE = "--queue"; /** http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java b/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java index 528a0c4..669a5ad 100644 --- a/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java +++ b/slider-core/src/main/java/org/apache/slider/core/build/InstanceBuilder.java @@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Map; +import static org.apache.slider.api.InternalKeys.INTERNAL_QUEUE; import static org.apache.slider.api.OptionKeys.INTERNAL_AM_TMP_DIR; import static org.apache.slider.api.OptionKeys.INTERNAL_TMP_DIR; import static org.apache.slider.api.OptionKeys.INTERNAL_APPLICATION_HOME; @@ -149,6 +150,21 @@ public class InstanceBuilder { } /** + * Set the queue used to start the application + * @param queue + * @throws BadConfigException + */ + public void setQueue(String queue) throws BadConfigException { + if(queue != null) { + if(SliderUtils.isUnset(queue)) { + throw new BadConfigException("Queue value cannot be empty."); + } + + instanceDescription.getInternalOperations().set(INTERNAL_QUEUE, queue); + } + } + + /** * Set up the image/app home path * @param appImage path in the DFS to the tar file * @param appHomeDir other strategy: home dir http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/test/app_packages/test_command_log/resources_queue_labels.json ---------------------------------------------------------------------- diff --git a/slider-core/src/test/app_packages/test_command_log/resources_queue_labels.json b/slider-core/src/test/app_packages/test_command_log/resources_queue_labels.json new file mode 100644 index 0000000..d121608 --- /dev/null +++ b/slider-core/src/test/app_packages/test_command_log/resources_queue_labels.json @@ -0,0 +1,17 @@ +{ + "schema": "http://example.org/specification/v2.0.0", + "metadata": { + }, + "global": { + }, + "components": { + "COMMAND_LOGGER": { + "yarn.role.priority": "1", + "yarn.component.instances": "1", + "yarn.label.expression":"blue" + }, + "slider-appmaster": { + "yarn.label.expression":"red" + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestBuildBasicAgent.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestBuildBasicAgent.groovy b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestBuildBasicAgent.groovy index 1b5269a..2f6a15e 100644 --- a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestBuildBasicAgent.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestBuildBasicAgent.groovy @@ -21,6 +21,7 @@ package org.apache.slider.providers.agent import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import org.apache.hadoop.yarn.conf.YarnConfiguration +import org.apache.slider.api.InternalKeys import org.apache.slider.api.ResourceKeys import org.apache.slider.api.RoleKeys import org.apache.slider.client.SliderClient @@ -354,7 +355,43 @@ class TestBuildBasicAgent extends AgentTestBase { fail("Build operation should not fail") } } - + + @Test + public void testSubmitToSpecificQueue() throws Throwable { + String clustername = createMiniCluster( + "", + configuration, + 1, + 1, + 1, + true, + false) + + try { + buildAgentCluster(clustername, + [:], + [ + ARG_OPTION, CONTROLLER_URL, "http://localhost", + ARG_PACKAGE, ".", + ARG_OPTION, APP_DEF, "file://" + appDef.absolutePath, + ARG_RESOURCES, TEST_FILES + "good/resources.json", + ARG_TEMPLATE, TEST_FILES + "good/appconf.json", + ARG_QUEUE, "labeled" + ], + true, false, + false) + } catch (BadConfigException exception) { + log.error( + "Build operation should not have failed with exception : \n$exception") + fail("Build operation should not fail") + } + + AggregateConf instanceDefinition = loadInstanceDefinition(clustername) + def label = instanceDefinition.getInternalOperations().get( + InternalKeys.INTERNAL_QUEUE) + assert label == "labeled", "Expect labeled as the queue" + } + @Test public void testBadAgentArgs() throws Throwable { String clustername = createMiniCluster( http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/AgentCommandTestBase.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/AgentCommandTestBase.groovy b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/AgentCommandTestBase.groovy index f1edff4..cf32e94 100644 --- a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/AgentCommandTestBase.groovy +++ b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/AgentCommandTestBase.groovy @@ -21,8 +21,10 @@ package org.apache.slider.funtest.framework import groovy.util.logging.Slf4j import org.apache.hadoop.fs.Path import org.apache.slider.common.SliderExitCodes +import org.apache.slider.common.SliderXMLConfKeysForTesting import org.apache.slider.common.params.Arguments import org.apache.slider.common.params.SliderActions +import org.apache.slider.common.tools.SliderUtils import org.apache.tools.zip.ZipEntry import org.apache.tools.zip.ZipOutputStream import org.junit.Before @@ -35,6 +37,8 @@ class AgentCommandTestBase extends CommandTestBase implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { public static final boolean AGENTTESTS_ENABLED + public static final boolean AGENTTESTS_QUEUE_LABELED_DEFINED + public static final boolean AGENTTESTS_LABELS_RED_BLUE_DEFINED private static String TEST_APP_PKG_DIR_PROP = "test.app.pkg.dir" private static String TEST_APP_PKG_FILE_PROP = "test.app.pkg.file" private static String TEST_APP_PKG_NAME_PROP = "test.app.pkg.name" @@ -57,6 +61,10 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { static { AGENTTESTS_ENABLED = SLIDER_CONFIG.getBoolean(KEY_TEST_AGENT_ENABLED, false) + AGENTTESTS_QUEUE_LABELED_DEFINED = + SLIDER_CONFIG.getBoolean(KEY_AGENTTESTS_QUEUE_LABELED_DEFINED, false) + AGENTTESTS_LABELS_RED_BLUE_DEFINED = + SLIDER_CONFIG.getBoolean(KEY_AGENTTESTS_LABELS_RED_BLUE_DEFINED, false) } protected String getAppResource() { @@ -74,6 +82,14 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { assume(AGENTTESTS_ENABLED, "Agent tests disabled") } + public static void assumeQueueNamedLabelDefined() { + assume(AGENTTESTS_QUEUE_LABELED_DEFINED, "Custom queue named labeled is not defined") + } + + public static void assumeLabelsRedAndBlueAdded() { + assume(AGENTTESTS_LABELS_RED_BLUE_DEFINED, "Custom node labels not defined") + } + @BeforeClass public static void setupAgent() { assumeAgentTestsEnabled() @@ -110,17 +126,23 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { public static void assertComponentCount(String component, int count, SliderShell shell) { log.info("Asserting component count.") + int instanceCount = getComponentCount(component, shell) + assert count == instanceCount, 'Instance count for component did not match expected.' + } + + public static int getComponentCount(String component, SliderShell shell) { String entry = findLineEntry(shell, ["instances", component] as String[]) - log.info(entry) - assert entry != null int instanceCount = 0 - int index = entry.indexOf("container_") - while (index != -1) { - instanceCount++; - index = entry.indexOf("container_", index + 1) + if (!SliderUtils.isUnset(entry)) { + log.info(entry) + int index = entry.indexOf("container_") + while (index != -1) { + instanceCount++; + index = entry.indexOf("container_", index + 1) + } } - assert instanceCount == count, 'Instance count for component did not match expected. Parsed: ' + entry + return instanceCount } public static String findLineEntry(SliderShell shell, String[] locaters) { http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentIT.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentIT.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentIT.groovy index 8930b8d..7e39791 100644 --- a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentIT.groovy +++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentIT.groovy @@ -50,7 +50,6 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { SliderShell shell = slider(EXIT_SUCCESS, [ ACTION_CREATE, APPLICATION_NAME, - //ARG_IMAGE, agentTarballPath.toString(), ARG_TEMPLATE, APP_TEMPLATE, ARG_RESOURCES, APP_RESOURCE ]) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentQueueAndLabelsIT.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentQueueAndLabelsIT.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentQueueAndLabelsIT.groovy new file mode 100644 index 0000000..f3f6612 --- /dev/null +++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AppsThroughAgentQueueAndLabelsIT.groovy @@ -0,0 +1,113 @@ +/* + * 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.slider.funtest.lifecycle + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.apache.slider.common.SliderExitCodes +import org.apache.slider.common.params.Arguments +import org.apache.slider.common.params.SliderActions +import org.apache.slider.funtest.framework.AgentCommandTestBase +import org.apache.slider.funtest.framework.FuntestProperties +import org.apache.slider.funtest.framework.SliderShell +import org.junit.After +import org.junit.Test + +@CompileStatic +@Slf4j +public class AppsThroughAgentQueueAndLabelsIT extends AgentCommandTestBase +implements FuntestProperties, Arguments, SliderExitCodes, SliderActions { + + private static String COMMAND_LOGGER = "COMMAND_LOGGER" + private static String APPLICATION_NAME = "happy-path-with-queue-labels" + private static String TARGET_QUEUE = "labeled" + private static String APP_RESOURCE4 = + "../slider-core/src/test/app_packages/test_command_log/resources_queue_labels.json" + + @After + public void destroyCluster() { + cleanup(APPLICATION_NAME) + } + + @Test + public void testCreateWithQueueAndLabels() throws Throwable { + assumeAgentTestsEnabled() + assumeQueueNamedLabelDefined() + assumeLabelsRedAndBlueAdded() + + cleanup(APPLICATION_NAME) + SliderShell shell = slider(EXIT_SUCCESS, + [ + ACTION_CREATE, APPLICATION_NAME, + ARG_QUEUE, TARGET_QUEUE, + ARG_TEMPLATE, APP_TEMPLATE, + ARG_RESOURCES, APP_RESOURCE4 + ]) + + logShell(shell) + + ensureApplicationIsUp(APPLICATION_NAME) + + repeatUntilTrue(this.&hasContainerCountExceeded, 15, 1000 * 10, ['arg1': '1']); + + shell = slider(EXIT_SUCCESS, + [ + ACTION_STATUS, + APPLICATION_NAME]) + assertComponentCount(COMMAND_LOGGER, 1, shell) + + //flex + slider(EXIT_SUCCESS, + [ + ACTION_FLEX, + APPLICATION_NAME, + ARG_COMPONENT, + COMMAND_LOGGER, + "2"]) + + // sleep till the new instance starts + repeatUntilTrue(this.&hasContainerCountExceeded, 15, 1000 * 10, ['arg1': '2']); + + shell = slider(EXIT_SUCCESS, + [ + ACTION_STATUS, + APPLICATION_NAME]) + assertComponentCount(COMMAND_LOGGER, 2, shell) + + assertSuccess(shell) + assert isApplicationInState("RUNNING", APPLICATION_NAME), 'App is not running.' + } + + boolean hasContainerCountExceeded(Map<String, String> args) { + int expectedCount = args['arg1'].toInteger(); + SliderShell shell = slider(EXIT_SUCCESS, + [ + ACTION_STATUS, + APPLICATION_NAME]) + + //logShell(shell) + int instanceCount = getComponentCount(COMMAND_LOGGER, shell) + log.info("Noticed instance count - " + instanceCount + " for " + COMMAND_LOGGER) + if (instanceCount >= expectedCount) { + return true + } + + return false + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/e3c49d59/src/test/clusters/remote/slider/slider-client.xml ---------------------------------------------------------------------- diff --git a/src/test/clusters/remote/slider/slider-client.xml b/src/test/clusters/remote/slider/slider-client.xml index 5ed4d10..ce261e9 100644 --- a/src/test/clusters/remote/slider/slider-client.xml +++ b/src/test/clusters/remote/slider/slider-client.xml @@ -53,7 +53,19 @@ <name>slider.test.agent.enabled</name> <value>true</value> </property> - + + <property> + <name>slider.test.agent.labeled.queue.enabled</name> + <value>false</value> + <description>Add a queue named labeled</description> + </property> + + <property> + <name>slider.test.agent.labels.defined</name> + <value>false</value> + <description>Add node labels red and blue and ensure enough capacities are allocated</description> + </property> + <property> <name>slider.test.agent.tar</name> <value>hdfs://c6403.ambari.apache.org:8020/slider/agent/slider-agent.tar.gz</value>
