Skip to content

Conversation

KinoriSR
Copy link

@KinoriSR KinoriSR commented Sep 4, 2025

What does this PR do?

Adds azmcp azuremanagedlustre filesystem import-job create and required testing and docs. [#318]

GitHub issue number?

Issue #318

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide)
    • Added comprehensive tests for new/modified functionality
    • Updated CHANGELOG.md for product changes (features, bug fixes, UI/UX, updated dependencies)
  • For MCP tool changes:
    • One tool per PR: This PR adds or modifies only one MCP tool for faster review cycles
    • Updated README.md documentation
    • Updated command list in /docs/azmcp-commands.md
    • Updated test prompts in /docs/e2eTestPrompts.md
    • For new or modified tool descriptions, ran ToolDescriptionEvaluator and obtained a score of 0.4 or more and a top 3 ranking for all related test prompts
  • 👉 For Community (non-Azure team member) PRs:
    • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
    • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline

@Copilot Copilot AI review requested due to automatic review settings September 4, 2025 19:21
@KinoriSR KinoriSR requested review from wolfgang-desalvador and a team as code owners September 4, 2025 19:21
@github-project-automation github-project-automation bot moved this to Untriaged in Azure MCP Server Sep 4, 2025
@KinoriSR
Copy link
Author

KinoriSR commented Sep 4, 2025

Some questions:

  • I had to tweak/fix some other files such as the test resources deployment script. That is not in the scope for this additional command. For the future, should fixes like that be in a separate PR or part of a PR like this?
  • After running the tool description script, there were some changes made to other files like the eng\tools\ToolDescriptionEvaluator\prompts.json and eng\tools\ToolDescriptionEvaluator\results.txt. Should those changes be included? Many of the changes were in sections that are not Azure Managed Lustre related. Should I only include changes that are Azure Managed Lustre related?

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@KinoriSR
Copy link
Author

KinoriSR commented Sep 4, 2025

Failed live tests are related to the test resources bicep file not creating HSM enabled AMLFS quite yet. This PR for AMLFS create should solve this issue.

@wolfgang-desalvador

azmcp azuremanagedlustre filesystem import-job create --subscription <subscription> \
--resource-group <resource-group> \
--file-system <filesystem-name> \
--import-prefixes <prefix1> <prefix2> ... <prefixN> \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--import-prefixes <prefix1> <prefix2> ... <prefixN> \
[--import-prefixes <prefix1> <prefix2> ... <prefixN>] \

Given that this isn't required in the tool call.

using Azure.Mcp.Tools.AzureManagedLustre.Services;
using Microsoft.Extensions.Logging;

namespace Azure.Mcp.Tools.AzureManagedLustre.Commands.FileSystem;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there be many job-based tools? Might be worth putting this into a sub-namespace of FileSystem given create is too generic of a Name.


public override string Title => CommandTitle;

public override ToolMetadata Metadata => new() { Destructive = false, ReadOnly = false };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be considered a Destructive tool given OverwriteAlways can mutate existing resources

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. Updating...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't updated yet. Currently figuring out if we want to remove the Overwrite options to prevent destruction.

Comment on lines 77 to 78
options.ConflictResolutionMode ?? "OverwriteAlways",
options.MaximumErrors ?? -1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on BindOptions are the null-coalescing cases even possible?

Comment on lines 62 to 68
var options = BindOptions(parseResult);
try
{
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
{
return context.Response;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an upcoming broad update where Validate should be called before BindOptions, mind updating that here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also make sure you rebase with main

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rebased


# Returns the required number of IP addresses for a specific Azure Managed Lustre SKU and filesystem size
azmcp azuremanagedlustre filesystem required-subnet-size --subscription <subscription> \
--sku <azure-managed-lustre-sku> \
--size <filesystem-size-in-tib>

# Create an Azure Managed Lustre filesystem import job (preview / placeholder)
azmcp azuremanagedlustre filesystem import-job create --subscription <subscription> \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't include azure in the name

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a planned refactor which will be addressed after the current PRed actions are in. Here is the open conversion issue: #345 .

Is this a sufficient solution for now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take that as a PR this week, thanks.

[--conflict-resolution-mode <conflict-mode>] \
[--maximum-errors <maximum-errors>] \
[--admin-status <admin-status>] \
[--job-name <job-name>]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only include -name in option name if required to diff from another name

@@ -22,13 +22,16 @@ public void ConfigureServices(IServiceCollection services)
public void RegisterCommands(CommandGroup rootGroup, ILoggerFactory loggerFactory)
{
var azureManagedLustre = new CommandGroup(Name,
"Azure Managed Lustre operations - Commands for listing and inspecting Azure Managed Lustre file systems (AMLFS) used for high-performance computing workloads.");
"Azure Managed Lustre operations - Commands for non-destructive interaction with Azure Managed Lustre file systems (AMLFS) used for high-performance computing workloads.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify this, too many repeated words

rootGroup.AddSubGroup(azureManagedLustre);

var fileSystem = new CommandGroup("filesystem", "Azure Managed Lustre file system operations - Commands for listing managed Lustre file systems.");
azureManagedLustre.AddSubGroup(fileSystem);

fileSystem.AddCommand("list", new FileSystemListCommand(loggerFactory.CreateLogger<FileSystemListCommand>()));
fileSystem.AddCommand("required-subnet-size", new FileSystemSubnetSizeCommand(loggerFactory.CreateLogger<FileSystemSubnetSizeCommand>()));
var importJob = new CommandGroup("import-job", "AMLFS import job operations - Create manual import jobs to hydrate the file system namespace.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is AMLFS IDK if copilot will know that acronym.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AMLFS is Azure Managed Lustre File System. I can expand to words in the next push.

@github-project-automation github-project-automation bot moved this from Untriaged to In Progress in Azure MCP Server Sep 4, 2025
Assert.Equal("/", result.ImportJob.ImportPrefixes![0]);
}

// TODO: may need a delay between tests to prevent conflicts with successful jobs
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing in next push.

IList<string>? importPrefixes = null,
string conflictResolutionMode = "OverwriteAlways",
int? maximumErrors = 0,
string? adminStatus = "Active", // TODO: discuss the necessity of this
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wolfgang-desalvador thoughts on the necessity of this param? It must always be "Active" when creating an import job. Only "Cancel" when canceling the job.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create and update will be separate commands so remove adminStatus can be hardcoded as "Active".


# Returns the required number of IP addresses for a specific Azure Managed Lustre SKU and filesystem size
azmcp azuremanagedlustre filesystem required-subnet-size --subscription <subscription> \
--sku <azure-managed-lustre-sku> \
--size <filesystem-size-in-tib>

# Create an Azure Managed Lustre filesystem import job (preview / placeholder)
azmcp azuremanagedlustre filesystem import-job create --subscription <subscription> \
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a planned refactor which will be addressed after the current PRed actions are in. Here is the open conversion issue: #345 .

Is this a sufficient solution for now?

rootGroup.AddSubGroup(azureManagedLustre);

var fileSystem = new CommandGroup("filesystem", "Azure Managed Lustre file system operations - Commands for listing managed Lustre file systems.");
azureManagedLustre.AddSubGroup(fileSystem);

fileSystem.AddCommand("list", new FileSystemListCommand(loggerFactory.CreateLogger<FileSystemListCommand>()));
fileSystem.AddCommand("required-subnet-size", new FileSystemSubnetSizeCommand(loggerFactory.CreateLogger<FileSystemSubnetSizeCommand>()));
var importJob = new CommandGroup("import-job", "AMLFS import job operations - Create manual import jobs to hydrate the file system namespace.");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AMLFS is Azure Managed Lustre File System. I can expand to words in the next push.


public override string Title => CommandTitle;

public override ToolMetadata Metadata => new() { Destructive = false, ReadOnly = false };
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. Updating...

Comment on lines 62 to 68
var options = BindOptions(parseResult);
try
{
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
{
return context.Response;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also make sure you rebase with main


public static readonly Option<string> FileSystemOption = new(
$"--{fileSystem}",
"The name of the Azure Managed Lustre file system (AMLFS)."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these need to be updated to Required and explicit Description property set

string? tenant = null,
RetryPolicyOptions? retryPolicy = null)
{
ArgumentException.ThrowIfNullOrWhiteSpace(subscription);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ValidateRequiredParameters method

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

var rg = await _resourceGroupService.GetResourceGroupResource(subscription, resourceGroup, tenant, retryPolicy)
?? throw new Exception($"Resource group '{resourceGroup}' not found");

var fs = await rg.GetAmlFileSystemAsync(fileSystemName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IF this takes a handle, then make sure it is disposed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return object does not seem to be disposable.


public override string Title => CommandTitle;

public override ToolMetadata Metadata => new() { Destructive = false, ReadOnly = false };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide values for all hints.

@joshfree joshfree added this to the 2025-09 milestone Sep 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

5 participants