New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
out of proc agent system plugins #1537
Conversation
f2fccd8
to
6103ca7
Compare
src/Agent.Worker/JobRunner.cs
Outdated
@@ -41,6 +41,87 @@ public sealed class JobRunner : AgentService, IJobRunner | |||
|
|||
DateTime jobStartTimeUtc = DateTime.UtcNow; | |||
|
|||
var tfsGit1 = new Pipelines.RepositoryResource() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is for me to test my change, since the server haven't sent down repository as part of job message.
src/dir.proj
Outdated
<RemoveDir Directories="Agent.PluginCore/obj" /> | ||
<RemoveDir Directories="Agent.RepositoryPlugin/bin" /> | ||
<RemoveDir Directories="Agent.RepositoryPlugin/obj" /> | ||
<RemoveDir Directories="Agent.DropPlugin/bin" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be a worthy reduction in overhead to just have two DLLs? PluginHost and Plugins? and let authors namespace their code.
We will quickly hit an issue where folks want shared DLLs for shared logic. That problem goes away if all plugsin are in one DLL. And note, everything is in one DLL today in the worker project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agent.pluginhost.exe
agent.pluginsdk.dll
agent.plugins.dll <- microsoft.vs.service.agent.plugins.repo/drop/etc...
|
||
public void Output(string message) | ||
{ | ||
Console.WriteLine(message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is a lock needed here? will lines get mixed from separate threads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base on doc, console.write is thread safe.
Console.WriteLine(message); | ||
} | ||
|
||
public void Fail(string message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
STDERR from while process ##command means the command process failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
} | ||
} | ||
|
||
private AgentCertificateSettings GetCertConfiguration() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this consistent with how the libs read the settings? or how the agent reads the settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is how the libs read proxy/cert settings.
} | ||
} | ||
|
||
private AgentWebProxySettings GetProxyConfiguration() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is consistent with how the libs read the settings, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, same as node/powershell lib, read setting from variables set by the agent..
src/Agent.PluginCore/PluginUtil.cs
Outdated
return string.IsNullOrEmpty(ProxyAddress) || uri.IsLoopback || IsMatchInBypassList(uri); | ||
} | ||
|
||
private bool IsMatchInBypassList(Uri input) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this bypass stuff intentionally duplicated in commandPlugin.cs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the one in commandplugin.cs is part of the IWebProxy implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put the calculation part into pluginutil.cs
src/Agent.PluginCore/PluginUtil.cs
Outdated
DeleteDirectory(path, contentsOnly: false, continueOnContentDeleteError: false, cancellationToken: cancellationToken); | ||
} | ||
|
||
public static void DeleteDirectory(string path, bool contentsOnly, bool continueOnContentDeleteError, CancellationToken cancellationToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider moving this to shared DLL so we don't have to maintain a fork of the code. perhaps something to clean up in a following pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we need to figure out a good name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agent.listener.exe
agent.worker.exe
microsoft.vs.service.agent.dll
agent.pluginhost.exe
agent,plugins.dll
agent.sdk.dll
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
src/Agent.PluginCore/PluginUtil.cs
Outdated
return path + Path.PathSeparator + currentPath; | ||
} | ||
|
||
public static void PrependPath(string directory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt the git source provider do this? is it an instruction for the agent to prepend path now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(for the benefit of downstream tasks)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess PluginSteps can write commands, commands cannot write commands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, you are right! i will change it to write ##vso[task.prepandpath]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
src/Agent.PluginCore/PluginUtil.cs
Outdated
} | ||
} | ||
|
||
private async Task CancelAndKillProcessTree() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm curious how cancellation works when initiated from the agent. let's discuss offline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decrease cancel timeout 5 secs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
src/Agent.PluginCore/TaskPlugin.cs
Outdated
Console.WriteLine($"##vso[task.debug]{message}"); | ||
} | ||
|
||
public void Error(string message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we ever use this? i would just remove this overload and rename fail to error. we can always add an overload later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error will output ##vso[task.setresult result=failed;] by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
src/Agent.PluginCore/TaskPlugin.cs
Outdated
public Dictionary<string, VariableValue> TaskVariables { get; set; } | ||
public Dictionary<string, string> Inputs { get; set; } | ||
|
||
public string GetInput(string name, bool required = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need a vault concept. we can port from powershell, but i'm not sure if it will work on linux.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i forgot that. it should work, we can just use AES.
string assemblyQualifiedName = args[1]; | ||
PluginUtil.NotNullOrEmpty(assemblyQualifiedName, nameof(assemblyQualifiedName)); | ||
|
||
string serializedContext = Console.ReadLine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a limitation to line size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clever
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i tried a input with 16K chars, doesn't seems to have limitation
AgentTaskPluginExecutionContext executionContext = PluginUtil.ConvertFromJson<AgentTaskPluginExecutionContext>(serializedContext); | ||
PluginUtil.NotNull(executionContext, nameof(executionContext)); | ||
|
||
AssemblyLoadContext.Default.Resolving += ResolveAssembly; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we going to have assembly resolver problems like the functions in the ps lib solve?
|
||
namespace Agent.RepositoryPlugin | ||
{ | ||
public class GitCommandManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the "Command" terminology is misleading
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitCLIManager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitCliManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
|
||
// Prepend the PATH. | ||
context.Output(PluginUtil.Loc("Prepending0WithDirectoryContaining1", "Path", Path.GetFileName(gitPath))); | ||
PluginUtil.PrependPath(Path.GetDirectoryName(gitPath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldnt this echo a ##command
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
throw new NotSupportedException(repo.Type); | ||
} | ||
|
||
if (executionContext.Stage == "main") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is another place a shared dll would help, so these loose strings could be moved into a shared const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agent.sdk.dll
} | ||
} | ||
|
||
private void MergeInputs(AgentTaskPluginExecutionContext executionContext, Pipelines.RepositoryResource repository) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets discuss offline. i'm confused why this is here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will deal with this later when we send repository as part of the message.
@@ -439,6 +446,15 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation | |||
} | |||
} | |||
|
|||
// Runtime option variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this for? why is this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the git source provide needs to know whether to use SChanel or OpenSSl as secure backend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
k, lets chat offline. i'm still confused why the variable is set here
} | ||
}; | ||
|
||
public Dictionary<string, Dictionary<string, AgentCommandPluginInfo>> SupportedLoggingCommands => _supportedLoggingCommands; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than expose these dictionaries, a nicer interface might be something like GetCommand() and return null if not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetTask(guid, version)
GetCommnad(String, string)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
|
||
// Resolve the working directory. | ||
string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Bin); | ||
ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not system.defaultWorkingDirectory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better be workfolder. :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
_supportedTasks[taskPlugin.Id][taskPlugin.Version].Data = new DefinitionData() | ||
{ | ||
Author = taskPlugin.Author, | ||
Description = taskPlugin.Description, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about instance name format? who calculates the instance name format? is it the agent or the server? is it based on the instance name format defined in the task instance or in the task definition? have you thought through how this will work for plugin steps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i assume server will do it since that how other task been handled as well.
Inputs = inputs, | ||
Stage = stage, | ||
Repositories = context.Repositories, | ||
Endpoints = context.Endpoints |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the host portion of the urls in the endpoints fixed up already? what about repositories, will they need to be fixed up too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
everything in executioncontext should already be fixed up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in jobrunner, fix url for repository as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
I will remove duplicated code between agent.sdk.dll and microsoft.vs.service.agent.dll in next PR |
60aa0f9
to
e1c3d10
Compare
c8be8ea
to
b3bc6bb
Compare
b3bc6bb
to
dedfd9b
Compare
No description provided.