mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-04-01 01:20:31 -04:00
Azure SQL Hybrid Cloud Toolkit Notebooks Extension Command (#13286)
* added extension folder incomplete * WIP extension progress * notebook finally opens in side panel * notebook now opens via notebook extension * html file spaces restored * package json fixed * fixed vscode import issue * more cleanup * remove git stuff * placeholder icon logos added * fixed gulpfile * cleanup changes * vscode import fixed * fixed main and yarn.lock * added provided notebooks view * formatting for package.json * removed first command as its not necessary * fixed notebook typo * readded spaces
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (console)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/SqlPackageWrapper.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/SqlPackageWrapper.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/SqlPackageWrapper.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"${workspaceFolder}/SqlPackageWrapper.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace SqlPackageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of sqlpackage action to perform.
|
||||
/// </summary>
|
||||
public enum ActionType
|
||||
{
|
||||
DefaultInvalid = -1,
|
||||
Export,
|
||||
Import
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace SqlPackageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for the batch wrapper.
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Environment variable names present or needed during the batch task execution.
|
||||
/// </summary>
|
||||
public static class EnvironmentVariableNames
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the directory containing the batch wrapper exe.
|
||||
/// </summary>
|
||||
public const string WrapperLocation = "AZ_BATCH_APP_PACKAGE_BATCHWRAPPER";
|
||||
|
||||
/// <summary>
|
||||
/// Path to the directory containing the sqlpackage exe.
|
||||
/// </summary>
|
||||
internal const string SqlPackageLocation = "AZ_BATCH_APP_PACKAGE_SQLPACKAGE";
|
||||
|
||||
/// <summary>
|
||||
/// Path to the working directory assigned to the batch task.
|
||||
/// </summary>
|
||||
internal const string TaskWorkingDir = "AZ_BATCH_TASK_WORKING_DIR";
|
||||
|
||||
/// <summary>
|
||||
/// Path to the working directory assigned to the batch task.
|
||||
/// </summary>
|
||||
internal const string AzBatchTaskId = "AZ_BATCH_TASK_ID";
|
||||
|
||||
/// <summary>
|
||||
/// Path to the working directory assigned to the batch task.
|
||||
/// </summary>
|
||||
internal const string JobContainerUrl = "JOB_CONTAINER_URL";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace SqlPackageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// The top-level object stored in the key vault for an import/export operation.
|
||||
/// </summary>
|
||||
public sealed class Payload
|
||||
{
|
||||
/// <summary>
|
||||
/// The version of sqlpackage to use for performing the import/export operation.
|
||||
/// </summary>
|
||||
public string SqlPackageVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of sqlpackage action to perform.
|
||||
/// </summary>
|
||||
public ActionType Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The logical server name to export from or import to.
|
||||
/// </summary>
|
||||
public string LogicalServerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The database name to export from or import to.
|
||||
/// </summary>
|
||||
public string DatabaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The server admin username.
|
||||
/// </summary>
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The server admin password.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using Microsoft.Azure.Batch.Conventions.Files;
|
||||
using Microsoft.WindowsAzure.Storage.Blob;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SqlPackageWrapper
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
private static string dataDirectory = "F:\\data";
|
||||
private static string tempDirectory = "F:\\temp";
|
||||
private static string[] directories = { dataDirectory, tempDirectory };
|
||||
|
||||
private static readonly TimeSpan stdoutFlushDelay = TimeSpan.FromSeconds(3);
|
||||
|
||||
private static void WriteLine(string message) => WriteLineInternal(Console.Out, message);
|
||||
private static void WriteErrorLine(string message) => WriteLineInternal(Console.Error, message);
|
||||
private static void WriteLineInternal(TextWriter writer, string message)
|
||||
{
|
||||
var lines = message?.Split('\n') ?? new string[0];
|
||||
foreach (var line in lines)
|
||||
{
|
||||
writer.WriteLine($"[{DateTime.UtcNow:u}] {line?.TrimEnd()}");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<int> Main(string[] args)
|
||||
{
|
||||
var assembly = typeof(Program).Assembly;
|
||||
WriteLine($"{assembly.ManifestModule.Name} v{assembly.GetName().Version.ToString(3)}");
|
||||
|
||||
// Get the command payload
|
||||
var payload = new Payload();
|
||||
|
||||
if (args.Length > 0)
|
||||
{
|
||||
payload.Action = (ActionType)Enum.Parse(typeof(ActionType), args[0]);
|
||||
payload.LogicalServerName = args[1] + ".database.windows.net";
|
||||
payload.DatabaseName = args[2];
|
||||
payload.Username = args[3];
|
||||
payload.Password = args[4];
|
||||
payload.SqlPackageVersion = args[5];
|
||||
}
|
||||
|
||||
// Cleanup folders
|
||||
foreach (string dir in directories)
|
||||
{
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
string sqlPackageDataPath = Path.Combine(dataDirectory, payload.DatabaseName + ".bacpac");
|
||||
string sqlPackageLogPath = Path.Combine(dataDirectory, payload.DatabaseName + ".log");
|
||||
|
||||
var targetDir = Environment.GetEnvironmentVariable($"{Constants.EnvironmentVariableNames.SqlPackageLocation}#{payload.SqlPackageVersion}");
|
||||
var workingDir = Environment.GetEnvironmentVariable(Constants.EnvironmentVariableNames.TaskWorkingDir);
|
||||
|
||||
string taskId = Environment.GetEnvironmentVariable(Constants.EnvironmentVariableNames.AzBatchTaskId);
|
||||
string jobContainerUrl = Environment.GetEnvironmentVariable(Constants.EnvironmentVariableNames.JobContainerUrl);
|
||||
|
||||
// Build the import/export command
|
||||
var cmdBuilder = new StringBuilder();
|
||||
cmdBuilder.Append($"/Action:{payload.Action}");
|
||||
cmdBuilder.Append(" /MaxParallelism:16");
|
||||
cmdBuilder.Append(String.Format(" /DiagnosticsFile:{0}", sqlPackageLogPath));
|
||||
cmdBuilder.Append(" /p:CommandTimeout=86400");
|
||||
|
||||
switch (payload.Action)
|
||||
{
|
||||
case ActionType.Export:
|
||||
cmdBuilder.Append($" /SourceServerName:{payload.LogicalServerName}");
|
||||
cmdBuilder.Append($" /SourceDatabaseName:{payload.DatabaseName}");
|
||||
cmdBuilder.Append($" /SourceUser:{payload.Username}");
|
||||
cmdBuilder.Append($" /SourcePassword:{payload.Password}");
|
||||
cmdBuilder.Append($" /TargetFile:{sqlPackageDataPath}");
|
||||
cmdBuilder.Append(String.Format(" /p:TempDirectoryForTableData=\"{0}\"", tempDirectory));
|
||||
cmdBuilder.Append(" /p:VerifyFullTextDocumentTypesSupported=false");
|
||||
break;
|
||||
|
||||
case ActionType.Import:
|
||||
cmdBuilder.Append($" /TargetServerName:{payload.LogicalServerName}");
|
||||
cmdBuilder.Append($" /TargetDatabaseName:{payload.DatabaseName}");
|
||||
cmdBuilder.Append($" /TargetUser:{payload.Username}");
|
||||
cmdBuilder.Append($" /TargetPassword:{payload.Password}");
|
||||
cmdBuilder.Append($" /SourceFile:{sqlPackageDataPath}");
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Invalid action type: {payload.Action}");
|
||||
}
|
||||
|
||||
if (payload.Action == ActionType.Import)
|
||||
{
|
||||
WriteLine(string.Format("Downloading {0} bacpac file to {1}", payload.DatabaseName, sqlPackageDataPath));
|
||||
CloudBlobContainer container = new CloudBlobContainer(new Uri(jobContainerUrl));
|
||||
CloudBlockBlob blob = container.GetBlockBlobReference(String.Format("$JobOutput/{0}.bacpac", payload.DatabaseName));
|
||||
await blob.DownloadToFileAsync(sqlPackageDataPath, FileMode.CreateNew);
|
||||
WriteLine(string.Format("Downloaded {0} bacpac file to {1}", payload.DatabaseName, sqlPackageDataPath));
|
||||
|
||||
await Task.Delay(stdoutFlushDelay);
|
||||
}
|
||||
|
||||
// Perform the import/export process
|
||||
var startTime = DateTimeOffset.UtcNow;
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
WorkingDirectory = workingDir,
|
||||
FileName = Path.Combine(targetDir, "sqlpackage.exe"),
|
||||
Arguments = cmdBuilder.ToString(),
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
}
|
||||
};
|
||||
process.OutputDataReceived += (s, e) => WriteLine(e.Data);
|
||||
process.ErrorDataReceived += (s, e) => WriteErrorLine(e.Data);
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit();
|
||||
|
||||
WriteLine(String.Format("SqlPackage.exe exited with code: {0}", process.ExitCode));
|
||||
|
||||
if (payload.Action == ActionType.Export)
|
||||
{
|
||||
// Persist the Job Output
|
||||
JobOutputStorage jobOutputStorage = new JobOutputStorage(new Uri(jobContainerUrl));
|
||||
|
||||
await jobOutputStorage.SaveAsync(JobOutputKind.JobOutput, sqlPackageLogPath, payload.DatabaseName + ".log");
|
||||
WriteLine(String.Format("Uploaded {0} to job account", sqlPackageLogPath));
|
||||
|
||||
await jobOutputStorage.SaveAsync(JobOutputKind.JobOutput, sqlPackageDataPath, payload.DatabaseName + ".bacpac");
|
||||
WriteLine(String.Format("Uploaded {0} to job account", sqlPackageDataPath));
|
||||
|
||||
// We are tracking the disk file to save our standard output, but the node agent may take
|
||||
// up to 3 seconds to flush the stdout stream to disk. So give the file a moment to catch up.
|
||||
await Task.Delay(stdoutFlushDelay);
|
||||
}
|
||||
|
||||
// Cleanup folders
|
||||
foreach (string dir in directories)
|
||||
{
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
}
|
||||
}
|
||||
|
||||
return process.ExitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.1;net452</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Batch" Version="13.0.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Batch.Conventions.Files" Version="3.5.1" />
|
||||
<PackageReference Include="Microsoft.Azure.Management.Batch" Version="11.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user