Пример #1
0
        /// <summary>
        ///     Called when the CLI invokes this command.
        /// </summary>
        /// <param name="IpcClient">Interprocess communication pipe to the application that invoked this command.</param>
        internal void Run(CommandIPC IpcClient)
        {
            VirtualPath = VirtualFileSystem.Normalize(VirtualPath);

            if (!Directory.Exists(LocalPath))
            {
                IpcClient.Respond("FAILED: Path does not exists: {0}");
                return;
            }

            if (!Program.NetClient.IsConnected)
            {
                IpcClient.Respond("FAILED: No connection to server.");
                return;
            }

            if (!Program.NetClient.Permissions.HasPermission(UserPermissionType.Write, "", false, true))
            {
                IpcClient.Respond("FAILED: Permission denied to manage builds.");
                return;
            }

            PublishBuildTask     Publisher         = new PublishBuildTask();
            BuildPublishingState OldPublisherState = BuildPublishingState.Unknown;
            int OldPublisherProgress = 0;

            Publisher.Start(VirtualPath, LocalPath);

            Program.PumpLoop(
                () =>
            {
                if (!Program.NetClient.IsConnected)
                {
                    IpcClient.Respond("FAILED: Lost connection to server.");
                    return(true);
                }

                if (Publisher != null && (Publisher.State != OldPublisherState || (int)Publisher.Progress != OldPublisherProgress))
                {
                    OldPublisherState    = Publisher.State;
                    OldPublisherProgress = (int)Publisher.Progress;

                    switch (Publisher.State)
                    {
                    case BuildPublishingState.CopyingFiles:
                        {
                            IpcClient.Respond(string.Format("Copying files to storage: {0}%", OldPublisherProgress));
                            break;
                        }

                    case BuildPublishingState.ScanningFiles:
                        {
                            IpcClient.Respond(string.Format("Scanning local files: {0}%", OldPublisherProgress));
                            break;
                        }

                    case BuildPublishingState.UploadingManifest:
                        {
                            IpcClient.Respond("Uploading manfiest to server.");
                            break;
                        }

                    case BuildPublishingState.FailedVirtualPathAlreadyExists:
                        {
                            IpcClient.Respond(string.Format("FAILED: Build already exists at path '{0}'.", VirtualPath));
                            return(true);
                        }

                    case BuildPublishingState.PermissionDenied:
                        {
                            IpcClient.Respond(string.Format("FAILED: Permission denied to path '{0}'.", VirtualPath));
                            return(true);
                        }

                    case BuildPublishingState.FailedGuidAlreadyExists:
                        {
                            IpcClient.Respond("FAILED: Manifest with same GUID already exists.");
                            return(true);
                        }

                    case BuildPublishingState.Success:
                        {
                            Publisher.Commit();
                            Publisher = null;
                            IpcClient.Respond("SUCCESS: Build added successfully.");
                            return(true);
                        }

                    case BuildPublishingState.Failed:
                    default:
                        {
                            IpcClient.Respond("FAILED: Undefined reason.");
                            return(true);
                        }
                    }
                }

                return(false);
            }
                );
        }
Пример #2
0
        /// <summary>
        /// </summary>
        /// <param name="Name"></param>
        /// <param name="VirtualPath"></param>
        /// <param name="LocalPath"></param>
        public void Start(string VirtualPath, string InLocalPath)
        {
            LocalPath = InLocalPath;
            State     = BuildPublishingState.ScanningFiles;

            Task.Run(
                () =>
            {
                try
                {
                    Guid NewManifestId = Guid.NewGuid();

                    // Don't allow downloading of this manifest until we have fully committed it.
                    Program.ManifestDownloadManager.BlockDownload(NewManifestId);

                    // Calculate max size of all files in folder to publish.
                    string[] Files = Directory.GetFiles(LocalPath, "*", SearchOption.AllDirectories);
                    long TotalSize = 0;
                    for (int i = 0; i < Files.Length; i++)
                    {
                        TotalSize += new FileInfo(Files[i]).Length;
                    }

                    // Allocate appropriate folder to store build in.
                    if (!Program.StorageManager.AllocateSpace(TotalSize, NewManifestId, out StoragePath))
                    {
                        Logger.Log(LogLevel.Error, LogCategory.Main, "Failed to allocate space, storage folders likely at capacity.");

                        Program.ManifestDownloadManager.UnblockDownload(NewManifestId);
                        State = BuildPublishingState.Failed;
                        return;
                    }

                    // Recreated directory.
                    if (Directory.Exists(StoragePath))
                    {
                        FileUtils.DeleteDirectory(StoragePath);
                    }

                    Directory.CreateDirectory(StoragePath);

                    // Copy each file over to the storage folder.
                    State = BuildPublishingState.CopyingFiles;
                    for (int i = 0; i < Files.Length; i++)
                    {
                        string Src          = Files[i];
                        string RelativePath = Files[i].Substring(LocalPath.Length).TrimStart('/', '\\');
                        string Dst          = Path.Combine(StoragePath, RelativePath);

                        string DstDir = Path.GetDirectoryName(Dst);
                        if (!Directory.Exists(DstDir))
                        {
                            Directory.CreateDirectory(DstDir);
                        }

                        Progress    = i / (float)Files.Length * 50.0f;
                        CurrentFile = Src;

                        File.Copy(Src, Dst);
                    }

                    // Build manifest from directory.
                    Manifest = BuildManifest.BuildFromDirectory(
                        NewManifestId, StoragePath, VirtualPath, Program.IOQueue, (InFile, InProgress) =>
                    {
                        Progress = 50.0f + InProgress * 0.5f;
                        if (InFile.Length > 0)
                        {
                            CurrentFile = InFile;
                        }
                    }
                        );

                    ManualResetEvent PublishCompleteEvent = new ManualResetEvent(false);
                    ManifestPublishResultRecievedHandler PublishHandler = (ManifestId, Result) =>
                    {
                        if (ManifestId == Manifest.Guid)
                        {
                            switch (Result)
                            {
                            case PublishManifestResult.Success:
                                {
                                    break;
                                }

                            case PublishManifestResult.VirtualPathAlreadyExists:
                                {
                                    State = BuildPublishingState.FailedVirtualPathAlreadyExists;
                                    break;
                                }

                            case PublishManifestResult.PermissionDenied:
                                {
                                    State = BuildPublishingState.PermissionDenied;
                                    break;
                                }

                            case PublishManifestResult.GuidAlreadyExists:
                                {
                                    State = BuildPublishingState.FailedGuidAlreadyExists;
                                    break;
                                }

                            case PublishManifestResult.Failed:
                            default:
                                {
                                    State = BuildPublishingState.Failed;
                                    break;
                                }
                            }

                            PublishCompleteEvent.Set();
                        }
                    };

                    Program.NetClient.OnManifestPublishResultRecieved += PublishHandler;

                    // Submit to the server.
                    State = BuildPublishingState.UploadingManifest;
                    if (!Program.NetClient.PublishManifest(Manifest))
                    {
                        State = BuildPublishingState.Failed;
                        Program.ManifestDownloadManager.UnblockDownload(NewManifestId);
                        return;
                    }

                    // Wait for complete delegate.
                    PublishCompleteEvent.WaitOne();

                    Program.NetClient.OnManifestPublishResultRecieved -= PublishHandler;

                    // Abort here if publishing failed.
                    if (State != BuildPublishingState.UploadingManifest)
                    {
                        Program.ManifestDownloadManager.UnblockDownload(NewManifestId);
                        return;
                    }

                    State    = BuildPublishingState.Success;
                    Progress = 100;
                }
                catch (Exception ex)
                {
                    Logger.Log(LogLevel.Error, LogCategory.Main, "Manifest publishing failed with exception: {0}", ex.Message);
                    State = BuildPublishingState.Failed;
                }
            }
                );
        }