diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/services/api/impl/ApplicationApiService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/services/api/impl/ApplicationApiService.java index 6db69ac..c4f5d43 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/services/api/impl/ApplicationApiService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/services/api/impl/ApplicationApiService.java @@ -77,6 +77,7 @@ import org.apache.slider.common.params.ActionListArgs; import org.apache.slider.common.params.ActionRegistryArgs; import org.apache.slider.common.params.ActionThawArgs; +import org.apache.slider.common.params.ActionUpdateArgs; import org.apache.slider.common.params.ComponentArgsDelegate; import org.apache.slider.common.tools.SliderUtils; import org.apache.slider.common.tools.SliderVersionInfo; @@ -1398,14 +1399,34 @@ public Response updateApplication(@PathParam("app_name") String appName, } // If new lifetime value specified then update it - if (updateAppData.getLifetime() != null) { - // TODO: Once YARN-3813 and YARN-4205 are available + if (updateAppData.getLifetime() != null + && updateAppData.getLifetime() > 0) { + try { + updateAppLifetime(appName, updateAppData.getLifetime()); + } catch (Exception e) { + logger.error("Failed to update application (" + appName + ") lifetime (" + + updateAppData.getLifetime() + ")", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } } // If nothing happens consider it a no-op return Response.status(Status.NO_CONTENT).build(); } + private Void updateAppLifetime(String appName, long lifetime) + throws InterruptedException, YarnException, IOException { + return invokeSliderClientRunnable(new SliderClientContextRunnable() { + @Override public Void run(SliderClient sliderClient) + throws YarnException, IOException, InterruptedException { + ActionUpdateArgs args = new ActionUpdateArgs(); + args.lifetime = lifetime; + sliderClient.actionUpdate(appName, args); + return null; + } + }); + } + // create default component and initialize with app level global values private List getDefaultComponentAsList(Application app) { List comps = getDefaultComponentAsList(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java index 3f2df0a..12f7870 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/client/SliderClient.java @@ -52,6 +52,7 @@ import org.apache.hadoop.security.alias.CredentialProviderFactory; import org.apache.hadoop.util.Shell; import org.apache.hadoop.yarn.api.ApplicationConstants; +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.ApplicationTimeoutType; @@ -65,6 +66,7 @@ import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException; import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.util.ConverterUtils; +import org.apache.hadoop.yarn.util.Times; import org.apache.slider.api.ClusterDescription; import org.apache.slider.api.ClusterNode; import org.apache.slider.api.SliderApplicationApi; @@ -177,14 +179,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.BufferedReader; import java.io.Console; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.PrintStream; import java.io.PrintWriter; @@ -1602,8 +1602,33 @@ private int actionPackageDelete(ActionPackageArgs actionPackageArgs) throws public int actionUpdate(String clustername, AbstractClusterBuildingActionArgs buildInfo) throws YarnException, IOException { - buildInstanceDefinition(clustername, buildInfo, true, true); - return EXIT_SUCCESS; + if (buildInfo.lifetime > 0) { + updateLifetime(clustername, buildInfo.lifetime); + } else { + buildInstanceDefinition(clustername, buildInfo, true, true); + } + return EXIT_SUCCESS; + } + + public void updateLifetime(String appName, long lifetime) + throws YarnException, IOException { + ApplicationReport report = findInstance(appName); + if (report == null) { + throw new YarnException("Application not found for " + appName); + } + ApplicationId appId = report.getApplicationId(); + log.info("Updating lifetime of an application: appName = " + appName + + ", appId = " + appId+ ", lifetime = " + lifetime); + Map 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 application: appName = " + + appName + ", appId = " + appId + + ". New expiry time in ISO8601 format is " + newTimeout); } /** diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java index 3cb75e1..e56fc39 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/src/main/java/org/apache/slider/common/params/AbstractClusterBuildingActionArgs.java @@ -103,8 +103,7 @@ public String queue; @Parameter(names = {ARG_LIFETIME}, - description = "Life time of the application since application started at" - + " running state") + description = "Life time of the application starting from now") public long lifetime; @ParametersDelegate