Skip to content

Commit

Permalink
wardeploy improvements to support custom app names (projectkudu#2718)
Browse files Browse the repository at this point in the history
- This change allows deploying war files to web apps other than ROOT.
- Posting war file contents to /api/wardeploy?name=myappname will create the myappname webapp by deploying the war contents to wwwroot/webapps/<appname> directory. If no app name is specified, ROOT is inferred.-
  • Loading branch information
shrishrirang authored and davidebbo committed Mar 14, 2018
1 parent 5c700d8 commit 2b038fe
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 9 deletions.
7 changes: 6 additions & 1 deletion Kudu.Client/Deployment/RemotePushDeploymentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public RemotePushDeploymentManager(string serviceUrl, ICredentials credentials =
{
}

public async Task<HttpResponseMessage> PushDeployFromStream(Stream zipFile, ZipDeployMetadata metadata)
public async Task<HttpResponseMessage> PushDeployFromStream(Stream zipFile, ZipDeployMetadata metadata, IList<KeyValuePair<string, string>> queryParams = null)
{
using (var request = new HttpRequestMessage())
{
Expand All @@ -35,6 +35,11 @@ public async Task<HttpResponseMessage> PushDeployFromStream(Stream zipFile, ZipD
new KeyValuePair<string, string>("message", metadata.Message),
};

if (queryParams != null)
{
map.AddRange(queryParams);
}

foreach (var item in map)
{
if (item.Value != null)
Expand Down
2 changes: 2 additions & 0 deletions Kudu.Contracts/Deployment/DeploymentInfoBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ protected DeploymentInfoBase()
// for instance, http://github.com/kuduapps/hellokudu.git#<commitid>
public string CommitId { get; set; }

public bool CleanupTargetDirectory { get; set; }

// Can set to false for deployments where we assume that the repository contains the entire
// built site, meaning we can skip app stack detection and simply use BasicBuilder
// (KuduSync only)
Expand Down
2 changes: 2 additions & 0 deletions Kudu.Core/Deployment/DeploymentContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class DeploymentContext
/// </summary>
public string NextManifestFilePath { get; set; }

public bool IgnoreManifest { get; set; }

/// <summary>
/// Writes diagnostic output to the trace.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions Kudu.Core/Deployment/DeploymentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ private async Task Build(
{
NextManifestFilePath = GetDeploymentManifestPath(id),
PreviousManifestFilePath = GetActiveDeploymentManifestPath(),
IgnoreManifest = deploymentInfo.CleanupTargetDirectory, // Ignoring the manifest will cause kudusync to delete sub-directories / files
// in the destination directory that are not present in the source directory,
// without checking the manifest to see if the file was copied over to the destination
// during a previous kudusync operation. This effectively performs a clean deployment
// from the source to the destination directory.
Tracer = tracer,
Logger = logger,
GlobalLogger = _globalLogger,
Expand Down
2 changes: 1 addition & 1 deletion Kudu.Core/Deployment/Generator/CustomBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override Task Build(DeploymentContext context)

try
{
RunCommand(context, _command);
RunCommand(context, _command, ignoreManifest: false);

tcs.SetResult(null);
}
Expand Down
5 changes: 3 additions & 2 deletions Kudu.Core/Deployment/Generator/ExternalCommandBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public void PostBuild(DeploymentContext context)
{
scriptFilePath = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", file);
}
RunCommand(context, scriptFilePath, Path.GetFileNameWithoutExtension(file));
RunCommand(context, scriptFilePath, false, Path.GetFileNameWithoutExtension(file));
}
}

protected void RunCommand(DeploymentContext context, string command, string message = "Running deployment command...")
protected void RunCommand(DeploymentContext context, string command, bool ignoreManifest, string message = "Running deployment command...")
{
ILogger customLogger = context.Logger.Log(message);
customLogger.Log("Command: " + command);
Expand All @@ -84,6 +84,7 @@ protected void RunCommand(DeploymentContext context, string command, string mess

exe.EnvironmentVariables[WellKnownEnvironmentVariables.PreviousManifestPath] = context.PreviousManifestFilePath ?? String.Empty;
exe.EnvironmentVariables[WellKnownEnvironmentVariables.NextManifestPath] = context.NextManifestFilePath;
exe.EnvironmentVariables[WellKnownEnvironmentVariables.IgnoreManifest] = ignoreManifest ? "1" : "0";

exe.EnvironmentVariables[WellKnownEnvironmentVariables.BuildTempPath] = context.BuildTempPath;

Expand Down
2 changes: 1 addition & 1 deletion Kudu.Core/Deployment/Generator/GeneratorSiteBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public override Task Build(DeploymentContext context)
{
GenerateScript(context, buildLogger);
string deploymentScriptPath = String.Format("\"{0}\"", DeploymentManager.GetCachedDeploymentScriptPath(Environment));
RunCommand(context, deploymentScriptPath);
RunCommand(context, deploymentScriptPath, context.IgnoreManifest);
tcs.SetResult(null);
}
catch (Exception ex)
Expand Down
1 change: 1 addition & 0 deletions Kudu.Core/Deployment/WellKnownEnvironmentVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal static class WellKnownEnvironmentVariables
public const string BuildTempPath = "DEPLOYMENT_TEMP";
public const string PreviousManifestPath = "PREVIOUS_MANIFEST_PATH";
public const string NextManifestPath = "NEXT_MANIFEST_PATH";
public const string IgnoreManifest = "IGNORE_MANIFEST";
public const string InPlaceDeployment = "IN_PLACE_DEPLOYMENT";
public const string ApplicationPoolId = "APP_POOL_ID";

Expand Down
47 changes: 44 additions & 3 deletions Kudu.FunctionalTests/ZipDeploymentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public Task TestWarDeploymentUpdatesWebXmlTimestamp()
{
return ApplicationManager.RunAsync("TestWarDeploymentUpdatesWebXmlTimestamp", async appManager =>
{
var files = new[] { new FileForZip {Filename = "WEB-INF/web.xml"} };
var files = new[] { new FileForZip { Filename = "WEB-INF/web.xml" } };

// STEP 1: Deploy WAR and get web.xml timestamp

Expand Down Expand Up @@ -345,6 +345,39 @@ public Task TestWarDeploymentUpdatesWebXmlTimestamp()
});
}

[Fact]
public Task TestSimpleWarDeploymentPerformsCleanDeployment()
{
return ApplicationManager.RunAsync("TestSimpleWarDeploymentPerformsCleanDeployment", async appManager =>
{
// STEP 1: create a file before doing a wardeploy. We expect wardeploy to remove this file
var fileName = "file-before-wardeployment-" + Guid.NewGuid().ToString("N");
appManager.VfsWebRootManager.WriteAllText("webapps/ROOT/" + fileName, "some content");
var deployedFiles = appManager.VfsWebRootManager.ListAsync("webapps/ROOT/").Result.ToList();
Assert.Equal(1, deployedFiles.Count);
Assert.Equal(fileName, deployedFiles[0].Name);

// STEP 2: Perform wardeploy and check files deployed by wardeploy are the only ones that exist now
// (in other words, check that the file created in step 1 is removed by wardeploy)
var files = CreateRandomFilesForZip(10);
var response = await DeployWar(appManager, files, new ZipDeployMetadata());
response.EnsureSuccessStatusCode();
await AssertSuccessfulDeploymentByFilenames(appManager, files.Select(f => f.Filename).ToArray(), "webapps/ROOT");
});
}

[Fact]
public Task TestSimpleWarDeploymentWithCustomAppName()
{
return ApplicationManager.RunAsync("TestSimpleWarDeploymentPerformsCleanDeployment", async appManager =>
{
var files = CreateRandomFilesForZip(10);
var response = await DeployWar(appManager, files, new ZipDeployMetadata(), "testappname");
response.EnsureSuccessStatusCode();
await AssertSuccessfulDeploymentByFilenames(appManager, files.Select(f => f.Filename).ToArray(), "webapps/testappname");
});
}

private static async Task AssertSuccessfulDeploymentByContent(ApplicationManager appManager, FileForZip[] files)
{
TestTracer.Trace("Verifying files are deployed and deployment record created.");
Expand Down Expand Up @@ -399,14 +432,22 @@ private static async Task<HttpResponseMessage> DeployZip(
private static async Task<HttpResponseMessage> DeployWar(
ApplicationManager appManager,
FileForZip[] files,
ZipDeployMetadata metadata)
ZipDeployMetadata metadata,
string appName = null)
{
TestTracer.Trace("Push-deploying war");
using (var zipStream = CreateZipStream(files))
{
IList<KeyValuePair<string, string>> queryParams = null;
if (!string.IsNullOrWhiteSpace(appName))
{
queryParams = new List<KeyValuePair<string, string>>(){ new KeyValuePair<string, string>( "name", appName ) };
}

return await appManager.WarDeploymentManager.PushDeployFromStream(
zipStream,
metadata);
metadata,
queryParams);
}
}

Expand Down
10 changes: 9 additions & 1 deletion Kudu.Services/Deployment/PushDeploymentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,23 @@ public async Task<HttpResponseMessage> WarPushDeploy(
{
using (_tracer.Step("WarPushDeploy"))
{
var appName = Request.RequestUri.ParseQueryString()["name"];

if (string.IsNullOrWhiteSpace(appName))
{
appName = "ROOT";
}

var deploymentInfo = new ZipDeploymentInfo(_environment, _traceFactory)
{
AllowDeploymentWhileScmDisabled = true,
Deployer = deployer,
TargetPath = Path.Combine("webapps", "ROOT"),
TargetPath = Path.Combine("webapps", appName),
WatchedFilePath = Path.Combine("WEB-INF", "web.xml"),
IsContinuous = false,
AllowDeferredDeployment = false,
IsReusable = false,
CleanupTargetDirectory = true, // For now, always cleanup the target directory. If needed, make it configurable
TargetChangeset = DeploymentManager.CreateTemporaryChangeSet(message: "Deploying from pushed war file"),
CommitId = null,
RepositoryType = RepositoryType.None,
Expand Down

0 comments on commit 2b038fe

Please sign in to comment.