/// <summary>
        /// Publish a WebDeploy package zip file to a web site.
        /// </summary>
        /// <param name="websiteName">The name of the web site.</param>
        /// <param name="slot">The name of the slot.</param>
        /// <param name="package">The WebDeploy package zip file.</param>
        /// <param name="connectionStrings">The connection strings to overwrite the ones in the Web.config file.</param>
        /// <param name="skipAppData">Skip app data</param>
        /// <param name="doNotDelete">Do not delete files at destination</param>
        private void PublishWebProjectFromPackageFile(string websiteName, string slot, string package, Hashtable connectionStrings, bool skipAppData, bool doNotDelete)
        {
            DeploymentBaseOptions remoteBaseOptions = CreateRemoteDeploymentBaseOptions(websiteName, slot);
            DeploymentBaseOptions localBaseOptions = new DeploymentBaseOptions();

            SetWebDeployToSkipAppData(skipAppData, localBaseOptions, remoteBaseOptions);

            DeploymentProviderOptions remoteProviderOptions = new DeploymentProviderOptions(DeploymentWellKnownProvider.Auto);

            using (var deployment = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, package, localBaseOptions))
            {
                DeploymentSyncParameter providerPathParameter = new DeploymentSyncParameter(
                    "Provider Path Parameter",
                    "Provider Path Parameter",
                    SetWebsiteNameForWebDeploy(websiteName, slot),
                    null);
                DeploymentSyncParameterEntry iisAppEntry = new DeploymentSyncParameterEntry(
                    DeploymentSyncParameterEntryKind.ProviderPath,
                    DeploymentWellKnownProvider.IisApp.ToString(),
                    ".*",
                    null);
                DeploymentSyncParameterEntry setAclEntry = new DeploymentSyncParameterEntry(
                    DeploymentSyncParameterEntryKind.ProviderPath,
                    DeploymentWellKnownProvider.SetAcl.ToString(),
                    ".*",
                    null);
                providerPathParameter.Add(iisAppEntry);
                providerPathParameter.Add(setAclEntry);
                deployment.SyncParameters.Add(providerPathParameter);

                // Replace the connection strings in Web.config with the ones user specifies from the cmdlet.
                ReplaceConnectionStrings(deployment, connectionStrings);

                DeploymentSyncOptions syncOptions = new DeploymentSyncOptions
                {
                    DoNotDelete = doNotDelete
                };

                deployment.SyncTo(remoteProviderOptions, remoteBaseOptions, syncOptions);
            }
        }
        private void Publish(object unusedState)
        {
            Operation operation = null;

            try
            {
                lock (_pendingPublishOperations)
                {
                    operation = _pendingPublishOperations.Dequeue();
                }

                if (operation == null)
                {
                    PublishHelper.LogVerboseInformation("Publish: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId);
                    return;
                }

                // This was not required earlier but now that every site will be synced twice for every incoming publish (Look at the postsync override in publishextender),
                // there are chances that same operation might get scheduled in concurrent threads which is not a supported web deploy scenario.
                bool canContinue = true;
                lock (_operationsInProgress)
                {
                    if (_operationsInProgress.Contains(operation.SiteName))
                    {
                        PublishHelper.LogVerboseInformation("Publish: An operation for {0} is already in progress. Thread {1} will mark it as not started to be scheduled later.", operation.SiteName, Thread.CurrentThread.ManagedThreadId);
                        operation.Status = PublishOperationStatus.NotStarted;
                        canContinue = false;
                    }
                    else
                    {
                        _operationsInProgress.Add(operation.SiteName);
                    }
                }

                if (!canContinue)
                {
                    lock (_completedOperations)
                    {
                        _completedOperations.Enqueue(operation);
                    }
                    return;
                }

                operation.ThreadID = Thread.CurrentThread.ManagedThreadId;
                operation.Status = PublishOperationStatus.Error;

                DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions();

                AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName);

                using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, PublishHelper.GetPublishManifest(operation.PhysicalPath), srcBaseOptions))
                {
                    try
                    {
                        DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                        destBaseOptions.ComputerName = operation.PublishUrl;
                        string modifiedPhysicalPath = operation.PhysicalPath;
                        string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath);

                        var fileServerIPParameter = new DeploymentSyncParameter(
                            FileServerIPParameterName,
                            FileServerIPParameterDescription,
                            ipDefaultValue,
                            string.Empty);
                        var fileServerIPEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        fileServerIPParameter.Add(fileServerIPEntry);

                        var contentPathParameter = new DeploymentSyncParameter(
                            ContentPathParameterName,
                            ContentPathParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var contentParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        contentPathParameter.Add(contentParamEntry);

                        var setAclParameter = new DeploymentSyncParameter(
                            SetAclParameterName,
                            SetAclParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.SetAcl.ToString());
                        var setAclParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.SetAcl.ToString(),
                            string.Empty,
                            string.Empty);
                        setAclParameter.Add(setAclParamEntry);

                        depObj.SyncParameters.Add(fileServerIPParameter);
                        depObj.SyncParameters.Add(contentPathParameter);
                        depObj.SyncParameters.Add(setAclParameter);

                        destBaseOptions.UserName = operation.AdminCredential.UserName;
                        destBaseOptions.Password = operation.AdminCredential.Password;
                        destBaseOptions.AuthenticationType = "basic";
                        destBaseOptions.Trace += new EventHandler<DeploymentTraceEventArgs>(WebDeployPublishTrace);
                        destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose;

                        depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions());
                        operation.Status = PublishOperationStatus.Completed;
                        AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName);
                    }
                    catch (Exception e)
                    {
                        AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                if ((e is DeploymentDetailedException
                        && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) ||
                        e is WebHostingObjectNotFoundException)
                {
                    operation.Status = PublishOperationStatus.SourceOrDestinationInvalid;
                }

                AntaresEventProvider.EventWritePublishFailOverServiceFailedToGetSourceSite(operation.SiteName, e.ToString());
            }
            finally
            {
                lock (_completedOperations)
                {
                    PublishHelper.LogVerboseInformation("Publish: Thread {0} qeuing completed operation for site: {1}", operation.ThreadID, operation.SiteName);
                    _completedOperations.Enqueue(operation);
                }

                lock (_operationsInProgress)
                {
                    _operationsInProgress.Remove(operation.SiteName);
                }

                _continueEvent.Set();
                PublishHelper.LogVerboseInformation("Publish: Thread {0} exiting", Thread.CurrentThread.ManagedThreadId);
            }
        }
 /// <summary>
 /// Add a connection string parameter to the deployment.
 /// </summary>
 /// <param name="deployment">The deployment object.</param>
 /// <param name="name">Connection string name.</param>
 /// <param name="value">Connection string value.</param>
 private void AddConnectionString(DeploymentObject deployment, string name, string value)
 {
     var deploymentSyncParameterName = string.Format("Connection String {0} Parameter", name);
     DeploymentSyncParameter connectionStringParameter = new DeploymentSyncParameter(
         deploymentSyncParameterName,
         deploymentSyncParameterName,
         value,
         null);
     DeploymentSyncParameterEntry connectionStringEntry = new DeploymentSyncParameterEntry(
         DeploymentSyncParameterEntryKind.XmlFile,
         @"\\web.config$",
         string.Format(@"//connectionStrings/add[@name='{0}']/@connectionString", name),
         null);
     connectionStringParameter.Add(connectionStringEntry);
     deployment.SyncParameters.Add(connectionStringParameter);
 }
        /// <summary>
        /// Web Deploy does not parameterize or run any rules (parameterization is one of the rules) when deletion is used.
        /// So to work around that deletecontent does a simple publish of empty content to the server and gets the IP that is hosting the volume.
        /// After finding the IP the deletion is called on that content path. This will effectively delete "\\someipaddress\volumename\guidfolder"
        /// </summary>
        /// <param name="unusedState">This is not used. This is the signature for the waitcallback expected by threadpool.</param>
        private void DeleteContent(object unusedState)
        {
            Operation operation = null;

            try
            {
                lock (_pendingDeleteOperations)
                {
                    operation = _pendingDeleteOperations.Dequeue();
                }

                if (operation == null)
                {
                    PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId);
                    return;
                }

                operation.ThreadID = Thread.CurrentThread.ManagedThreadId;
                operation.Status = PublishOperationStatus.Error;
                DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions();
                AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName);

                string remoteIP = string.Empty;
                bool errorOcurred = false;

                using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.ContentPath, Path.GetTempPath(), srcBaseOptions))
                {
                    try
                    {
                        DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                        destBaseOptions.ComputerName = operation.PublishUrl;
                        string modifiedPhysicalPath = operation.PhysicalPath;
                        string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath);

                        var queryServerIPParameter = new DeploymentSyncParameter(
                            QueryServerIPParameterName,
                            QueryServerIPParameterDescription,
                            string.Empty,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var queryServerIPParameterEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        queryServerIPParameter.Add(queryServerIPParameterEntry);

                        var contentPathParameter = new DeploymentSyncParameter(
                            ContentPathParameterName,
                            ContentPathParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var contentParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        contentPathParameter.Add(contentParamEntry);

                        depObj.SyncParameters.Add(contentPathParameter);
                        depObj.SyncParameters.Add(queryServerIPParameter);

                        destBaseOptions.UserName = operation.AdminCredential.UserName;
                        destBaseOptions.Password = operation.AdminCredential.Password;
                        destBaseOptions.AuthenticationType = "basic";

                        depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions());
                    }
                    catch (Exception e)
                    {
                        bool unhandledException = false;
                        // In cases where the site was deleted on the source before it was ever synced to the destination
                        // mark as the destination invalid and set the status so that its never attempted again.
                        if (e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.ERROR_INVALID_PATH)
                        {
                            string[] messageArray = e.Message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                            if (messageArray.Length > 0)
                            {
                                remoteIP = messageArray[0];
                            }
                            else
                            {
                                errorOcurred = true;
                            }
                        }
                        else if (e is DeploymentException)
                        {
                            errorOcurred = true;
                        }
                        else
                        {
                            // its not a deployment exception. This is an exception not handled by web deploy such as duplicate key exception.
                            // This needs to be retried.
                            unhandledException = true;
                            errorOcurred = true;
                        }

                        if (errorOcurred)
                        {
                            AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                            operation.Status = unhandledException ? PublishOperationStatus.Error : PublishOperationStatus.SourceOrDestinationInvalid;
                        }
                    }
                }

                if (!errorOcurred)
                {
                    string[] pathParts = operation.PhysicalPath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                    string remotePath = string.Concat(@"\\", remoteIP, @"\", pathParts[1], @"\", pathParts[2]);

                    using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Auto, string.Empty, srcBaseOptions))
                    {
                        try
                        {
                            DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                            destBaseOptions.ComputerName = operation.PublishUrl;
                            destBaseOptions.UserName = operation.AdminCredential.UserName;
                            destBaseOptions.Password = operation.AdminCredential.Password;
                            destBaseOptions.AuthenticationType = "basic";
                            destBaseOptions.Trace += new EventHandler<DeploymentTraceEventArgs>(WebDeployPublishTrace);
                            destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose;

                            var syncOptions = new DeploymentSyncOptions();
                            syncOptions.DeleteDestination = true;

                            depObj.SyncTo(DeploymentWellKnownProvider.ContentPath, remotePath, destBaseOptions, syncOptions);
                            operation.Status = PublishOperationStatus.Completed;
                            AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName);
                        }
                        catch (Exception e)
                        {
                            var ex = e as DeploymentDetailedException;
                            if (ex != null && ex.ErrorCode == DeploymentErrorCode.FileOrFolderNotFound)
                            {
                                operation.Status = PublishOperationStatus.SourceOrDestinationInvalid;
                            }
                            else
                            {
                                AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                            }
                        }
                    }
                }
            }
            finally
            {
                lock (_completedOperations)
                {
                    PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} queuing completed operation for site: {1}", operation.ThreadID, operation.SiteName);
                    _completedOperations.Enqueue(operation);
                }

                _continueEvent.Set();
                PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} exiting.", Thread.CurrentThread.ManagedThreadId);
            }
        }
        public override bool Publish(bool setSize)
        {
            var sourceBaseOptions = new DeploymentBaseOptions();

            var destBaseOptions = new DeploymentBaseOptions();
            if (!setSize)
            {
                sourceBaseOptions.Trace += TraceEventHandler;
                sourceBaseOptions.TraceLevel = TraceLevel.Verbose;
                destBaseOptions.Trace += TraceEventHandler;
                destBaseOptions.TraceLevel = TraceLevel.Verbose;
            }

            destBaseOptions.ComputerName = _publishSettings.ComputerName;
            destBaseOptions.UserName = _publishSettings.Username;
            destBaseOptions.Password = _publishSettings.Password;
            LogTrace("Publishing as {0}", destBaseOptions.UserName);
            destBaseOptions.AuthenticationType = "basic";

            bool publishSucceeded = true;

            #region Publish Content

            try
            {
                using (var sourceObject =
                DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: true),
                    sourceBaseOptions))
                {
                    var syncOptions = new DeploymentSyncOptions()
                    {
                        DoNotDelete = true,
                    };

                    if (!setSize)
                    {
                        LogTrace("Started content publish for: {0}", _localSite.SiteName);

                        if (HasDatabase)
                        {
                            var connectionStringParameter = new DeploymentSyncParameter(
                            "ConnectionStringParam",                    // Name
                            "DBConnectionString Param",                 // Description
                            _publishSettings.SqlDBConnectionString.ConnectionString,     // Default Value to set
                            null);                                      // Tag

                            var entry = new DeploymentSyncParameterEntry(
                                DeploymentSyncParameterEntryKind.XmlFile,                                           // Kind
                                @"\\web\.config$",                                                                   // Scope
                                connectionStringXPath,    // Match
                                null);                                                                              // Tag

                            connectionStringParameter.Add(entry);
                            sourceObject.SyncParameters.Add(connectionStringParameter);
                        }
                    }

                    try
                    {
                        syncOptions.WhatIf = setSize;

                        var summary = sourceObject.SyncTo(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: false),
                            destBaseOptions, syncOptions);

                        if (!setSize)
                        {
                            LogTrace("Content Published Succesfully For Site: {0} to {1} ", _localSite.SiteName, _publishSettings.SiteName);
                            Helper.UpdateStatus(_localSite.SiteName, _localSite.ServerName);
                        }
                        else
                        {
                            _control.SetProgressbarMax(this.LocalSite.ServerName + this.LocalSite.SiteName, summary.TotalChanges);
                        }
                    }
                    catch (Exception ex)
                    {
                        string message = string.Format("Error syncing content for site: {0}", _localSite.SiteName);
                        LogTrace(message);
                        LogTrace(ex.ToString());
                        publishSucceeded = false;
                    }
                }
            }
            catch (Exception ex)
            {
                LogTrace("Error starting content publish for site: {0}", _localSite.SiteName);
                LogTrace(ex.ToString());
                publishSucceeded = false;
            }

            _control.UpdateStatusLabel(string.Empty);

            #endregion

            if (!setSize)
            {
                _control.SetContentPublished(this.LocalSite.ServerName + this.LocalSite.SiteName, publishSucceeded);
            }

            this.PublishStatus = publishSucceeded;
            return publishSucceeded;
        }
Example #6
0
        public override bool Publish(bool setSize)
        {
            var sourceBaseOptions = new DeploymentBaseOptions();

            var destBaseOptions = new DeploymentBaseOptions();

            if (!setSize)
            {
                sourceBaseOptions.Trace     += TraceEventHandler;
                sourceBaseOptions.TraceLevel = TraceLevel.Verbose;
                destBaseOptions.Trace       += TraceEventHandler;
                destBaseOptions.TraceLevel   = TraceLevel.Verbose;
            }

            destBaseOptions.ComputerName = _publishSettings.ComputerName;
            destBaseOptions.UserName     = _publishSettings.Username;
            destBaseOptions.Password     = _publishSettings.Password;
            LogTrace("Publishing as {0}", destBaseOptions.UserName);
            destBaseOptions.AuthenticationType = "basic";

            bool publishSucceeded = true;

            #region Publish Content

            try
            {
                using (var sourceObject =
                           DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: true),
                                                          sourceBaseOptions))
                {
                    var syncOptions = new DeploymentSyncOptions()
                    {
                        DoNotDelete = true,
                    };

                    if (!setSize)
                    {
                        LogTrace("Started content publish for: {0}", _localSite.SiteName);

                        if (HasDatabase)
                        {
                            var connectionStringParameter = new DeploymentSyncParameter(
                                "ConnectionStringParam",                                 // Name
                                "DBConnectionString Param",                              // Description
                                _publishSettings.SqlDBConnectionString.ConnectionString, // Default Value to set
                                null);                                                   // Tag

                            var entry = new DeploymentSyncParameterEntry(
                                DeploymentSyncParameterEntryKind.XmlFile, // Kind
                                @"\\web\.config$",                        // Scope
                                connectionStringXPath,                    // Match
                                null);                                    // Tag

                            connectionStringParameter.Add(entry);
                            sourceObject.SyncParameters.Add(connectionStringParameter);
                        }
                    }

                    try
                    {
                        syncOptions.WhatIf = setSize;

                        var summary = sourceObject.SyncTo(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: false),
                                                          destBaseOptions, syncOptions);

                        if (!setSize)
                        {
                            LogTrace("Content Published Succesfully For Site: {0} to {1} ", _localSite.SiteName, _publishSettings.SiteName);
                            Helper.UpdateStatus(_localSite.SiteName, _localSite.ServerName);
                        }
                        else
                        {
                            _control.SetProgressbarMax(this.LocalSite.ServerName + this.LocalSite.SiteName, summary.TotalChanges);
                        }
                    }
                    catch (Exception ex)
                    {
                        string message = string.Format("Error syncing content for site: {0}", _localSite.SiteName);
                        LogTrace(message);
                        LogTrace(ex.ToString());
                        publishSucceeded = false;
                    }
                }
            }
            catch (Exception ex)
            {
                LogTrace("Error starting content publish for site: {0}", _localSite.SiteName);
                LogTrace(ex.ToString());
                publishSucceeded = false;
            }

            _control.UpdateStatusLabel(string.Empty);

            #endregion

            if (!setSize)
            {
                _control.SetContentPublished(this.LocalSite.ServerName + this.LocalSite.SiteName, publishSucceeded);
            }

            this.PublishStatus = publishSucceeded;
            return(publishSucceeded);
        }
Example #7
0
        private void Publish(object unusedState)
        {
            Operation operation = null;

            try
            {
                lock (_pendingPublishOperations)
                {
                    operation = _pendingPublishOperations.Dequeue();
                }

                if (operation == null)
                {
                    PublishHelper.LogVerboseInformation("Publish: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId);
                    return;
                }

                // This was not required earlier but now that every site will be synced twice for every incoming publish (Look at the postsync override in publishextender),
                // there are chances that same operation might get scheduled in concurrent threads which is not a supported web deploy scenario.
                bool canContinue = true;
                lock (_operationsInProgress)
                {
                    if (_operationsInProgress.Contains(operation.SiteName))
                    {
                        PublishHelper.LogVerboseInformation("Publish: An operation for {0} is already in progress. Thread {1} will mark it as not started to be scheduled later.", operation.SiteName, Thread.CurrentThread.ManagedThreadId);
                        operation.Status = PublishOperationStatus.NotStarted;
                        canContinue      = false;
                    }
                    else
                    {
                        _operationsInProgress.Add(operation.SiteName);
                    }
                }

                if (!canContinue)
                {
                    lock (_completedOperations)
                    {
                        _completedOperations.Enqueue(operation);
                    }
                    return;
                }

                operation.ThreadID = Thread.CurrentThread.ManagedThreadId;
                operation.Status   = PublishOperationStatus.Error;

                DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions();

                AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName);

                using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, PublishHelper.GetPublishManifest(operation.PhysicalPath), srcBaseOptions))
                {
                    try
                    {
                        DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                        destBaseOptions.ComputerName = operation.PublishUrl;
                        string modifiedPhysicalPath = operation.PhysicalPath;
                        string ipDefaultValue       = GetFileServerIP(ref modifiedPhysicalPath);

                        var fileServerIPParameter = new DeploymentSyncParameter(
                            FileServerIPParameterName,
                            FileServerIPParameterDescription,
                            ipDefaultValue,
                            string.Empty);
                        var fileServerIPEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        fileServerIPParameter.Add(fileServerIPEntry);

                        var contentPathParameter = new DeploymentSyncParameter(
                            ContentPathParameterName,
                            ContentPathParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var contentParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        contentPathParameter.Add(contentParamEntry);

                        var setAclParameter = new DeploymentSyncParameter(
                            SetAclParameterName,
                            SetAclParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.SetAcl.ToString());
                        var setAclParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.SetAcl.ToString(),
                            string.Empty,
                            string.Empty);
                        setAclParameter.Add(setAclParamEntry);

                        depObj.SyncParameters.Add(fileServerIPParameter);
                        depObj.SyncParameters.Add(contentPathParameter);
                        depObj.SyncParameters.Add(setAclParameter);

                        destBaseOptions.UserName           = operation.AdminCredential.UserName;
                        destBaseOptions.Password           = operation.AdminCredential.Password;
                        destBaseOptions.AuthenticationType = "basic";
                        destBaseOptions.Trace     += new EventHandler <DeploymentTraceEventArgs>(WebDeployPublishTrace);
                        destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose;

                        depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions());
                        operation.Status = PublishOperationStatus.Completed;
                        AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName);
                    }
                    catch (Exception e)
                    {
                        AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                if ((e is DeploymentDetailedException &&
                     ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) ||
                    e is WebHostingObjectNotFoundException)
                {
                    operation.Status = PublishOperationStatus.SourceOrDestinationInvalid;
                }

                AntaresEventProvider.EventWritePublishFailOverServiceFailedToGetSourceSite(operation.SiteName, e.ToString());
            }
            finally
            {
                lock (_completedOperations)
                {
                    PublishHelper.LogVerboseInformation("Publish: Thread {0} qeuing completed operation for site: {1}", operation.ThreadID, operation.SiteName);
                    _completedOperations.Enqueue(operation);
                }

                lock (_operationsInProgress)
                {
                    _operationsInProgress.Remove(operation.SiteName);
                }

                _continueEvent.Set();
                PublishHelper.LogVerboseInformation("Publish: Thread {0} exiting", Thread.CurrentThread.ManagedThreadId);
            }
        }
Example #8
0
        /// <summary>
        /// Web Deploy does not parameterize or run any rules (parameterization is one of the rules) when deletion is used.
        /// So to work around that deletecontent does a simple publish of empty content to the server and gets the IP that is hosting the volume.
        /// After finding the IP the deletion is called on that content path. This will effectively delete "\\someipaddress\volumename\guidfolder"
        /// </summary>
        /// <param name="unusedState">This is not used. This is the signature for the waitcallback expected by threadpool.</param>
        private void DeleteContent(object unusedState)
        {
            Operation operation = null;

            try
            {
                lock (_pendingDeleteOperations)
                {
                    operation = _pendingDeleteOperations.Dequeue();
                }

                if (operation == null)
                {
                    PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId);
                    return;
                }

                operation.ThreadID = Thread.CurrentThread.ManagedThreadId;
                operation.Status   = PublishOperationStatus.Error;
                DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions();
                AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName);

                string remoteIP     = string.Empty;
                bool   errorOcurred = false;

                using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.ContentPath, Path.GetTempPath(), srcBaseOptions))
                {
                    try
                    {
                        DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                        destBaseOptions.ComputerName = operation.PublishUrl;
                        string modifiedPhysicalPath = operation.PhysicalPath;
                        string ipDefaultValue       = GetFileServerIP(ref modifiedPhysicalPath);

                        var queryServerIPParameter = new DeploymentSyncParameter(
                            QueryServerIPParameterName,
                            QueryServerIPParameterDescription,
                            string.Empty,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var queryServerIPParameterEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        queryServerIPParameter.Add(queryServerIPParameterEntry);

                        var contentPathParameter = new DeploymentSyncParameter(
                            ContentPathParameterName,
                            ContentPathParameterDescription,
                            modifiedPhysicalPath,
                            DeploymentWellKnownTag.PhysicalPath.ToString());
                        var contentParamEntry = new DeploymentSyncParameterEntry(
                            DeploymentSyncParameterEntryKind.ProviderPath,
                            DeploymentWellKnownProvider.ContentPath.ToString(),
                            string.Empty,
                            string.Empty);
                        contentPathParameter.Add(contentParamEntry);

                        depObj.SyncParameters.Add(contentPathParameter);
                        depObj.SyncParameters.Add(queryServerIPParameter);

                        destBaseOptions.UserName           = operation.AdminCredential.UserName;
                        destBaseOptions.Password           = operation.AdminCredential.Password;
                        destBaseOptions.AuthenticationType = "basic";

                        depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions());
                    }
                    catch (Exception e)
                    {
                        bool unhandledException = false;
                        // In cases where the site was deleted on the source before it was ever synced to the destination
                        // mark as the destination invalid and set the status so that its never attempted again.
                        if (e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.ERROR_INVALID_PATH)
                        {
                            string[] messageArray = e.Message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                            if (messageArray.Length > 0)
                            {
                                remoteIP = messageArray[0];
                            }
                            else
                            {
                                errorOcurred = true;
                            }
                        }
                        else if (e is DeploymentException)
                        {
                            errorOcurred = true;
                        }
                        else
                        {
                            // its not a deployment exception. This is an exception not handled by web deploy such as duplicate key exception.
                            // This needs to be retried.
                            unhandledException = true;
                            errorOcurred       = true;
                        }

                        if (errorOcurred)
                        {
                            AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                            operation.Status = unhandledException ? PublishOperationStatus.Error : PublishOperationStatus.SourceOrDestinationInvalid;
                        }
                    }
                }

                if (!errorOcurred)
                {
                    string[] pathParts  = operation.PhysicalPath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                    string   remotePath = string.Concat(@"\\", remoteIP, @"\", pathParts[1], @"\", pathParts[2]);

                    using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Auto, string.Empty, srcBaseOptions))
                    {
                        try
                        {
                            DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions();
                            destBaseOptions.ComputerName       = operation.PublishUrl;
                            destBaseOptions.UserName           = operation.AdminCredential.UserName;
                            destBaseOptions.Password           = operation.AdminCredential.Password;
                            destBaseOptions.AuthenticationType = "basic";
                            destBaseOptions.Trace     += new EventHandler <DeploymentTraceEventArgs>(WebDeployPublishTrace);
                            destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose;

                            var syncOptions = new DeploymentSyncOptions();
                            syncOptions.DeleteDestination = true;

                            depObj.SyncTo(DeploymentWellKnownProvider.ContentPath, remotePath, destBaseOptions, syncOptions);
                            operation.Status = PublishOperationStatus.Completed;
                            AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName);
                        }
                        catch (Exception e)
                        {
                            var ex = e as DeploymentDetailedException;
                            if (ex != null && ex.ErrorCode == DeploymentErrorCode.FileOrFolderNotFound)
                            {
                                operation.Status = PublishOperationStatus.SourceOrDestinationInvalid;
                            }
                            else
                            {
                                AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString());
                            }
                        }
                    }
                }
            }
            finally
            {
                lock (_completedOperations)
                {
                    PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} queuing completed operation for site: {1}", operation.ThreadID, operation.SiteName);
                    _completedOperations.Enqueue(operation);
                }

                _continueEvent.Set();
                PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} exiting.", Thread.CurrentThread.ManagedThreadId);
            }
        }