예제 #1
0
        private ActivityResult RunSqlScript( InstallData installData, string sqlScriptFile, int consoleMessageReportFrequency, int progressbarEventFrequency, int percentOfStep, int startPercent )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;
            SqlConnection conn = null;

            string currentScript = string.Empty;

            try
            {
                string sql = System.IO.File.ReadAllText( sqlScriptFile );

                string connectionString = String.Format( "user id={0};password={1};server={2};Initial Catalog={3};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server, installData.ConnectionString.Database );
                conn = new SqlConnection( connectionString );
                conn.Open();

                RockScriptParser scriptParser = new RockScriptParser(sql);

                int sqlScriptCount = scriptParser.ScriptCount;
                int scriptsRun = 0;
                int scriptNextConsolePercentile = consoleMessageReportFrequency;
                int scriptNextProgressbarPercentile = progressbarEventFrequency;

                if ( consoleMessageReportFrequency != 0 )
                {
                    this.SendConsoleMessage( String.Format("There are {0} scripts to run.", sqlScriptCount) );
                }

                using ( SqlTransaction transaction = conn.BeginTransaction() )
                {
                    foreach ( var script in scriptParser.ScriptCollection )
                    {
                        currentScript = script;

                        if ( !string.IsNullOrWhiteSpace( script ) )
                        {
                            SqlCommand command = new SqlCommand( script, conn, transaction );
                            command.ExecuteNonQuery();
                        }

                        scriptsRun++;

                        // calculate current percentile
                        int currentPercentile = (int)(((double)scriptsRun / (double)sqlScriptCount) * 100);

                        // update console messages
                        if ( consoleMessageReportFrequency != 0 )
                        {
                            if ( sqlScriptCount == scriptsRun )
                            {
                                this.SendConsoleMessage( "100% of scripts run" );
                            }
                            else if ( currentPercentile >= scriptNextConsolePercentile )
                            {
                                this.SendConsoleMessage( currentPercentile + "% of scripts run" );
                                scriptNextConsolePercentile = currentPercentile + consoleMessageReportFrequency;
                            }
                        }

                        // update progress bar
                        if ( progressbarEventFrequency != 0 )
                        {
                            if ( sqlScriptCount == scriptsRun )
                            {
                                this.UpdateProgressBar( (int)(100 * (percentOfStep * .01)) + startPercent );
                            }
                            else if ( currentPercentile >= scriptNextProgressbarPercentile )
                            {
                                this.UpdateProgressBar( (int)(currentPercentile * (percentOfStep * .01)) + startPercent );
                                scriptNextProgressbarPercentile = currentPercentile + progressbarEventFrequency;
                            }
                        }
                    }

                    transaction.Commit();
                }
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message + " Current Script: " + currentScript;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }

            return result;
        }
예제 #2
0
        private void ReportInstallData( InstallData installData )
        {
            this.SendConsoleMessage( new ConsoleMessage( "--= Install Data =--", ConsoleMessageType.Highlight ) );

            this.SendConsoleMessage( new ConsoleMessage( "Installer Properties", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Installer Version: {0}", installData.InstallerProperties.InstallVersion ) );

            this.SendConsoleMessage( new ConsoleMessage( "Connection String", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Server: {0}", installData.ConnectionString.Server ) );
            this.SendConsoleMessage( String.Format( "Database: {0}", installData.ConnectionString.Database ) );
            this.SendConsoleMessage( String.Format( "Username: {0}", installData.ConnectionString.Username ) );
            this.SendConsoleMessage( String.Format( "Password: {0}", "*****"));

            this.SendConsoleMessage( new ConsoleMessage( "Admin User", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Username: {0}", installData.AdminUser.Username ) );
            this.SendConsoleMessage( String.Format( "Password: {0}", "***** (Ha! Good one...)" ) );

            this.SendConsoleMessage( new ConsoleMessage( "Organization Info", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Name: {0}", installData.Organization.Name ) );
            this.SendConsoleMessage( String.Format( "Email: {0}", installData.Organization.Email ) );
            this.SendConsoleMessage( String.Format( "Phone: {0}", installData.Organization.Phone ) );
            this.SendConsoleMessage( String.Format( "Website: {0}", installData.Organization.Website ) );

            this.SendConsoleMessage( new ConsoleMessage( "Hosting Info", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Internal Url: {0}", installData.HostingInfo.InternalUrl ) );
            this.SendConsoleMessage( String.Format( "External Url: {0}", installData.HostingInfo.ExternalUrl ) );
            this.SendConsoleMessage( String.Format( "Timezone: {0}", installData.HostingInfo.Timezone + " (sounds like a nice place)" ) );

            this.SendConsoleMessage( new ConsoleMessage( "Email Settings", ConsoleMessageType.Highlight ) );
            this.SendConsoleMessage( String.Format( "Server: {0}", installData.EmailSettings.Server ) );
            this.SendConsoleMessage( String.Format( "Port: {0}", installData.EmailSettings.Port ) );
            this.SendConsoleMessage( String.Format( "Use SSL: {0}", installData.EmailSettings.UseSsl.ToString() ) );
            this.SendConsoleMessage( String.Format( "Relay Username: {0}", installData.EmailSettings.RelayUsername ) );
            this.SendConsoleMessage( String.Format( "Relay Password: {0}", "*****" ) );
        }
예제 #3
0
        private ActivityResult RunSql( InstallData installData, string sqlFile )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;
            SqlConnection conn = null;

            try
            {
                string sql = System.IO.File.ReadAllText( sqlFile );

                string connectionString = String.Format( "user id={0};password={1};server={2};Initial Catalog={3};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server, installData.ConnectionString.Database );
                conn = new SqlConnection( connectionString );
                conn.Open();

                SqlCommand command = new SqlCommand( sql, conn );
                command.ExecuteNonQuery();

            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }

            return result;
        }
예제 #4
0
        private ActivityResult DownloadSqlStep(InstallData installData)
        {
            ActivityResult result = new ActivityResult();

            this.SendConsoleMessage( new ConsoleMessage( "--= Download SQL Step =--", ConsoleMessageType.Highlight ) );

            string serverDir = baseStorageUrl + installData.InstallerProperties.InstallVersion;
            this.SendConsoleMessage( "Downloading file: " + serverDir + "/Data/" + sqlScripts );

            result = DownloadFile( serverDir + "/Data/" + sqlScripts, serverPath + @"\" + sqlScripts, 10, 1 );

            this.SendConsoleMessage( "File Download Complete!" );

            return result;
        }
예제 #5
0
        private ActivityResult InstallRockApp( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            // if we're not in development unzip the file, otherwise we'll fake it... (for that full experience)
            if ( !installData.InstallerProperties.IsDebug )
            {
                this.SendConsoleMessage( "Preparing to unzip the rock application file." );

                // unzip the rock zip
                result = UnzipFile( serverPath + @"\" + rockSource, serverPath + @"\rock", 10, 1, 100, 0 );

                this.SendConsoleMessage( "Unzip complete." );
            }
            else
            {
                // fake it...
                for ( int i = 0; i <= 100; i++ )
                {
                    UpdateProgressBar( i );
                    Thread.Sleep( 100 ); // nap time...
                }
            }

            return result;
        }
예제 #6
0
        private ActivityResult DownloadRockStep( InstallData installData )
        {
            ActivityResult result = new ActivityResult();

            this.SendConsoleMessage( new ConsoleMessage( "--= Download Rock Step =--", ConsoleMessageType.Highlight ) );

            string rockURL = baseStorageUrl + installData.InstallerProperties.InstallVersion;
            this.SendConsoleMessage( "Downloading file: " + rockURL + "/Data/" + rockSource );

            result = DownloadFile( rockURL + "/Data/" + rockSource, serverPath + @"\" + rockSource, 10, 1 );

            if ( result.Success )
            {
                this.SendConsoleMessage( "File Download Complete!" );
            }

            return result;
        }
예제 #7
0
        private ActivityResult CreateDatabase( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            this.SendConsoleMessage( new ConsoleMessage( "--= Creating Database =--", ConsoleMessageType.Highlight ) );

            // create database if needed
            if ( !RockEnvironmentChecks.CheckSqlDatabaseExists( installData.ConnectionString.Server, installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Database ) )
            {
                this.SendConsoleMessage( String.Format("Database {0} does not exist creating it.", installData.ConnectionString.Database) );

                string sql = String.Format("CREATE DATABASE [{0}]", installData.ConnectionString.Database);

                string connectionString = String.Format( "user id={0};password={1};server={2};connection timeout=10", installData.ConnectionString.Username, installData.ConnectionString.Password, installData.ConnectionString.Server );
                SqlConnection conn = new SqlConnection( connectionString );

                try
                {
                    conn.Open();
                    SqlCommand command = new SqlCommand( sql, conn );
                    command.ExecuteNonQuery();
                    this.SendConsoleMessage( String.Format("Database {0} created successfully.", installData.ConnectionString.Database) );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                }
            }
            else
            {
                this.SendConsoleMessage( String.Format( "Database {0} exists, will attempt to install using it.", installData.ConnectionString.Database ) );
            }

            // tease the user with a little progress
            this.UpdateProgressBar( 10 );

            // unzip sql files
            if ( result.Success )
            {
                this.SendConsoleMessage( "Unziping file: " + sqlScripts );
                string sqlZipFile = serverPath + @"\" + sqlScripts;
                result = UnzipFile( sqlZipFile, serverPath, 10, 1, 30, 10 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( String.Format( "{0} sucessfully unzipped.", sqlScripts ) );
                }
            }

            // run sql install
            if ( result.Success )
            {
                this.SendConsoleMessage( "Preparing to run sql-install.sql" );

                result = RunSqlScript( installData, serverPath + @"\sql-install.sql", 10, 1, 60, 40 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( String.Format( "Successfully ran sql-install.sql." ) );
                }
            }

            return result;
        }
예제 #8
0
        private ActivityResult ConfigureRock( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            string tempWebConfig = serverPath + @"\webconfig.xml";

            this.SendConsoleMessage( new ConsoleMessage( "--= Configuring Rock =--", ConsoleMessageType.Highlight ) );

            string passwordKey = RockInstallUtilities.GeneratePasswordKey();

            // write connection string file
            result = WriteConnectionStringFile( installData.ConnectionString.Server, installData.ConnectionString.Database, installData.ConnectionString.Username, installData.ConnectionString.Password );
            if ( result.Success )
            {
                this.UpdateProgressBar( 20 );
                this.SendConsoleMessage( String.Format( "Successfully created web.ConnectionString.config." ) );
            }

            // create and run custom sql config
            if ( result.Success )
            {
                // download configure script
                string urlSqlConfigScript = baseStorageUrl + installData.InstallerProperties.InstallVersion + "/Data/" + sqlConfigureScript;
                string localSqlConfigScript = serverPath + @"\" + sqlConfigureScript;

                this.SendConsoleMessage( "Downloading SQL configuration script." );
                result = this.DownloadFile( urlSqlConfigScript, localSqlConfigScript, 0, 0 );

                if ( result.Success )
                {
                    this.SendConsoleMessage( "SQL configuration script downloaded." );

                    // merge settings
                    this.SendConsoleMessage( "Merging values into SQL config script." );
                    string sqlScript = System.IO.File.ReadAllText( localSqlConfigScript );
                    sqlScript = sqlScript.Replace( "{AdminPassword}", RockInstallUtilities.EncodePassword( installData.AdminUser.Password, "7E10A764-EF6B-431F-87C7-861053C84131", passwordKey ) );
                    sqlScript = sqlScript.Replace( "{AdminUsername}", SqlClean(installData.AdminUser.Username) );
                    sqlScript = sqlScript.Replace( "{PublicAppRoot}", RockInstallUtilities.CleanBaseAddress( installData.HostingInfo.ExternalUrl ) );
                    sqlScript = sqlScript.Replace( "{PublicAppSite}", RockInstallUtilities.GetDomainFromString( installData.HostingInfo.ExternalUrl ) );
                    sqlScript = sqlScript.Replace( "{InternalAppRoot}", RockInstallUtilities.CleanBaseAddress( installData.HostingInfo.InternalUrl ) );
                    sqlScript = sqlScript.Replace( "{InternalAppSite}", RockInstallUtilities.GetDomainFromString( installData.HostingInfo.InternalUrl ) );
                    sqlScript = sqlScript.Replace( "{OrgName}", SqlClean(installData.Organization.Name ));
                    sqlScript = sqlScript.Replace( "{OrgPhone}", SqlClean(installData.Organization.Phone ));
                    sqlScript = sqlScript.Replace( "{OrgEmail}", SqlClean(installData.Organization.Email ));
                    sqlScript = sqlScript.Replace( "{OrgWebsite}", SqlClean(installData.Organization.Website ));
                    sqlScript = sqlScript.Replace( "{SafeSender}", RockInstallUtilities.GetDomainFromEmail( installData.Organization.Email ) );
                    sqlScript = sqlScript.Replace( "{EmailException}", SqlClean(installData.Organization.Email ));
                    sqlScript = sqlScript.Replace( "{SmtpServer}", SqlClean(installData.EmailSettings.Server) );
                    sqlScript = sqlScript.Replace( "{SmtpPort}", installData.EmailSettings.Port );
                    sqlScript = sqlScript.Replace( "{SmtpUser}", SqlClean(installData.EmailSettings.RelayUsername ));
                    sqlScript = sqlScript.Replace( "{SmtpPassword}", SqlClean( installData.EmailSettings.RelayPassword ) );
                    sqlScript = sqlScript.Replace( "{SmtpUseSsl}", installData.EmailSettings.UseSsl.ToString() );

                    System.IO.File.WriteAllText( localSqlConfigScript, sqlScript );

                    this.SendConsoleMessage( "Values merged into SQL config script." );

                    // run sql configure script
                    this.SendConsoleMessage( "Running SQL config script." );
                    result = this.RunSql( installData, localSqlConfigScript );

                    if ( result.Success )
                    {
                        this.SendConsoleMessage( "Successfully ran SQL config script." );
                        this.UpdateProgressBar( 40 );
                    }
                    else
                    {
                        return result;
                    }
                }
            }

            // extract web.config
            string rockZipFile = serverPath + @"\" + rockSource;
            if ( result.Success )
            {
                this.SendConsoleMessage( "Extracting web.config file for edits." );

                try
                {
                    using ( FileStream fsZipFile = File.Create( tempWebConfig ) )
                    {
                        using ( ZipFile zip = ZipFile.Read( rockZipFile ) )
                        {
                            ZipEntry webConfigEntry = zip["web.config"];
                            webConfigEntry.Extract( fsZipFile );

                            // remove file from zip
                            zip.RemoveEntry( "web.config" );
                            zip.Save();
                        }
                    }

                    this.SendConsoleMessage( "Extracted web.config to webconfig.xml." );
                    this.UpdateProgressBar( 60 );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
            }

            try
            {
                // edit web.config
                XDocument document = XDocument.Load( tempWebConfig );

                // update timezone
                var node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "OrgTimeZone" ).FirstOrDefault();
                node.SetAttributeValue( "value", installData.HostingInfo.Timezone );

                // update password key
                node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "PasswordKey" ).FirstOrDefault();
                node.SetAttributeValue( "value", passwordKey );

                // update data encryption key
                string dataEncryptionKey = RockInstallUtilities.GeneratePasswordKey( 128 );
                node = document.Descendants( "appSettings" ).Elements( "add" ).Where( e => e.Attribute( "key" ).Value == "DataEncryptionKey" ).FirstOrDefault();
                node.SetAttributeValue( "value", dataEncryptionKey );

                // update machine key
                string validationKey = RockInstallUtilities.GenerateMachineKey( 64 );
                string decryptionKey = RockInstallUtilities.GenerateMachineKey( 32 );
                node = document.Descendants( "system.web" ).Elements( "machineKey" ).FirstOrDefault();
                node.SetAttributeValue( "validationKey", validationKey );
                node.SetAttributeValue( "decryptionKey", decryptionKey );

                document.Save( tempWebConfig );
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = "An error occurred while customizing the web.config file for Rock. " + ex.Message;
            }

            this.UpdateProgressBar( 100 );
            return result;
        }
예제 #9
0
        // starts the install process
        public void StartInstall(InstallData installData)
        {
            ReportServerInfo();
            ReportInstallData(installData);

            // download sql file
            ActivityResult result = DownloadSqlStep( installData );
            if ( !result.Success ) {
                this.SendConsoleMessage( new ConsoleMessage( "Error downloading SQL file:" + result.Message, ConsoleMessageType.Critical ) );
                this.ReportError( String.Format( "<div class='alert alert-danger'><strong>That Wasn't Suppose To Happen</strong> An error occurred in the downloading of Rock's SQL files. Message: {0}</div>", result.Message ) );
                return;
            }

            Thread.Sleep( 1000 ); // slow the process to let progress bars catchup

            // download rock
            UpdateStep( "step-downloadsql", "Step 2: Downloading Rock" );

            result = DownloadRockStep( installData );
            if ( !result.Success )
            {
                this.SendConsoleMessage( new ConsoleMessage( "Error downloading Rock file:" + result.Message, ConsoleMessageType.Critical ) );
                this.ReportError( String.Format( "<div class='alert alert-danger'><strong>That Wasn't Suppose To Happen</strong> An error occurred in the downloading of Rock. Message: {0}</div>", result.Message ) );
                return;
            }

            Thread.Sleep( 1000 ); // slow the process to let progress bars catchup

            // create database
            UpdateStep( "step-downloadrock", "Step 3: Creating Database" );

            result = CreateDatabase( installData );
            if ( !result.Success )
            {
                this.SendConsoleMessage( new ConsoleMessage( "Error creating database:" + result.Message, ConsoleMessageType.Critical ) );
                this.ReportError( String.Format( "<div class='alert alert-danger'><strong>That Wasn't Suppose To Happen</strong> An error occurred creating database. Message: {0}</div>", result.Message ) );
                return;
            }

            Thread.Sleep( 1000 ); // slow the process to let progress bars catchup

            // configuring rock
            UpdateStep( "step-sql", "Step 4: Configuring Rock" );

            result = ConfigureRock( installData );
            if (!result.Success) {
                this.SendConsoleMessage( new ConsoleMessage( "Error configuring Rock:" + result.Message, ConsoleMessageType.Critical ) );
                this.ReportError( String.Format( "<div class='alert alert-danger'><strong>That Wasn't Suppose To Happen</strong> An error occurred while configuring Rock. Message: {0}</div>", result.Message ) );
                return;
            }

            Thread.Sleep( 1000 ); // slow the process to let progress bars catchup

            // unzip rock
            UpdateStep( "step-configure", "Step 5: Installing Rock Application" );

            result = InstallRockApp( installData );
            if ( !result.Success )
            {
                this.SendConsoleMessage( new ConsoleMessage( "Error installing Rock application:" + result.Message, ConsoleMessageType.Critical ) );
                this.ReportError( String.Format( "<div class='alert alert-danger'><strong>That Wasn't Suppose To Happen</strong> An error occurred while installing the Rock application.  At this point you may need to delete all files off of the web server and recreate the database once you address the error. Message: {0}</div>", result.Message ) );
                return;
            }

            Thread.Sleep( 1000 ); // slow the process to let progress bars catchup

            // redirect to the final complete page
            this.RedirectToComplete();
        }
예제 #10
0
        private ActivityResult DeleteInstaller( InstallData installData )
        {
            ActivityResult result = new ActivityResult();
            result.Success = true;

            // let's not delete the installer if we're in development, source control is nice but no use pressing our luck...
            if ( !installData.InstallerProperties.IsDebug )
            {

                try
                {
                    File.Delete( serverPath + @"Start.aspx" );
                    File.Delete( serverPath + @"Install.aspx" );
                    File.Delete( serverPath + @"InstallController.cs" );
                    File.Delete( serverPath + @"Startup.cs" );

                    File.Delete( serverPath + @"bin\Microsoft.AspNet.SignalR.Core.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.AspNet.SignalR.SystemWeb.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.Host.SystemWeb.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.Owin.Security.dll" );
                    File.Delete( serverPath + @"bin\Owin.dll" );

                    File.Delete( serverPath + @"bin\Ionic.Zip.dll" );
                    File.Delete( serverPath + @"bin\Microsoft.ApplicationBlocks.Data.dll" );
                    File.Delete( serverPath + @"bin\RockInstaller.dll" );
                    File.Delete( serverPath + @"bin\RockInstallTools.dll" );
                    File.Delete( serverPath + @"bin\Subtext.Scripting.dll" );
                }
                catch ( Exception ex )
                {
                    result.Success = false;
                    result.Message = ex.Message;
                }
            }
            else
            {
                // if it is a debug session let's do delete the connection string file
                File.Delete( serverPath + @"web.ConnectionStrings.config" );
            }

            // these files should be deleted even in the developer environment
            try
            {
                File.Delete( serverPath + @"\rock-install-latest.zip" );
                File.Delete( serverPath + @"\sql-config.sql" );
                File.Delete( serverPath + @"\sql-install.sql" );
                File.Delete( serverPath + @"\sql-latest.zip" );
                File.Delete( serverPath + @"\webconfig.xml" );
            }
            catch ( Exception ex )
            {
                result.Success = false;
                result.Message = ex.Message;
            }

            return result;
        }