Ability to set agent name upon registration

Originally from https://youtrack.jetbrains.com/issue/TW-49809:

This feature would be especially useful for dynamically created cloud agents in order to provide meaningful names to the end users. In my particular case, I would like the agent name to contains a reference to the hosting Docker container.

It is currently possible to set an agent's name at registration time, by using the BuildAgentInit.setName() method. This class is however part of the server JAR and not the public API.

Having some way to deal with duplicated agent name would also be helpful. When using the BuildAgentInit.setName() method, it is the responsibility of the caller to provide an unique agent name, which can be tricky to achieve.

9 comments
Comment actions Permalink

if you are implementing a cloud provider for TC, there's a way to set an agent name upon registration.
In particular implementation of CloudClient#generateAgentName does that.

Alternatively, you can autowire a spring bean that implements jetbrains.buildServer.serverSide.impl.AgentNameGenerator.  The javadoc here explains everything. 

0
Comment actions Permalink

Thanks for the hint.

I almost forgot about the generateAgentName method.

The problem is: it's never invoked. I assume this has something to do with the following message in logs: server.impl.CloudManagerFacade - generateName requires for agent without PROFILE_ID

I must dig a little further...

0
Comment actions Permalink

Actually, logging is bad in this point. To have generateAgentName called, agent must report its profile id in system.cloud.profile_id parameter.

0
Comment actions Permalink

Indeed, what I must probably do, is transferring all the custom agent configuration parameters stored in the CloudInstanceUserData to the agent parameters.

I guess that the best way to do so is probably with the help of an agent plugin (similarly to what is being done in the wmware and azure plugins).

Dealing with instance in a stopped state will be tricky however. The cloud plugin is publishing information to the agent using environment variables configured directly on the Docker container. Once a container is created, there is no way to reconfigure those environment variable. The agent parameters related to a stopped can therefore not be updated. I'll see if I can work around this...

Thank you again for the swift help :-)

0
Comment actions Permalink

This was not as easy as I tough, setting the missing parameter using an agent plugin did not work in my case.

The generateAgentName seems to be called very early in the agent registration sequence, namely, before the agent gets upgraded. This means that if the agent plugin is not available during the initial connection on the agent side (before upgrading), the 'system.cloud.profile_id' parameter will never be set at the time the agent name is generated.

In the end, I was able to work around this issue using a custom agent name generator, but I'm concerned that other functionalities may break, now or in the future, if the 'system.cloud.profile_id' (or any other parameter available in the CloudInstanceUserData instance) are not immediately available on the created agent instance.

Do you have any hint on how to properly propagate the CloudInstanceUserData parameters to the created agent? If this can't be done reliably with an agent plugin, or a build listener (the agentRegistered callback is also invoked too late), the only possibility I see is setting the required parameters in the buildAgent.properties file that would be generated or modified on the fly, but accessing the filesystem of the agent host to is cumbersome as well.

0
Comment actions Permalink

The fact that CloudInstanceUserData is not available is not a big problem. 

For instance, agent comes initially w/out plugins and gets a default name like ip_10.0.1.2. After upgrade it will be able to retrieve the data. At this point you need to set name to jetbrains.buildServer.clouds.CloudInstanceUserData#getAgentName to trigger name generator work once again and the new name should replace the old one. Actually jetbrains.buildServer.clouds.CloudInstanceUserData#getAgentName returns empty string now, but for further compatibility it's better to use this value, not just the empty string.

0
Comment actions Permalink
At this point you need to set name to jetbrains.buildServer.clouds.CloudInstanceUserData#getAgentName to trigger name generator work once again and the new name should replace the old one.

Where and how can I set name? Should I do it in agent or server? And there is no public method to set name other than generateAgentName() so should I call BuildAgentInit.setName() instead? How can I get BuildAgentInit? jetbrains.buildServer.clouds.CloudInstanceUserData#getAgentName seems to simply return a member variable so I suppose it won't trigger anything.

Thanks

0
Comment actions Permalink

If agent comes to server with an empty name, server calls jetbrains.buildServer.clouds.CloudClient#generateAgentName to generate a new name and sends the new name back to the agent. But in order to be able to do that agent must provide system.cloud.profile_id parameter. Server will find CloudClient that corresponds to that profile_id and will call the generateAgentName method for it.

0
Comment actions Permalink

I put system.cloud.profile_id in buildAgent.properties. Now in /agents.html?tab=unauthorizedAgents there is an item with default name like ip_10.0.1.2 left. Is it supposed to be there? Is there any setting that can help me remove it?

0

Please sign in to leave a comment.