http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java new file mode 100644 index 0000000..c3a2752 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java @@ -0,0 +1,892 @@ +/** + * 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.service.client; + +import org.apache.commons.lang.StringUtils; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.RetryNTimes; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.registry.client.api.RegistryConstants; +import org.apache.hadoop.registry.client.api.RegistryOperations; +import org.apache.hadoop.registry.client.api.RegistryOperationsFactory; +import org.apache.hadoop.registry.client.binding.RegistryUtils; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.service.CompositeService; +import org.apache.hadoop.util.VersionInfo; +import org.apache.hadoop.yarn.api.ApplicationConstants; +import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest; +import org.apache.hadoop.yarn.api.protocolrecords.UpdateApplicationTimeoutsRequest; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.api.records.ApplicationReport; +import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext; +import org.apache.hadoop.yarn.api.records.ApplicationTimeout; +import org.apache.hadoop.yarn.api.records.ApplicationTimeoutType; +import org.apache.hadoop.yarn.api.records.ContainerLaunchContext; +import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; +import org.apache.hadoop.yarn.api.records.LocalResource; +import org.apache.hadoop.yarn.api.records.LocalResourceType; +import org.apache.hadoop.yarn.api.records.Resource; +import org.apache.hadoop.yarn.api.records.YarnApplicationState; +import org.apache.hadoop.yarn.client.api.YarnClient; +import org.apache.hadoop.yarn.client.api.YarnClientApplication; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.ipc.YarnRPC; +import org.apache.hadoop.yarn.proto.ClientAMProtocol.ComponentCountProto; +import org.apache.hadoop.yarn.proto.ClientAMProtocol.FlexComponentsRequestProto; +import org.apache.hadoop.yarn.proto.ClientAMProtocol.GetStatusRequestProto; +import org.apache.hadoop.yarn.proto.ClientAMProtocol.GetStatusResponseProto; +import org.apache.hadoop.yarn.proto.ClientAMProtocol.StopRequestProto; +import org.apache.hadoop.yarn.service.ClientAMProtocol; +import org.apache.hadoop.yarn.service.ServiceMaster; +import org.apache.hadoop.yarn.service.api.records.Service; +import org.apache.hadoop.yarn.service.api.records.Component; +import org.apache.hadoop.yarn.service.api.records.ServiceState; +import org.apache.hadoop.yarn.service.client.params.AbstractClusterBuildingActionArgs; +import org.apache.hadoop.yarn.service.client.params.ActionDependencyArgs; +import org.apache.hadoop.yarn.service.client.params.ActionFlexArgs; +import org.apache.hadoop.yarn.service.client.params.Arguments; +import org.apache.hadoop.yarn.service.client.params.ClientArgs; +import org.apache.hadoop.yarn.service.client.params.CommonArgs; +import org.apache.hadoop.yarn.service.conf.SliderExitCodes; +import org.apache.hadoop.yarn.service.conf.YarnServiceConstants; +import org.apache.hadoop.yarn.service.conf.YarnServiceConf; +import org.apache.hadoop.yarn.service.provider.AbstractClientProvider; +import org.apache.hadoop.yarn.service.provider.ProviderUtils; +import org.apache.hadoop.yarn.service.utils.ServiceApiUtil; +import org.apache.hadoop.yarn.service.utils.ServiceRegistryUtils; +import org.apache.hadoop.yarn.service.utils.SliderFileSystem; +import org.apache.hadoop.yarn.service.utils.SliderUtils; +import org.apache.hadoop.yarn.util.Records; +import org.apache.hadoop.yarn.util.Times; +import org.apache.hadoop.yarn.service.exceptions.BadClusterStateException; +import org.apache.hadoop.yarn.service.exceptions.BadConfigException; +import org.apache.hadoop.yarn.service.exceptions.SliderException; +import org.apache.hadoop.yarn.service.exceptions.UsageException; +import org.apache.hadoop.yarn.service.containerlaunch.ClasspathConstructor; +import org.apache.hadoop.yarn.service.containerlaunch.JavaCommandLineBuilder; +import org.apache.hadoop.yarn.service.utils.ZookeeperUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static org.apache.hadoop.yarn.api.records.YarnApplicationState.*; +import static org.apache.hadoop.yarn.service.client.params.SliderActions.ACTION_CREATE; +import static org.apache.hadoop.yarn.service.client.params.SliderActions.ACTION_FLEX; +import static org.apache.hadoop.yarn.service.conf.YarnServiceConf.YARN_QUEUE; +import static org.apache.hadoop.yarn.service.utils.ServiceApiUtil.jsonSerDeser; +import static org.apache.hadoop.yarn.service.utils.SliderUtils.*; + +@InterfaceAudience.Public +@InterfaceStability.Unstable +public class ServiceClient extends CompositeService + implements SliderExitCodes, YarnServiceConstants { + private static final Logger LOG = + LoggerFactory.getLogger(ServiceClient.class); + private SliderFileSystem fs; + //TODO disable retry so that client / rest API doesn't block? + protected YarnClient yarnClient; + // Avoid looking up applicationId from fs all the time. + private Map<String, ApplicationId> cachedAppIds = new ConcurrentHashMap<>(); + + private RegistryOperations registryClient; + private CuratorFramework curatorClient; + private YarnRPC rpc; + + private static EnumSet<YarnApplicationState> terminatedStates = + EnumSet.of(FINISHED, FAILED, KILLED); + private static EnumSet<YarnApplicationState> liveStates = + EnumSet.of(NEW, NEW_SAVING, SUBMITTED, ACCEPTED, RUNNING); + private static EnumSet<YarnApplicationState> preRunningStates = + EnumSet.of(NEW, NEW_SAVING, SUBMITTED, ACCEPTED); + + public ServiceClient() { + super(ServiceClient.class.getName()); + } + + @Override protected void serviceInit(Configuration configuration) + throws Exception { + fs = new SliderFileSystem(configuration); + yarnClient = YarnClient.createYarnClient(); + rpc = YarnRPC.create(configuration); + addService(yarnClient); + super.serviceInit(configuration); + } + + @Override + protected void serviceStop() throws Exception { + if (registryClient != null) { + registryClient.stop(); + } + super.serviceStop(); + } + + private Service loadAppJsonFromLocalFS( + AbstractClusterBuildingActionArgs args) throws IOException { + File file = args.getAppDef(); + Path filePath = new Path(file.getAbsolutePath()); + LOG.info("Loading app json from: " + filePath); + Service service = jsonSerDeser + .load(FileSystem.getLocal(getConfig()), filePath); + if (args.lifetime > 0) { + service.setLifetime(args.lifetime); + } + service.setName(args.getClusterName()); + return service; + } + + public int actionBuild(AbstractClusterBuildingActionArgs args) + throws IOException, YarnException { + return actionBuild(loadAppJsonFromLocalFS(args)); + } + + public int actionBuild(Service service) + throws YarnException, IOException { + Path appDir = checkAppNotExistOnHdfs(service); + ServiceApiUtil.validateAndResolveService(service, fs, getConfig()); + createDirAndPersistApp(appDir, service); + return EXIT_SUCCESS; + } + + public int actionCreate(AbstractClusterBuildingActionArgs args) + throws IOException, YarnException { + actionCreate(loadAppJsonFromLocalFS(args)); + return EXIT_SUCCESS; + } + + public ApplicationId actionCreate(Service service) + throws IOException, YarnException { + String serviceName = service.getName(); + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + ServiceApiUtil.validateAndResolveService(service, fs, getConfig()); + verifyNoLiveAppInRM(serviceName, "create"); + Path appDir = checkAppNotExistOnHdfs(service); + + // Write the definition first and then submit - AM will read the definition + createDirAndPersistApp(appDir, service); + ApplicationId appId = submitApp(service); + cachedAppIds.put(serviceName, appId); + service.setId(appId.toString()); + // update app definition with appId + persistAppDef(appDir, service); + return appId; + } + + // Called by ServiceCLI + protected int actionFlexByCLI(ClientArgs args) + throws YarnException, IOException { + ActionFlexArgs flexArgs = args.getActionFlexArgs(); + Map<String, Long> componentCounts = + new HashMap<>(flexArgs.getComponentMap().size()); + Service persistedService = + ServiceApiUtil.loadService(fs, flexArgs.getClusterName()); + if (!StringUtils.isEmpty(persistedService.getId())) { + cachedAppIds.put(persistedService.getName(), + ApplicationId.fromString(persistedService.getId())); + } else { + throw new YarnException(persistedService.getName() + + " appId is null, may be not submitted to YARN yet"); + } + + for (Map.Entry<String, String> entry : flexArgs.getComponentMap() + .entrySet()) { + String compName = entry.getKey(); + ServiceApiUtil.validateNameFormat(compName, getConfig()); + Component component = persistedService.getComponent(compName); + if (component == null) { + throw new IllegalArgumentException(entry.getKey() + " does not exist !"); + } + long numberOfContainers = + parseNumberOfContainers(component, entry.getValue()); + componentCounts.put(compName, numberOfContainers); + } + // throw usage exception if no changes proposed + if (componentCounts.size() == 0) { + actionHelp(ACTION_FLEX, args); + } + flexComponents(args.getClusterName(), componentCounts, persistedService); + return EXIT_SUCCESS; + } + + // Parse the number of containers requested by user, e.g. + // +5 means add 5 additional containers + // -5 means reduce 5 containers, if it goes to negative, sets it to 0 + // 5 means sets it to 5 containers. + private long parseNumberOfContainers(Component component, String newNumber) { + + long orig = component.getNumberOfContainers(); + if (newNumber.startsWith("+")) { + return orig + Long.parseLong(newNumber.substring(1)); + } else if (newNumber.startsWith("-")) { + long ret = orig - Long.parseLong(newNumber.substring(1)); + if (ret < 0) { + LOG.warn(MessageFormat.format( + "[COMPONENT {}]: component count goes to negative ({}{} = {}), reset it to 0.", + component.getName(), orig, newNumber, ret)); + ret = 0; + } + return ret; + } else { + return Long.parseLong(newNumber); + } + } + + // Called by Rest Service + public Map<String, Long> flexByRestService(String serviceName, + Map<String, Long> componentCounts) throws YarnException, IOException { + // load app definition + Service persistedService = ServiceApiUtil.loadService(fs, serviceName); + if (StringUtils.isEmpty(persistedService.getId())) { + throw new YarnException( + serviceName + " appId is null, may be not submitted to YARN yet"); + } + cachedAppIds.put(persistedService.getName(), + ApplicationId.fromString(persistedService.getId())); + return flexComponents(serviceName, componentCounts, persistedService); + } + + private Map<String, Long> flexComponents(String serviceName, + Map<String, Long> componentCounts, Service persistedService) + throws YarnException, IOException { + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + + Map<String, Long> original = new HashMap<>(componentCounts.size()); + + ComponentCountProto.Builder countBuilder = ComponentCountProto.newBuilder(); + FlexComponentsRequestProto.Builder requestBuilder = + FlexComponentsRequestProto.newBuilder(); + + for (Component persistedComp : persistedService.getComponents()) { + String name = persistedComp.getName(); + if (componentCounts.containsKey(persistedComp.getName())) { + original.put(name, persistedComp.getNumberOfContainers()); + persistedComp.setNumberOfContainers(componentCounts.get(name)); + + // build the request + countBuilder.setName(persistedComp.getName()) + .setNumberOfContainers(persistedComp.getNumberOfContainers()); + requestBuilder.addComponents(countBuilder.build()); + } + } + if (original.size() < componentCounts.size()) { + componentCounts.keySet().removeAll(original.keySet()); + throw new YarnException("Components " + componentCounts.keySet() + + " do not exist in app definition."); + } + jsonSerDeser + .save(fs.getFileSystem(), ServiceApiUtil.getServiceJsonPath(fs, serviceName), + persistedService, true); + + ApplicationReport appReport = + yarnClient.getApplicationReport(getAppId(serviceName)); + if (appReport.getYarnApplicationState() != RUNNING) { + String message = + serviceName + " is at " + appReport.getYarnApplicationState() + + " state, flex can only be invoked when service is running"; + LOG.error(message); + throw new YarnException(message); + } + if (StringUtils.isEmpty(appReport.getHost())) { + throw new YarnException(serviceName + " AM hostname is empty"); + } + ClientAMProtocol proxy = + createAMProxy(appReport.getHost(), appReport.getRpcPort()); + proxy.flexComponents(requestBuilder.build()); + for (Map.Entry<String, Long> entry : original.entrySet()) { + LOG.info("[COMPONENT {}]: number of containers changed from {} to {}", + entry.getKey(), entry.getValue(), + componentCounts.get(entry.getKey())); + } + return original; + } + + public int actionStop(String serviceName, boolean waitForAppStopped) + throws YarnException, IOException { + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + ApplicationId currentAppId = getAppId(serviceName); + ApplicationReport report = yarnClient.getApplicationReport(currentAppId); + if (terminatedStates.contains(report.getYarnApplicationState())) { + LOG.info("Service {} is already in a terminated state {}", serviceName, + report.getYarnApplicationState()); + return EXIT_SUCCESS; + } + if (preRunningStates.contains(report.getYarnApplicationState())) { + String msg = serviceName + " is at " + report.getYarnApplicationState() + + ", forcefully killed by user!"; + yarnClient.killApplication(currentAppId, msg); + LOG.info(msg); + return EXIT_SUCCESS; + } + if (StringUtils.isEmpty(report.getHost())) { + throw new YarnException(serviceName + " AM hostname is empty"); + } + LOG.info("Stopping service {}, with appId = {}", serviceName, currentAppId); + try { + ClientAMProtocol proxy = + createAMProxy(report.getHost(), report.getRpcPort()); + cachedAppIds.remove(serviceName); + if (proxy != null) { + // try to stop the app gracefully. + StopRequestProto request = StopRequestProto.newBuilder().build(); + proxy.stop(request); + LOG.info("Service " + serviceName + " is being gracefully stopped..."); + } else { + yarnClient.killApplication(currentAppId, + serviceName + " is forcefully killed by user!"); + LOG.info("Forcefully kill the service: " + serviceName); + return EXIT_SUCCESS; + } + + if (!waitForAppStopped) { + return EXIT_SUCCESS; + } + // Wait until the app is killed. + long startTime = System.currentTimeMillis(); + int pollCount = 0; + while (true) { + Thread.sleep(2000); + report = yarnClient.getApplicationReport(currentAppId); + if (terminatedStates.contains(report.getYarnApplicationState())) { + LOG.info("Service " + serviceName + " is stopped."); + break; + } + // Forcefully kill after 10 seconds. + if ((System.currentTimeMillis() - startTime) > 10000) { + LOG.info("Stop operation timeout stopping, forcefully kill the app " + + serviceName); + yarnClient.killApplication(currentAppId, + "Forcefully kill the app by user"); + break; + } + if (++pollCount % 10 == 0) { + LOG.info("Waiting for service " + serviceName + " to be stopped."); + } + } + } catch (IOException | YarnException | InterruptedException e) { + LOG.info("Failed to stop " + serviceName + + " gracefully, forcefully kill the app."); + yarnClient.killApplication(currentAppId, "Forcefully kill the app"); + } + return EXIT_SUCCESS; + } + + public int actionDestroy(String serviceName) throws Exception { + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + verifyNoLiveAppInRM(serviceName, "Destroy"); + Path appDir = fs.buildClusterDirPath(serviceName); + FileSystem fileSystem = fs.getFileSystem(); + // remove from the appId cache + cachedAppIds.remove(serviceName); + if (fileSystem.exists(appDir)) { + if (fileSystem.delete(appDir, true)) { + LOG.info("Successfully deleted service dir for " + serviceName + ": " + + appDir); + } else { + String message = + "Failed to delete service + " + serviceName + " at: " + appDir; + LOG.info(message); + throw new YarnException(message); + } + } + deleteZKNode(serviceName); + String registryPath = ServiceRegistryUtils.registryPathForInstance(serviceName); + try { + getRegistryClient().delete(registryPath, true); + } catch (IOException e) { + LOG.warn("Error deleting registry entry {}", registryPath, e); + } + LOG.info("Destroyed cluster {}", serviceName); + return EXIT_SUCCESS; + } + + private synchronized RegistryOperations getRegistryClient() + throws SliderException, IOException { + + if (registryClient == null) { + registryClient = + RegistryOperationsFactory.createInstance("ServiceClient", getConfig()); + registryClient.init(getConfig()); + registryClient.start(); + } + return registryClient; + } + + private void deleteZKNode(String clusterName) throws Exception { + CuratorFramework curatorFramework = getCuratorClient(); + String user = RegistryUtils.currentUser(); + String zkPath = ServiceRegistryUtils.mkClusterPath(user, clusterName); + if (curatorFramework.checkExists().forPath(zkPath) != null) { + curatorFramework.delete().deletingChildrenIfNeeded().forPath(zkPath); + LOG.info("Deleted zookeeper path: " + zkPath); + } + } + + private synchronized CuratorFramework getCuratorClient() + throws BadConfigException { + String registryQuorum = + getConfig().get(RegistryConstants.KEY_REGISTRY_ZK_QUORUM); + + // though if neither is set: trouble + if (SliderUtils.isUnset(registryQuorum)) { + throw new BadConfigException( + "No Zookeeper quorum provided in the" + " configuration property " + + RegistryConstants.KEY_REGISTRY_ZK_QUORUM); + } + ZookeeperUtils.splitToHostsAndPortsStrictly(registryQuorum); + + if (curatorClient == null) { + curatorClient = + CuratorFrameworkFactory.builder().connectString(registryQuorum) + .sessionTimeoutMs(10000).retryPolicy(new RetryNTimes(5, 2000)) + .build(); + curatorClient.start(); + } + return curatorClient; + } + + private int actionHelp(String actionName, CommonArgs args) + throws YarnException, IOException { + throw new UsageException(CommonArgs.usage(args, actionName)); + } + + private void verifyNoLiveAppInRM(String serviceName, String action) + throws IOException, YarnException { + Set<String> types = new HashSet<>(1); + types.add(YarnServiceConstants.APP_TYPE); + Set<String> tags = null; + if (serviceName != null) { + tags = Collections.singleton(SliderUtils.createNameTag(serviceName)); + } + GetApplicationsRequest request = GetApplicationsRequest.newInstance(); + request.setApplicationTypes(types); + request.setApplicationTags(tags); + request.setApplicationStates(liveStates); + List<ApplicationReport> reports = yarnClient.getApplications(request); + if (!reports.isEmpty()) { + throw new YarnException( + "Failed to " + action + " service, as " + serviceName + + " already exists."); + } + } + + private ApplicationId submitApp(Service app) + throws IOException, YarnException { + String serviceName = app.getName(); + Configuration conf = getConfig(); + Path appRootDir = fs.buildClusterDirPath(app.getName()); + + YarnClientApplication yarnApp = yarnClient.createApplication(); + ApplicationSubmissionContext submissionContext = + yarnApp.getApplicationSubmissionContext(); + ServiceApiUtil.validateCompResourceSize( + yarnApp.getNewApplicationResponse().getMaximumResourceCapability(), + app); + + submissionContext.setKeepContainersAcrossApplicationAttempts(true); + if (app.getLifetime() > 0) { + Map<ApplicationTimeoutType, Long> appTimeout = new HashMap<>(); + appTimeout.put(ApplicationTimeoutType.LIFETIME, app.getLifetime()); + submissionContext.setApplicationTimeouts(appTimeout); + } + submissionContext.setMaxAppAttempts(conf.getInt( + YarnServiceConf.AM_RESTART_MAX, 2)); + + Map<String, LocalResource> localResources = new HashMap<>(); + + // copy local slideram-log4j.properties to hdfs and add to localResources + boolean hasAMLog4j = + addAMLog4jResource(serviceName, conf, localResources); + // copy jars to hdfs and add to localResources + addJarResource(serviceName, localResources); + // add keytab if in secure env + addKeytabResourceIfSecure(fs, localResources, conf, serviceName); + if (LOG.isDebugEnabled()) { + printLocalResources(localResources); + } + Map<String, String> env = addAMEnv(conf); + + // create AM CLI + String cmdStr = + buildCommandLine(serviceName, conf, appRootDir, hasAMLog4j); + submissionContext.setResource(Resource.newInstance(YarnServiceConf + .getLong(YarnServiceConf.AM_RESOURCE_MEM, YarnServiceConf.DEFAULT_KEY_AM_RESOURCE_MEM, + app.getConfiguration(), conf), 1)); + String queue = app.getQueue(); + if (StringUtils.isEmpty(queue)) { + queue = conf.get(YARN_QUEUE, "default"); + } + submissionContext.setQueue(queue); + submissionContext.setApplicationName(serviceName); + submissionContext.setApplicationType(YarnServiceConstants.APP_TYPE); + Set<String> appTags = + AbstractClientProvider.createApplicationTags(serviceName, null, null); + if (!appTags.isEmpty()) { + submissionContext.setApplicationTags(appTags); + } + ContainerLaunchContext amLaunchContext = + Records.newRecord(ContainerLaunchContext.class); + amLaunchContext.setCommands(Collections.singletonList(cmdStr)); + amLaunchContext.setEnvironment(env); + amLaunchContext.setLocalResources(localResources); + submissionContext.setAMContainerSpec(amLaunchContext); + yarnClient.submitApplication(submissionContext); + return submissionContext.getApplicationId(); + } + + private void printLocalResources(Map<String, LocalResource> map) { + LOG.debug("Added LocalResource for localization: "); + StringBuilder builder = new StringBuilder(); + for (Map.Entry<String, LocalResource> entry : map.entrySet()) { + builder.append(entry.getKey()).append(" -> ") + .append(entry.getValue().getResource().getFile()) + .append(System.lineSeparator()); + } + LOG.debug(builder.toString()); + } + + private String buildCommandLine(String serviceName, Configuration conf, + Path appRootDir, boolean hasSliderAMLog4j) throws BadConfigException { + JavaCommandLineBuilder CLI = new JavaCommandLineBuilder(); + CLI.forceIPv4().headless(); + //TODO CLI.setJVMHeap + //TODO CLI.addJVMOPTS + if (hasSliderAMLog4j) { + CLI.sysprop(SYSPROP_LOG4J_CONFIGURATION, YARN_SERVICE_LOG4J_FILENAME); + CLI.sysprop(SYSPROP_LOG_DIR, ApplicationConstants.LOG_DIR_EXPANSION_VAR); + } + CLI.add(ServiceMaster.class.getCanonicalName()); + CLI.add(ACTION_CREATE, serviceName); + //TODO debugAM CLI.add(Arguments.ARG_DEBUG) + CLI.add(Arguments.ARG_CLUSTER_URI, new Path(appRootDir, serviceName + ".json")); + // pass the registry binding + CLI.addConfOptionToCLI(conf, RegistryConstants.KEY_REGISTRY_ZK_ROOT, + RegistryConstants.DEFAULT_ZK_REGISTRY_ROOT); + CLI.addMandatoryConfOption(conf, RegistryConstants.KEY_REGISTRY_ZK_QUORUM); + + // write out the path output + CLI.addOutAndErrFiles(STDOUT_AM, STDERR_AM); + String cmdStr = CLI.build(); + LOG.info("AM launch command: {}", cmdStr); + return cmdStr; + } + + private Map<String, String> addAMEnv(Configuration conf) throws IOException { + Map<String, String> env = new HashMap<>(); + ClasspathConstructor classpath = + buildClasspath(YarnServiceConstants.SUBMITTED_CONF_DIR, "lib", fs, getConfig() + .getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false)); + env.put("CLASSPATH", classpath.buildClasspath()); + env.put("LANG", "en_US.UTF-8"); + env.put("LC_ALL", "en_US.UTF-8"); + env.put("LANGUAGE", "en_US.UTF-8"); + String jaas = System.getenv("HADOOP_JAAS_DEBUG"); + if (jaas != null) { + env.put("HADOOP_JAAS_DEBUG", jaas); + } + if (!UserGroupInformation.isSecurityEnabled()) { + String userName = UserGroupInformation.getCurrentUser().getUserName(); + LOG.info("Run as user " + userName); + // HADOOP_USER_NAME env is used by UserGroupInformation when log in + // This env makes AM run as this user + env.put("HADOOP_USER_NAME", userName); + } + LOG.info("AM env: \n{}", stringifyMap(env)); + return env; + } + + protected Path addJarResource(String serviceName, + Map<String, LocalResource> localResources) + throws IOException, SliderException { + Path libPath = fs.buildClusterDirPath(serviceName); + ProviderUtils + .addProviderJar(localResources, ServiceMaster.class, SERVICE_CORE_JAR, fs, + libPath, "lib", false); + Path dependencyLibTarGzip = fs.getDependencyTarGzip(); + if (fs.isFile(dependencyLibTarGzip)) { + LOG.info("Loading lib tar from " + fs.getFileSystem().getScheme() + ":/" + + dependencyLibTarGzip); + SliderUtils.putAmTarGzipAndUpdate(localResources, fs); + } else { + String[] libs = SliderUtils.getLibDirs(); + for (String libDirProp : libs) { + ProviderUtils.addAllDependencyJars(localResources, fs, libPath, "lib", + libDirProp); + } + } + return libPath; + } + + private boolean addAMLog4jResource(String serviceName, Configuration conf, + Map<String, LocalResource> localResources) + throws IOException, BadClusterStateException { + boolean hasAMLog4j = false; + String hadoopConfDir = + System.getenv(ApplicationConstants.Environment.HADOOP_CONF_DIR.name()); + if (hadoopConfDir != null) { + File localFile = + new File(hadoopConfDir, YarnServiceConstants.YARN_SERVICE_LOG4J_FILENAME); + if (localFile.exists()) { + Path localFilePath = createLocalPath(localFile); + Path appDirPath = fs.buildClusterDirPath(serviceName); + Path remoteConfPath = + new Path(appDirPath, YarnServiceConstants.SUBMITTED_CONF_DIR); + Path remoteFilePath = + new Path(remoteConfPath, YarnServiceConstants.YARN_SERVICE_LOG4J_FILENAME); + copy(conf, localFilePath, remoteFilePath); + LocalResource localResource = + fs.createAmResource(remoteConfPath, LocalResourceType.FILE); + localResources.put(localFilePath.getName(), localResource); + hasAMLog4j = true; + } else { + LOG.warn("AM log4j property file doesn't exist: " + localFile); + } + } + return hasAMLog4j; + } + + public int actionStart(String serviceName) throws YarnException, IOException { + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + Path appDir = checkAppExistOnHdfs(serviceName); + Service service = ServiceApiUtil.loadService(fs, serviceName); + ServiceApiUtil.validateAndResolveService(service, fs, getConfig()); + // see if it is actually running and bail out; + verifyNoLiveAppInRM(serviceName, "thaw"); + ApplicationId appId = submitApp(service); + service.setId(appId.toString()); + // write app definition on to hdfs + createDirAndPersistApp(appDir, service); + return 0; + } + + private Path checkAppNotExistOnHdfs(Service service) + throws IOException, SliderException { + Path appDir = fs.buildClusterDirPath(service.getName()); + fs.verifyDirectoryNonexistent( + new Path(appDir, service.getName() + ".json")); + return appDir; + } + + private Path checkAppExistOnHdfs(String serviceName) + throws IOException, SliderException { + Path appDir = fs.buildClusterDirPath(serviceName); + fs.verifyPathExists(new Path(appDir, serviceName + ".json")); + return appDir; + } + + private void createDirAndPersistApp(Path appDir, Service service) + throws IOException, SliderException { + FsPermission appDirPermission = new FsPermission("750"); + fs.createWithPermissions(appDir, appDirPermission); + persistAppDef(appDir, service); + } + + private void persistAppDef(Path appDir, Service service) + throws IOException { + Path appJson = new Path(appDir, service.getName() + ".json"); + jsonSerDeser + .save(fs.getFileSystem(), appJson, service, true); + LOG.info( + "Persisted service " + service.getName() + " at " + appJson); + } + + private void addKeytabResourceIfSecure(SliderFileSystem fileSystem, + Map<String, LocalResource> localResource, Configuration conf, + String serviceName) throws IOException, BadConfigException { + if (!UserGroupInformation.isSecurityEnabled()) { + return; + } + String keytabPreInstalledOnHost = + conf.get(YarnServiceConf.KEY_AM_KEYTAB_LOCAL_PATH); + if (StringUtils.isEmpty(keytabPreInstalledOnHost)) { + String amKeytabName = + conf.get(YarnServiceConf.KEY_AM_LOGIN_KEYTAB_NAME); + String keytabDir = conf.get(YarnServiceConf.KEY_HDFS_KEYTAB_DIR); + Path keytabPath = + fileSystem.buildKeytabPath(keytabDir, amKeytabName, serviceName); + if (fileSystem.getFileSystem().exists(keytabPath)) { + LocalResource keytabRes = + fileSystem.createAmResource(keytabPath, LocalResourceType.FILE); + localResource + .put(YarnServiceConstants.KEYTAB_DIR + "/" + amKeytabName, keytabRes); + LOG.info("Adding AM keytab on hdfs: " + keytabPath); + } else { + LOG.warn("No keytab file was found at {}.", keytabPath); + if (conf.getBoolean(YarnServiceConf.KEY_AM_LOGIN_KEYTAB_REQUIRED, false)) { + throw new BadConfigException("No keytab file was found at %s.", + keytabPath); + } else { + LOG.warn("The AM will be " + + "started without a kerberos authenticated identity. " + + "The service is therefore not guaranteed to remain " + + "operational beyond 24 hours."); + } + } + } + } + + public String updateLifetime(String serviceName, long lifetime) + throws YarnException, IOException { + ApplicationId currentAppId = getAppId(serviceName); + ApplicationReport report = yarnClient.getApplicationReport(currentAppId); + if (report == null) { + throw new YarnException("Service not found for " + serviceName); + } + ApplicationId appId = report.getApplicationId(); + LOG.info("Updating lifetime of an service: serviceName = " + serviceName + + ", appId = " + appId + ", lifetime = " + lifetime); + Map<ApplicationTimeoutType, String> map = new HashMap<>(); + String newTimeout = + Times.formatISO8601(System.currentTimeMillis() + lifetime * 1000); + map.put(ApplicationTimeoutType.LIFETIME, newTimeout); + UpdateApplicationTimeoutsRequest request = + UpdateApplicationTimeoutsRequest.newInstance(appId, map); + yarnClient.updateApplicationTimeouts(request); + LOG.info( + "Successfully updated lifetime for an service: serviceName = " + serviceName + + ", appId = " + appId + ". New expiry time in ISO8601 format is " + + newTimeout); + return newTimeout; + } + + public ServiceState convertState(FinalApplicationStatus status) { + switch (status) { + case UNDEFINED: + return ServiceState.ACCEPTED; + case FAILED: + case KILLED: + return ServiceState.FAILED; + case ENDED: + case SUCCEEDED: + return ServiceState.STOPPED; + } + return ServiceState.ACCEPTED; + } + + public Service getStatus(String serviceName) + throws IOException, YarnException { + ServiceApiUtil.validateNameFormat(serviceName, getConfig()); + ApplicationId currentAppId = getAppId(serviceName); + ApplicationReport appReport = yarnClient.getApplicationReport(currentAppId); + Service appSpec = new Service(); + appSpec.setName(serviceName); + appSpec.setState(convertState(appReport.getFinalApplicationStatus())); + ApplicationTimeout lifetime = + appReport.getApplicationTimeouts().get(ApplicationTimeoutType.LIFETIME); + if (lifetime != null) { + appSpec.setLifetime(lifetime.getRemainingTime()); + } + + if (appReport.getYarnApplicationState() != RUNNING) { + LOG.info("Service {} is at {} state", serviceName, + appReport.getYarnApplicationState()); + return appSpec; + } + if (StringUtils.isEmpty(appReport.getHost())) { + LOG.warn(serviceName + " AM hostname is empty"); + return appSpec; + } + ClientAMProtocol amProxy = + createAMProxy(appReport.getHost(), appReport.getRpcPort()); + GetStatusResponseProto response = + amProxy.getStatus(GetStatusRequestProto.newBuilder().build()); + appSpec = jsonSerDeser.fromJson(response.getStatus()); + + return appSpec; + } + + public YarnClient getYarnClient() { + return this.yarnClient; + } + + public int actionDependency(ActionDependencyArgs args) + throws IOException, YarnException { + String currentUser = RegistryUtils.currentUser(); + LOG.info("Running command as user {}", currentUser); + + Path dependencyLibTarGzip = fs.getDependencyTarGzip(); + + // Check if dependency has already been uploaded, in which case log + // appropriately and exit success (unless overwrite has been requested) + if (fs.isFile(dependencyLibTarGzip) && !args.overwrite) { + System.out.println(String.format( + "Dependency libs are already uploaded to %s. Use %s " + + "if you want to re-upload", dependencyLibTarGzip.toUri(), + Arguments.ARG_OVERWRITE)); + return EXIT_SUCCESS; + } + + String[] libDirs = SliderUtils.getLibDirs(); + if (libDirs.length > 0) { + File tempLibTarGzipFile = File.createTempFile( + YarnServiceConstants.DEPENDENCY_TAR_GZ_FILE_NAME + "_", + YarnServiceConstants.DEPENDENCY_TAR_GZ_FILE_EXT); + // copy all jars + tarGzipFolder(libDirs, tempLibTarGzipFile, createJarFilter()); + + LOG.info("Version Info: " + VersionInfo.getBuildVersion()); + fs.copyLocalFileToHdfs(tempLibTarGzipFile, dependencyLibTarGzip, + new FsPermission(YarnServiceConstants.DEPENDENCY_DIR_PERMISSIONS)); + return EXIT_SUCCESS; + } else { + return EXIT_FALSE; + } + } + + protected ClientAMProtocol createAMProxy(String host, int port) + throws IOException { + InetSocketAddress address = + NetUtils.createSocketAddrForHost(host, port); + return ClientAMProxy.createProxy(getConfig(), ClientAMProtocol.class, + UserGroupInformation.getCurrentUser(), rpc, address); + } + + private synchronized ApplicationId getAppId(String serviceName) + throws IOException, YarnException { + if (cachedAppIds.containsKey(serviceName)) { + return cachedAppIds.get(serviceName); + } + Service persistedService = ServiceApiUtil.loadService(fs, serviceName); + if (persistedService == null) { + throw new YarnException("Service " + serviceName + + " doesn't exist on hdfs. Please check if the app exists in RM"); + } + ApplicationId currentAppId = ApplicationId.fromString(persistedService.getId()); + cachedAppIds.put(serviceName, currentAppId); + return currentAppId; + } +}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java new file mode 100644 index 0000000..ea3bb0a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractActionArgs.java @@ -0,0 +1,158 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException; +import org.apache.hadoop.yarn.service.exceptions.ErrorStrings; +import org.apache.hadoop.yarn.service.exceptions.UsageException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Base args for all actions + */ +public abstract class AbstractActionArgs extends ArgOps implements Arguments { + protected static final Logger log = + LoggerFactory.getLogger(AbstractActionArgs.class); + + + protected AbstractActionArgs() { + } + + /** + * URI/binding to the filesystem + */ + @Parameter(names = {ARG_FILESYSTEM, ARG_FILESYSTEM_LONG}, + description = "Filesystem Binding") + public String filesystemBinding; + + @Parameter(names = {ARG_BASE_PATH}, + description = "Service base path on the filesystem", + converter = PathArgumentConverter.class) + public Path basePath; + + /** + * This is the default parameter + */ + @Parameter + public final List<String> parameters = new ArrayList<>(); + + /** + * get the name: relies on arg 1 being the cluster name in all operations + * @return the name argument, null if there is none + */ + public String getClusterName() { + return (parameters.isEmpty()) ? null : parameters.get(0); + } + + /** + -D name=value + + Define an configuration option which overrides any options in + the configuration XML files of the image or in the image configuration + directory. The values will be persisted. + Configuration options are only passed to the cluster when creating or reconfiguring a cluster. + + */ + + @Parameter(names = ARG_DEFINE, arity = 1, description = "Definitions") + public final List<String> definitions = new ArrayList<>(); + + /** + * System properties + */ + @Parameter(names = {ARG_SYSPROP}, arity = 1, + description = "system properties in the form name value" + + " These are set after the JVM is started.") + public final List<String> sysprops = new ArrayList<>(0); + + + @Parameter(names = {ARG_MANAGER_SHORT, ARG_MANAGER}, + description = "Binding (usually hostname:port) of the YARN resource manager") + public String manager; + + + @Parameter(names = ARG_DEBUG, description = "Debug mode") + public boolean debug = false; + + @Parameter(names = {ARG_HELP}, description = "Help", help = true) + public boolean help = false; + + /** + * Get the min #of params expected + * @return the min number of params in the {@link #parameters} field + */ + public int getMinParams() { + return 1; + } + + /** + * Get the name of the action + * @return the action name + */ + public abstract String getActionName() ; + + /** + * Get the max #of params expected + * @return the number of params in the {@link #parameters} field; + */ + public int getMaxParams() { + return getMinParams(); + } + + public void validate() throws BadCommandArgumentsException, UsageException { + + int minArgs = getMinParams(); + int actionArgSize = parameters.size(); + if (minArgs > actionArgSize) { + throw new BadCommandArgumentsException( + ErrorStrings.ERROR_NOT_ENOUGH_ARGUMENTS + getActionName() + + ", Expected minimum " + minArgs + " but got " + actionArgSize); + } + int maxArgs = getMaxParams(); + if (maxArgs == -1) { + maxArgs = minArgs; + } + if (actionArgSize > maxArgs) { + String message = String.format("%s for action %s: limit is %d but saw %d: ", + ErrorStrings.ERROR_TOO_MANY_ARGUMENTS, + getActionName(), maxArgs, + actionArgSize); + + log.error(message); + int index = 1; + StringBuilder buf = new StringBuilder(message); + for (String actionArg : parameters) { + log.error("[{}] \"{}\"", index++, actionArg); + buf.append(" \"").append(actionArg).append("\" "); + } + throw new BadCommandArgumentsException(buf.toString()); + } + } + + @Override + public String toString() { + return super.toString() + ": " + getActionName(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java new file mode 100644 index 0000000..457e357 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractArgsDelegate.java @@ -0,0 +1,28 @@ +/* + * 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.service.client.params; + +import org.apache.hadoop.yarn.service.client.params.ArgOps; +import org.apache.hadoop.yarn.service.client.params.Arguments; + +/** + * Base class for all the delegates + */ +public class AbstractArgsDelegate extends ArgOps implements Arguments { +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java new file mode 100644 index 0000000..3a3a19a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/AbstractClusterBuildingActionArgs.java @@ -0,0 +1,58 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParametersDelegate; +import com.google.common.annotations.VisibleForTesting; +import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * Abstract Action to build things; shares args across build and + * list + */ +public abstract class AbstractClusterBuildingActionArgs + extends AbstractActionArgs { + @Parameter(names = {ARG_APPDEF}, + description = "Template service definition file in JSON format.") + public File appDef; + + public File getAppDef() { + return appDef; + } + + @Parameter(names = { + ARG_QUEUE }, description = "Queue to submit the service") + public String queue; + + @Parameter(names = { + ARG_LIFETIME }, description = "Lifetime of the service from the time of request") + public long lifetime; + + @ParametersDelegate + public ComponentArgsDelegate componentDelegate = new ComponentArgsDelegate(); + + @ParametersDelegate + public OptionArgsDelegate optionsDelegate = + new OptionArgsDelegate(); +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java new file mode 100644 index 0000000..c2ff545 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionBuildArgs.java @@ -0,0 +1,31 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameters; + +@Parameters(commandNames = { SliderActions.ACTION_BUILD}, + commandDescription = SliderActions.DESCRIBE_ACTION_BUILD) + +public class ActionBuildArgs extends AbstractClusterBuildingActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_BUILD; + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java new file mode 100644 index 0000000..c43d61a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionClientArgs.java @@ -0,0 +1,71 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs; +import org.apache.hadoop.yarn.service.client.params.SliderActions; + +import java.io.File; + +@Parameters(commandNames = { SliderActions.ACTION_CLIENT}, + commandDescription = SliderActions.DESCRIBE_ACTION_CLIENT) + +public class ActionClientArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_CLIENT; + } + + @Parameter(names = {ARG_INSTALL}, + description = "Install client") + public boolean install; + + @Parameter(names = {ARG_NAME}, + description = "The name of the service") + public String name; + + @Parameter(names = {ARG_PACKAGE}, + description = "Path to app package") + public String packageURI; + + @Parameter(names = {ARG_DEST}, + description = "The location where to install the client") + public File installLocation; + + @Parameter(names = {ARG_CONFIG}, + description = "Client configuration") + public File clientConfig; + + /** + * Get the min #of params expected + * + * @return the min number of params in the {@link #parameters} field + */ + public int getMinParams() { + return 0; + } + + @Override + public int getMaxParams() { + return 1; + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java new file mode 100644 index 0000000..eecffb6 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionCreateArgs.java @@ -0,0 +1,33 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameters; + +@Parameters(commandNames = { SliderActions.ACTION_CREATE}, + commandDescription = SliderActions.DESCRIBE_ACTION_CREATE) + +public class ActionCreateArgs extends AbstractClusterBuildingActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_CREATE; + } +} + http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java new file mode 100644 index 0000000..51e07c9 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDependencyArgs.java @@ -0,0 +1,65 @@ +/* + * 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.service.client.params; + +import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException; +import org.apache.hadoop.yarn.service.exceptions.UsageException; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(commandNames = { SliderActions.ACTION_DEPENDENCY }, + commandDescription = SliderActions.DESCRIBE_ACTION_DEPENDENCY) +public class ActionDependencyArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_DEPENDENCY; + } + + @Parameter(names = { ARG_UPLOAD }, + description = "Upload AM and agent libraries to HDFS for this client") + public boolean upload; + + @Parameter(names = { ARG_OVERWRITE }, + description = "Overwrite current uploaded dependency libs") + public boolean overwrite = false; + + /** + * Get the min #of params expected + * + * @return the min number of params in the {@link #parameters} field + */ + public int getMinParams() { + return 0; + } + + @Override + public int getMaxParams() { + return 1; + } + + @Override + public void validate() throws BadCommandArgumentsException, UsageException { + super.validate(); + + if (!upload) { + throw new UsageException("Option " + ARG_UPLOAD + " is mandatory"); + } + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java new file mode 100644 index 0000000..8c41c04 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionDestroyArgs.java @@ -0,0 +1,37 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(commandNames = { SliderActions.ACTION_DESTROY}, + commandDescription = SliderActions.DESCRIBE_ACTION_DESTROY) + +public class ActionDestroyArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_DESTROY; + } + + @Parameter(names = {ARG_FORCE}, + description = "force the operation") + public boolean force; +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java new file mode 100644 index 0000000..088ad47 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionExistsArgs.java @@ -0,0 +1,49 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs; +import org.apache.hadoop.yarn.service.client.params.SliderActions; + +import java.io.File; + +@Parameters(commandNames = { SliderActions.ACTION_EXISTS}, + commandDescription = SliderActions.DESCRIBE_ACTION_EXISTS) + +public class ActionExistsArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_EXISTS; + } + + @Parameter(names = {ARG_LIVE}, + description = "verify that the service is running") + public boolean live; + + @Parameter(names = {ARG_STATE}, + description = "verify that the service is in the specific YARN state") + public String state = ""; + + @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT}, + description = "output file for any service report") + public File out; +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java new file mode 100644 index 0000000..b7acf58 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFlexArgs.java @@ -0,0 +1,50 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameters; +import com.beust.jcommander.ParametersDelegate; +import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException; + +import java.util.List; +import java.util.Map; + +@Parameters(commandNames = { SliderActions.ACTION_FLEX}, + commandDescription = SliderActions.DESCRIBE_ACTION_FLEX) + +public class ActionFlexArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_FLEX; + } + + @ParametersDelegate + public ComponentArgsDelegate componentDelegate = new ComponentArgsDelegate(); + + /** + * Get the component mapping (may be empty, but never null) + * @return mapping + * @throws BadCommandArgumentsException parse problem + */ + public Map<String, String> getComponentMap() throws + BadCommandArgumentsException { + return componentDelegate.getComponentMap(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java new file mode 100644 index 0000000..aecf0eb --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionFreezeArgs.java @@ -0,0 +1,56 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.beust.jcommander.ParametersDelegate; + +@Parameters(commandNames = { SliderActions.ACTION_STOP }, + commandDescription = SliderActions.DESCRIBE_ACTION_FREEZE) + +public class ActionFreezeArgs extends AbstractActionArgs implements + WaitTimeAccessor { + @Override + public String getActionName() { + return SliderActions.ACTION_STOP; + } + + public static final String FREEZE_COMMAND_ISSUED = "stop command issued"; + @ParametersDelegate + public WaitArgsDelegate waitDelegate = new WaitArgsDelegate(); + + @Override + public int getWaittime() { + return waitDelegate.getWaittime(); + } + + @Override + public void setWaittime(int waittime) { + waitDelegate.setWaittime(waittime); + } + + @Parameter(names={ARG_MESSAGE}, + description = "reason for the operation") + public String message = FREEZE_COMMAND_ISSUED; + + @Parameter(names = {ARG_FORCE}, + description = "force the operation") + public boolean force; +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java new file mode 100644 index 0000000..51aa88a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionHelpArgs.java @@ -0,0 +1,44 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs; +import org.apache.hadoop.yarn.service.client.params.SliderActions; + +/** + * The Help command + */ +@Parameters(commandNames = { SliderActions.ACTION_HELP}, + commandDescription = SliderActions.DESCRIBE_ACTION_HELP) +public class ActionHelpArgs extends AbstractActionArgs { + @Override + public String getActionName() { + return SliderActions.ACTION_HELP; + } + + /** + * Get the min #of params expected + * @return the min number of params in the {@link #parameters} field + */ + @Override + public int getMinParams() { + return 0; + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java new file mode 100644 index 0000000..061121e --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKDiagArgs.java @@ -0,0 +1,76 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.utils.SliderUtils; +import org.apache.hadoop.yarn.service.exceptions.BadCommandArgumentsException; +import org.apache.hadoop.yarn.service.exceptions.UsageException; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +@Parameters(commandNames = { SliderActions.ACTION_KDIAG}, + commandDescription = SliderActions.DESCRIBE_ACTION_KDIAG) + +public class ActionKDiagArgs extends AbstractActionArgs { + + @Override + public String getActionName() { + return SliderActions.ACTION_KDIAG; + } + + @Parameter(names = {ARG_SERVICES}, variableArity = true, + description =" list of services to check") + public List<String> services = new ArrayList<>(); + + @Parameter(names = {ARG_OUTPUT, ARG_OUTPUT_SHORT}, + description = "output file for report") + public File out; + + @Parameter(names = {ARG_KEYTAB}, description = "keytab to use") + public File keytab; + + @Parameter(names = {ARG_KEYLEN}, description = "minimum key length") + public int keylen = 256; + + @Parameter(names = {ARG_PRINCIPAL}, description = "principal to log in from a keytab") + public String principal; + + @Parameter(names = {ARG_SECURE}, description = "Is security required") + public boolean secure = false; + + @Override + public int getMinParams() { + return 0; + } + + @Override + public void validate() throws BadCommandArgumentsException, UsageException { + super.validate(); + if (keytab != null && SliderUtils.isUnset(principal)) { + throw new UsageException("Missing argument " + ARG_PRINCIPAL); + } + if (keytab == null && SliderUtils.isSet(principal)) { + throw new UsageException("Missing argument " + ARG_KEYTAB); + } + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java new file mode 100644 index 0000000..7e51457 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionKeytabArgs.java @@ -0,0 +1,76 @@ +/* + * 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.service.client.params; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs; +import org.apache.hadoop.yarn.service.client.params.SliderActions; + +@Parameters(commandNames = { SliderActions.ACTION_KEYTAB}, + commandDescription = SliderActions.DESCRIBE_ACTION_KEYTAB) + +public class ActionKeytabArgs extends AbstractActionArgs { + + public ActionKeytabArgs() { + super(); + } + + @Override + public String getActionName() { + return SliderActions.ACTION_INSTALL_KEYTAB; + } + + @Parameter(names = {ARG_KEYTABINSTALL}, + description = "Install the keytab") + public boolean install; + + @Parameter(names = {ARG_KEYTABDELETE}, + description = "Delete the keytab") + public boolean delete; + + @Parameter(names = {ARG_KEYTABLIST}, + description = "List of installed keytabs") + public boolean list; + + @Parameter(names = {ARG_KEYTAB}, + description = "Path or name of the keytab") + public String keytab; + + @Parameter(names = {ARG_FOLDER}, + description = "The name of the folder in which to store the keytab") + public String folder; + + @Parameter(names = {ARG_OVERWRITE}, description = "Overwrite existing keytab") + public boolean overwrite = false; + + /** + * Get the min #of params expected + * @return the min number of params in the {@link #parameters} field + */ + public int getMinParams() { + return 0; + } + + @Override + public int getMaxParams() { + return 3; + } + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/3928a646/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java new file mode 100644 index 0000000..c05e602 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/params/ActionListArgs.java @@ -0,0 +1,76 @@ +/* + * 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.service.client.params; + +import java.util.HashSet; +import java.util.Set; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.apache.hadoop.yarn.service.client.params.AbstractActionArgs; +import org.apache.hadoop.yarn.service.client.params.SliderActions; + +@Parameters(commandNames = { SliderActions.ACTION_LIST}, + commandDescription = SliderActions.DESCRIBE_ACTION_LIST) + +public class ActionListArgs extends AbstractActionArgs { + @Override + public String getActionName() { + return SliderActions.ACTION_LIST; + } + + @Parameter(names = {ARG_LIVE}, + description = "List only live service instances") + public boolean live; + + @Parameter(names = {ARG_STATE}, + description = "list only applications in the specific YARN state") + public String state = ""; + + @Parameter(names = {ARG_VERBOSE}, + description = "print out information in details") + public boolean verbose = false; + + @Parameter(names = {ARG_CONTAINERS}, + description = "List containers of a service instance") + public boolean containers; + + @Parameter(names = {ARG_VERSION}, + description = "Filter containers by app version (used with " + + ARG_CONTAINERS + ")") + public String version; + + @Parameter(names = {ARG_COMPONENTS}, variableArity = true, + description = "Filter containers by component names (used with " + + ARG_CONTAINERS + ")") + public Set<String> components = new HashSet<>(0); + + /** + * Get the min #of params expected + * @return the min number of params in the {@link #parameters} field + */ + public int getMinParams() { + return 0; + } + + @Override + public int getMaxParams() { + return 1; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org