public ApplicationDeployment(ApplicationDeployStatus status, ApplicationDeployment copyFrom) : this(copyFrom.Cluster, status, copyFrom.ImageStorePath, copyFrom.ApplicationTypeName, copyFrom.ApplicationTypeVersion, copyFrom.ApplicationInstanceName, copyFrom.PackagePath, copyFrom.DeploymentTimestamp) { }
/// <summary> /// Queues deployment of application packages to the given cluster. /// </summary> /// <param name="clusterAddress"></param> /// <param name="connectionPort"></param> /// <returns></returns> public async Task<IEnumerable<Guid>> QueueApplicationDeploymentAsync(string clusterAddress, int clusterPort) { IReliableQueue<Guid> queue = await this.StateManager.GetOrAddAsync<IReliableQueue<Guid>>(QueueName); IReliableDictionary<Guid, ApplicationDeployment> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<Guid, ApplicationDeployment>>(DictionaryName); List<Guid> workIds = new List<Guid>(this.ApplicationPackages.Count()); using (ITransaction tx = this.StateManager.CreateTransaction()) { foreach (ApplicationPackageInfo package in this.ApplicationPackages) { Guid id = Guid.NewGuid(); ApplicationDeployment applicationDeployment = new ApplicationDeployment( cluster: GetClusterAddress(clusterAddress, clusterPort), status: ApplicationDeployStatus.Copy, imageStorePath: null, applicationTypeName: package.ApplicationTypeName, applicationTypeVersion: package.ApplicationTypeVersion, applicationInstanceName: GetApplicationInstanceName(package.PackageFileName), packageZipFilePath: Path.Combine(this.applicationPackageDataPath.FullName, package.PackageFileName), timestamp: DateTimeOffset.UtcNow); await dictionary.AddAsync(tx, id, applicationDeployment); await queue.EnqueueAsync(tx, id); workIds.Add(id); } await tx.CommitAsync(); return workIds; } }
internal async Task<ApplicationDeployment> ProcessApplicationDeployment(ApplicationDeployment applicationDeployment, CancellationToken cancellationToken) { try { switch (applicationDeployment.Status) { case ApplicationDeployStatus.Copy: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Copying to image store. Cluster: {0}. Application: {1}. Package path: {2}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.PackageZipFilePath); try { // Unzip the package contents to a temporary location on disk. if (!this.applicationPackageTempDirectory.Exists) { this.applicationPackageTempDirectory.Create(); } FileInfo packageFile = new FileInfo(applicationDeployment.PackageZipFilePath); DirectoryInfo packageExtractLocation = new DirectoryInfo(Path.Combine(this.applicationPackageTempDirectory.FullName, applicationDeployment.ApplicationInstanceName)); if (packageExtractLocation.Exists) { packageExtractLocation.Delete(true); } ServiceEventSource.Current.ServiceMessage( this, "Extracting application package from {0} to {1}", packageFile.FullName, packageExtractLocation.FullName); ZipFile.ExtractToDirectory(packageFile.FullName, packageExtractLocation.FullName); // Copy the unzipped application package to the cluster's imagestore and clean up. string imageStorePath = await this.applicationOperator.CopyPackageToImageStoreAsync( applicationDeployment.Cluster, packageExtractLocation.FullName, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, cancellationToken); packageExtractLocation.Delete(true); return new ApplicationDeployment( applicationDeployment.Cluster, ApplicationDeployStatus.Register, imageStorePath, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, applicationDeployment.ApplicationInstanceName, applicationDeployment.PackageZipFilePath, applicationDeployment.DeploymentTimestamp); } catch (FabricServiceNotFoundException fsnfe) { // image store service isn't ready yet. // This is retry-able, just need to wait a bit for it to come up. // This can happen when an application deployment is attempted immediately after a cluster comes up. ServiceEventSource.Current.ServiceMessage( this, "Copy to image store failed with FabricServiceNotFoundException. Package: {0}. Error: {1}", applicationDeployment.PackageZipFilePath, fsnfe.Message); return applicationDeployment; } catch (FileNotFoundException fnfe) { ServiceEventSource.Current.ServiceMessage( this, "Found corrupt application package. Package: {0}. Error: {1}", applicationDeployment.PackageZipFilePath, fnfe.Message); return new ApplicationDeployment(ApplicationDeployStatus.Failed, applicationDeployment); } case ApplicationDeployStatus.Register: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Registering. Cluster: {0}. Application: {1}, Imagestore path: {2}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.ImageStorePath); try { await this.applicationOperator.RegisterApplicationAsync( applicationDeployment.Cluster, applicationDeployment.ImageStorePath, cancellationToken); return new ApplicationDeployment(ApplicationDeployStatus.Create, applicationDeployment); } catch (FabricElementAlreadyExistsException) { ServiceEventSource.Current.ServiceMessage(this, "Application package is already registered. Package: {0}.", applicationDeployment.PackageZipFilePath); // application already exists, set status to Create it so we don't keep failing on this. return new ApplicationDeployment(ApplicationDeployStatus.Create, applicationDeployment); } case ApplicationDeployStatus.Create: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Creating. Cluster: {0}. Application: {1}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName); await this.applicationOperator.CreateApplicationAsync( applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, cancellationToken); return new ApplicationDeployment(ApplicationDeployStatus.Complete, applicationDeployment); default: return applicationDeployment; } } catch (FabricTransientException fte) { ServiceEventSource.Current.ServiceMessage( this, "A transient error occured during package processing. Package: {0}. Stage: {1}. Error: {2}", applicationDeployment.ApplicationInstanceName, applicationDeployment.Status, fte.Message); // return the deployment unchanged. It will be returned to the queue and tried again. return applicationDeployment; } catch (Exception e) { ServiceEventSource.Current.ServiceMessage( this, "Application package processing failed. Package: {0}. Error: {1}", applicationDeployment.PackageZipFilePath, e.ToString()); return new ApplicationDeployment(ApplicationDeployStatus.Failed, applicationDeployment); } }
internal async Task<ApplicationDeployment> ProcessApplicationDeployment(ApplicationDeployment applicationDeployment, CancellationToken cancellationToken) { switch (applicationDeployment.Status) { case ApplicationDeployStatus.Copy: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Copying to image store. Cluster: {0}. Application: {1}. Package path: {2}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.PackagePath); string imageStorePath = await this.applicationOperator.CopyPackageToImageStoreAsync( applicationDeployment.Cluster, applicationDeployment.PackagePath, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, cancellationToken); return new ApplicationDeployment( applicationDeployment.Cluster, ApplicationDeployStatus.Register, imageStorePath, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, applicationDeployment.ApplicationInstanceName, applicationDeployment.PackagePath, applicationDeployment.DeploymentTimestamp); case ApplicationDeployStatus.Register: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Registering. Cluster: {0}. Application: {1}, Imagestore path: {2}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.ImageStorePath); await this.applicationOperator.RegisterApplicationAsync( applicationDeployment.Cluster, applicationDeployment.ImageStorePath, cancellationToken); return new ApplicationDeployment(ApplicationDeployStatus.Create, applicationDeployment); case ApplicationDeployStatus.Create: ServiceEventSource.Current.ServiceMessage( this, "Application deployment: Creating. Cluster: {0}. Application: {1}", applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName); await this.applicationOperator.CreateApplicationAsync( applicationDeployment.Cluster, applicationDeployment.ApplicationInstanceName, applicationDeployment.ApplicationTypeName, applicationDeployment.ApplicationTypeVersion, cancellationToken); return new ApplicationDeployment(ApplicationDeployStatus.Complete, applicationDeployment); default: return applicationDeployment; } }