So, I can get the build details, but it does not contain any info on the build jobs. E.g. Each build job has run on a build agent - how can I get this piece using REST Api?
We are talking about a vNext build, not XAML.
You can find all tasks and jobs in timeline records: Timeline - Get. You can paste into browser this template to check results for a specific build:
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/timeline
I use Microsoft.TeamFoundationServer.Client package and this is example for it:
static void PrintTimeLine(string TeamProjectName, int BuildId)
{
var timeline = BuildClient.GetBuildTimelineAsync(TeamProjectName, BuildId).Result;
if (timeline.Records.Count > 0)
{
Console.WriteLine("Task Name-----------------------------Start Time---Finish Time---Result");
foreach(var record in timeline.Records)
if (record.RecordType == "Task")
Console.WriteLine("{0, -35} | {1, -10} | {2, -10} | {3}",
(record.Name.Length < 35) ? record.Name : record.Name.Substring(0, 35),
(record.StartTime.HasValue) ? record.StartTime.Value.ToLongTimeString() : "",
(record.FinishTime.HasValue) ? record.FinishTime.Value.ToLongTimeString() : "",
(record.Result.HasValue) ? record.Result.Value.ToString() : "");
}
}
https://github.com/ashamrai/TFRestApi/blob/master/19.TFRestApiAppQueueBuild/TFRestApiApp/Program.cs
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId} will let you know the Agent used under the object queue and there it shows the agent queue (91) number and the pool id (8)
"queue":{
"id":91,
"name":"MotBuild-Default",
"pool":{
"id":8,
"name":"MotBuild-Default"
}
Use
https://dev.azure.com/{org}/_apis/distributedtask/pools/{pool_id}?api-version=5.0-preview.1 or https://dev.azure.com/{org}/{project}/_apis/distributedtask/queues/{queue_id} will return the pool.
So now using https://dev.azure.com/{org}/_apis/distributedtask/pools/{pool_id}/agents will return a LIST of agents under the Agent Pools
Now that I've explained all that let's try to tie everything together.
1) Use https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId} and find the Queue and Pool IDs.
2) use https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/timeline and find the record of type Job and the property workerName which will return NAME of the Agent used.
3) Query the Agents with https://dev.azure.com/{org}/_apis/distributedtask/pools/{pool_id}/agents and find the agent id by filtering the name from the name found in step #2 above.
4) Finally query https://dev.azure.com/{org}/_apis/distributedtask/pools/{pool_id}/agents/{agent_id} will return a high-level info of the agent, not much info.
This next api is undocumented
5) To get the detailed capabilities query https://dev.azure.com/{org}/_apis/distributedtask/pools/{pool_id}/agents/{agent_id}?includeCapabilities=true which a huge result set will be returned!! I think this is what you want.
Read more about the APIs at:
Pools
Queues
Agents
Related
I am planning to write simple program using kubernetes java client (https://github.com/kubernetes-client/java/). I could get all namespaces and pods but how do i get list of deployments in a given namespace? I couldn't find any method. Is there any way to get it?
for (V1Namespace ns: namespaces.getItems()) {
System.out.println("------Begin-----");
System.out.println("Namespace: " + ns.getMetadata().getName());
V1PodList pods = api.listNamespacedPod(ns.getMetadata().getName(), null, null, null, null, null, null, null, null, null);
int count = 0;
for (V1Pod pod: pods.getItems()) {
System.out.println("Pod " + (++count) + ": " + pod.getMetadata().getName());
System.out.println("Node: " + pod.getSpec().getNodeName());
}
System.out.println("------ENd-----");
}
I guess you're looking for the following example:
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://localhost");
// Configure API key authorization: BearerToken
ApiKeyAuth BearerToken = (ApiKeyAuth) defaultClient.getAuthentication("BearerToken");
BearerToken.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//BearerToken.setApiKeyPrefix("Token");
AppsV1Api apiInstance = new AppsV1Api(defaultClient);
String namespace = "namespace_example"; // String | object name and auth scope, such as for teams and projects
String pretty = "pretty_example"; // String | If 'true', then the output is pretty printed.
Boolean allowWatchBookmarks = true; // Boolean | allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored.
String _continue = "_continue_example"; // String | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.
String fieldSelector = "fieldSelector_example"; // String | A selector to restrict the list of returned objects by their fields. Defaults to everything.
String labelSelector = "labelSelector_example"; // String | A selector to restrict the list of returned objects by their labels. Defaults to everything.
Integer limit = 56; // Integer | limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.
String resourceVersion = "resourceVersion_example"; // String | When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history. When specified for list: - if unset, then the result is returned from remote storage based on quorum-read flag; - if it's 0, then we simply return what we currently have in cache, no guarantee; - if set to non zero, then the result is at least as fresh as given rv.
Integer timeoutSeconds = 56; // Integer | Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.
Boolean watch = true; // Boolean | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.
try {
V1DeploymentList result = apiInstance.listNamespacedDeployment(namespace, pretty, allowWatchBookmarks, _continue, fieldSelector, labelSelector, limit, resourceVersion, timeoutSeconds, watch);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling AppsV1Api#listNamespacedDeployment");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
I'm supporting a production Xamarin Forms app with offline sync feature implemented using Azure Mobile Services.
We have a lot of production issues related to users losing data or general instability that goes away if the reinstall the app. After having a look through, I think the issues are around how the conflict resolution is handled in the app.
For every entity that tries to sync we handle MobileServicePushFailedException and then traverse through the errors returned and take action.
catch (MobileServicePushFailedException ex)
{
foreach (var error in ex.PushResult.Errors) // These are MobileServiceTableOpearationErrors
{
var status = error.Status; // HttpStatus code returned
// Take Action based on this status
// If its 409 or 412, we go in to conflict resolving and tries to decide whether the client or server version wins
}
}
The conflict resolving seems too custom to me and I'm checking to see whether there are general guidelines.
For example, we seem to be getting empty values for 'CreatedAt' & 'UpdatedAt' timestamps for local and server versions of the entities returned, which is weird.
var serverItem = error.Result;
var clientItem = error.Item;
// sometimes serverItem.UpdatedAt or clientItem.UpdatedAt is NULL. Since we use these 2 fields to determine who wins, we are stumped here
If anyone can point me to some guideline or sample code on how these conflicts should be generally handled using information from the MobileServiceTableOperationError, that will be highly appreciated
I came across the following code snippet from the following doc.
// Simple error/conflict handling.
if (syncErrors != null)
{
foreach (var error in syncErrors)
{
if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
{
//Update failed, reverting to server's copy.
await error.CancelAndUpdateItemAsync(error.Result);
}
else
{
// Discard local change.
await error.CancelAndDiscardItemAsync();
}
Debug.WriteLine(#"Error executing sync operation. Item: {0} ({1}). Operation discarded.",
error.TableName, error.Item["id"]);
}
}
Surfacing conflicts to the UI I found in this doc
private async Task ResolveConflict(TodoItem localItem, TodoItem serverItem)
{
//Ask user to choose the resolution between versions
MessageDialog msgDialog = new MessageDialog(
String.Format("Server Text: \"{0}\" \nLocal Text: \"{1}\"\n",
serverItem.Text, localItem.Text),
"CONFLICT DETECTED - Select a resolution:");
UICommand localBtn = new UICommand("Commit Local Text");
UICommand ServerBtn = new UICommand("Leave Server Text");
msgDialog.Commands.Add(localBtn);
msgDialog.Commands.Add(ServerBtn);
localBtn.Invoked = async (IUICommand command) =>
{
// To resolve the conflict, update the version of the item being committed. Otherwise, you will keep
// catching a MobileServicePreConditionFailedException.
localItem.Version = serverItem.Version;
// Updating recursively here just in case another change happened while the user was making a decision
UpdateToDoItem(localItem);
};
ServerBtn.Invoked = async (IUICommand command) =>
{
RefreshTodoItems();
};
await msgDialog.ShowAsync();
}
I hope this helps provide some direction. Although the Azure Mobile docs have been deprecated, the SDK hasn't changed and should still be relevant. If this doesn't help, let me know what you're using for a backend store.
I am new to Azure environment. i have written some code using .net core that starts Azure pipeline using Azure Data factory. The status of the pipeline run status when trying from my local is always success. I deployed the code in the azure environment. When try to start the pipe line from azure server always the status is queued. what is queued status and what i have to do with it. can some one please help. do i need to change any settings in azure so that the pipeline run will be success
AuthenticationContext context = new AuthenticationContext("https://login.windows.net/" + tenantID);
ClientCredential cc = new ClientCredential(applicationId, authenticationKey);
AuthenticationResult result = context.AcquireTokenAsync("https://management.azure.com/", cc).Result;
ServiceClientCredentials cred = new TokenCredentials(result.AccessToken);
var client = new Microsoft.Azure.Management.DataFactory.DataFactoryManagementClient(cred) { SubscriptionId = subscriptionId };
CreateRunResponse runResponse = client.Pipelines.CreateRunWithHttpMessagesAsync(resourceGroup, dataFactoryName, pipelineName).Result.Body;
string RunId = runResponse.RunId;
PipelineRun pipelineRun;
while (true)
{
pipelineRun = client.PipelineRuns.Get(resourceGroup, dataFactoryName, runResponse.RunId);
if (pipelineRun.Status == "InProgress")
System.Threading.Thread.Sleep(15000);
else
break;
}
You should try to look into the diagnotics logs of the IR , it does have valuable info which should help .
Navigate to IR -> diagnotics log or open event viewer -> Application and service logs ->
Is there any pythonic way to get all running/pending celery tasks for current loggedin django user? Pseudo code for what I am trying:
#celery.task
def process_task(user, task_to_do):
#get all running or pending(queued) task for current user
user_tasks = user.get_task(status=PENDING or status=STARTED)
if not user_task:
#allow user to schedule additional task
process....
else:
return "Your previous tasks is already running"
That's in general a tricky task.
First you need to implement inspecting of workers
inspector = app.control.inspect()
scheduled = inspector.scheduled()
reserved = inspector.reserved()
active = inspector.active()
Celery will get them from your broker. The point is - broker does not store information about user, so you need to add user it to task kwargs.
user_task.delay(user=user)
Than you'll be able to filter results from thees functions by kwarg user in result:
[{'worker1.example.com':
[{'eta': '2010-06-07 09:07:52', 'priority': 0,
'request': {
'name': 'tasks.usertask',
'id': '1a7980ea-8b19-413e-91d2-0b74f3844c4d',
'args': '[]',
'kwargs': '{'user':'7'}'}},
...
The problem here - it will be slow.
I have a workflow started and persisted using messaging activities.
The correlation between the Start initial command and the Stop final command works well if they're sent within few seconds.
Problems begin when the workflow is unloaded, because the following Stop message throws the following FaultException:
If LoadWorkflowByInstanceKeyCommand.AssociateLookupKeyToInstanceId is not specified, the LookupInstanceKey must already be associated to an instance, or the LoadWorkflowByInstanceKeyCommand will fail. For this reason, it is invalid to also specify the LookupInstanceKey in the InstanceKeysToAssociate collection if AssociateLookupKeyToInstanceId isn't set
Can anybody help me?
The variables inside the workflow are of types int and XDocument.
This is the code to initialize the WorkflowServiceHost:
WorkflowServiceHost serviceHost = new WorkflowServiceHost(myWorkflow, new Uri(serviceUri));
ServiceDebugBehavior debug = serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
if (debug == null)
{
debug = new ServiceDebugBehavior();
serviceHost.Description.Behaviors.Add(debug);
}
debug.IncludeExceptionDetailInFaults = true;
WorkflowIdleBehavior idle = serviceHost.Description.Behaviors.Find<WorkflowIdleBehavior>();
if (idle == null)
{
idle = new WorkflowIdleBehavior();
serviceHost.Description.Behaviors.Add(idle);
}
idle.TimeToPersist = TimeSpan.FromSeconds(2);
idle.TimeToUnload = TimeSpan.FromSeconds(10);
var behavior = new SqlWorkflowInstanceStoreBehavior
{
ConnectionString = ConfigurationManager.ConnectionStrings["WorkflowPersistence"].ConnectionString,
InstanceEncodingOption = InstanceEncodingOption.None,
InstanceCompletionAction = InstanceCompletionAction.DeleteAll,
InstanceLockedExceptionAction = InstanceLockedExceptionAction.BasicRetry,
HostLockRenewalPeriod = new TimeSpan(00, 00, 30),
RunnableInstancesDetectionPeriod = new TimeSpan(00, 00, 05)
};
serviceHost.Description.Behaviors.Add(behavior);
serviceHost.Open();
Looking at the database, it seems that the workflow is never suspended.
Any help appreciated,
thank you
Not really sure what is going on here but it sounds like there are types used in the workflow that cannot be serialized and prevent the workflow from being stored to disk. When you say "Looking at the database, it seems that the workflow is never suspended." do you really mean suspended? And why do you expect the workflow to be suspended?
What happens if you send just the start message to the workflow and wait 2 seconds? Do you get a new record in the persistence database?