diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..4a291b8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,17 @@
+We welcome your code contributions. Before submitting code via a GitHub pull
+request, or by filing a bug in https://bugs.mysql.com you will need to have
+signed the Oracle Contributor Agreement (see https://oca.opensource.oracle.com).
+
+Only pull requests from committers that can be verified as having signed the OCA
+can be accepted.
+
+# Submitting a contribution
+
+1. Make sure you have a user account at bugs.mysql.com. You'll need to reference this
+ user account when you submit your OCA (Oracle Contributor Agreement).
+2. Sign the Oracle OCA. You can find instructions for doing that at the OCA Page.
+ at https://oca.opensource.oracle.com
+3. Validate your contribution by including tests that sufficiently cover the functionality.
+4. Verify that the entire test suite passes with your code applied.
+5. Submit your pull request via GitHub or uploading it using the contribution tab to a bug
+ record in https://bugs.mysql.com (using the 'contribution' tab.
\ No newline at end of file
diff --git a/Configurator/Core/Classes/ExtensionMethods.cs b/Configurator/Core/Classes/ExtensionMethods.cs
index 65649cb..0163052 100644
--- a/Configurator/Core/Classes/ExtensionMethods.cs
+++ b/Configurator/Core/Classes/ExtensionMethods.cs
@@ -1102,6 +1102,207 @@ public static bool ServerSupportsCachingSha2Authentication(this Version serverVe
return serverVersion >= new Version("8.0.4");
}
+ ///
+ /// Checks if the LTS versions are consecutive.
+ ///
+ /// The version to which the upgrade will be made to.
+ /// The version of the existing server instance.
+ /// The maturity of the version to which the upgrade will be made to.
+ /// The maturity of the version of the existing server instance.
+ /// true if the validation has been met; otherwise, false.
+ public static bool IsFromLtsToNextLts(this Version newVersion, Version oldVersion, ServerMaturity newVersionMaturity, ServerMaturity oldVersionMaturity)
+ {
+ if (newVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (oldVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (newVersionMaturity != ServerMaturity.LTS
+ || oldVersionMaturity != ServerMaturity.LTS)
+ {
+ return false;
+ }
+
+ if ((oldVersion.Major == 8
+ && oldVersion.Minor == 0
+ && oldVersion.Build >=35
+ && newVersion.Major == 8
+ && newVersion.Minor == 4)
+ || (oldVersion.Major == 8
+ && oldVersion.Minor == 4
+ && newVersion.Major == 9
+ && newVersion.Minor == 7))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks if an LTS version is being upgraded to an innovation release that comes before
+ /// the next LTS.
+ ///
+ /// The version to which the upgrade will be made to.
+ /// The version of the existing server instance.
+ /// The maturity of the version to which the upgrade will be made to.
+ /// The maturity of the version of the existing server instance.
+ /// true if the validation has been met; otherwise, false.
+ public static bool IsFromLtsToInnovationBeforeNextLts(this Version newVersion, Version oldVersion, ServerMaturity newVersionMaturity, ServerMaturity oldVersionMaturity)
+ {
+ if (newVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (oldVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (newVersionMaturity != ServerMaturity.Innovation
+ || oldVersionMaturity != ServerMaturity.LTS)
+ {
+ return false;
+ }
+
+ if ((oldVersion.Major == 8
+ && oldVersion.Minor == 0
+ && oldVersion.Build >= 35
+ && newVersion.Major == 8
+ && newVersion.Minor < 4)
+ ||(oldVersion.Major == 8
+ && oldVersion.Minor == 4
+ && newVersion.Major == 9
+ && newVersion.Minor < 7))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks if an innovation release is being upgaded to the next LTS.
+ ///
+ /// The version to which the upgrade will be made to.
+ /// The version of the existing server instance.
+ /// The maturity of the version to which the upgrade will be made to.
+ /// The maturity of the version of the existing server instance.
+ /// true if the validation has been met; otherwise, false.
+ public static bool IsFromInnovationToNextLts(this Version newVersion, Version oldVersion, ServerMaturity newVersionMaturity, ServerMaturity oldVersionMaturity)
+ {
+ if (newVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (oldVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (newVersionMaturity != ServerMaturity.LTS
+ || oldVersionMaturity != ServerMaturity.Innovation)
+ {
+ return false;
+ }
+
+ if ((oldVersion.Major == 8
+ && oldVersion.Minor <= 3
+ && newVersion.Major == 8
+ && newVersion.Minor == 4)
+ || (((oldVersion.Major == 8
+ && oldVersion.Minor > 4)
+ || (oldVersion.Major == 9
+ && oldVersion.Minor < 7))
+ && newVersion.Major == 9
+ && newVersion.Minor == 7))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks if both versions are within the same innovation release series.
+ ///
+ /// The version to which the upgrade will be made to.
+ /// The version of the existing server instance.
+ /// The maturity of the version to which the upgrade will be made to.
+ /// The maturity of the version of the existing server instance.
+ /// true if the validation has been met; otherwise, false.
+ public static bool IsWithinSameInnovationSeries(this Version newVersion, Version oldVersion, ServerMaturity newVersionMaturity, ServerMaturity oldVersionMaturity)
+ {
+ if (newVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (oldVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (newVersionMaturity != ServerMaturity.Innovation
+ || oldVersionMaturity != ServerMaturity.Innovation)
+ {
+ return false;
+ }
+
+ if (oldVersion.Major == newVersion.Major
+ && ((oldVersion.Major == 8
+ && oldVersion.Minor < 4)
+ || (oldVersion.Major == 9
+ && oldVersion.Minor < 7)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks if both versions are within the same LTS.
+ ///
+ /// The version to which the upgrade will be made to.
+ /// The version of the existing server instance.
+ /// The maturity of the version to which the upgrade will be made to.
+ /// The maturity of the version of the existing server instance.
+ /// true if the validation has been met; otherwise, false.
+ public static bool IsWithinSameLts(this Version newVersion, Version oldVersion, ServerMaturity newVersionMaturity, ServerMaturity oldVersionMaturity)
+ {
+ if (newVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (oldVersion == null)
+ {
+ throw new ArgumentNullException(nameof(oldVersion));
+ }
+
+ if (newVersionMaturity != ServerMaturity.LTS
+ || oldVersionMaturity != ServerMaturity.LTS)
+ {
+ return false;
+ }
+
+ if (oldVersion.Major == newVersion.Major
+ && oldVersion.Minor == newVersion.Minor)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
///
/// Validates if the specified server version supports an in-place upgrade based on the rules outlined by the new versioning scheme.
///
@@ -1143,44 +1344,16 @@ public static UpgradeViability ServerSupportsInPlaceUpgrades(this Version newVer
return UpgradeViability.Unsupported;
}
else if (
- // If 8.0.X to 8.Y Innovation. X>=35, Y=1
- (oldVersionMaturity == ServerMaturity.Older
- && oldVersion >= new Version(8, 0, 35)
- && newVersionMaturiy == ServerMaturity.Innovation
- && newVersion.Major == 8
- && newVersion.Minor == 1)
- // If 8.0.X to 8.4 LTS. X>=35
- || (oldVersionMaturity == ServerMaturity.Older
- && oldVersion >= new Version(8, 0, 35)
- && newVersionMaturiy == ServerMaturity.LTS
- && newVersion.Major == 8
- && newVersion.Minor == 4)
- // Upgrade from innovation to next innovation. 8.X.0 to 8.Y.0 innovation. Y = X + 1
- // E.g. 8.2.0 to 8.3.0
- || (oldVersionMaturity == ServerMaturity.Innovation
- && newVersionMaturiy == ServerMaturity.Innovation
- && oldVersion.Major == newVersion.Major
- && oldVersion.Minor + 1 == newVersion.Minor
- && oldVersion.Build == 0
- && newVersion.Build == 0)
- // Upgrade from last innovation release to next LTS. E.g. 8.3.0 Innovation to 8.4.0 LTS
- || (oldVersionMaturity == ServerMaturity.Innovation
- && newVersionMaturiy == ServerMaturity.LTS
- && oldVersion.Minor + 1 == newVersion.Minor
- && newVersion.Build == 0)
- // Upgrade within same LTS. E.g 8.4.X LTS to 8.4.Y LTS
- || (oldVersionMaturity == ServerMaturity.LTS
- && newVersionMaturiy == ServerMaturity.LTS
- && oldVersion.Major == newVersion.Major
- && oldVersion.Minor == newVersion.Minor)
- // Upgrade from one LTS to the next innovation release. E.g. 8.4.X LTS to 9.0.0 Innovation
- || (oldVersionMaturity == ServerMaturity.LTS
- && newVersionMaturiy == ServerMaturity.Innovation
- && newVersion == new Version(oldVersion.Major + 1, 0, 0))
- // Upgrade from one LTS to the next LTS. E.g. 8.4.X LTS to 9.7.Y LTS
- || (oldVersionMaturity == ServerMaturity.LTS
- && newVersionMaturiy == ServerMaturity.LTS
- && oldVersion.Major + 1 == newVersion.Major))
+ // Within an LTS. E.g 8.4.X LTS to 8.4.Y LTS.
+ IsWithinSameLts(newVersion, oldVersion, newVersionMaturiy, oldVersionMaturity)
+ // From an LTS to the next LTS series.
+ || IsFromLtsToNextLts(newVersion, oldVersion, newVersionMaturiy, oldVersionMaturity)
+ // From an LTS to an innovation release before the next LTS series.
+ || IsFromLtsToInnovationBeforeNextLts(newVersion, oldVersion, newVersionMaturiy, oldVersionMaturity)
+ // From an innovation series to the next LTS series.
+ || IsFromInnovationToNextLts(newVersion, oldVersion, newVersionMaturiy, oldVersionMaturity)
+ // From within an innovation series.
+ || IsWithinSameInnovationSeries(newVersion, oldVersion, newVersionMaturiy, oldVersionMaturity))
{
return UpgradeViability.Supported;
}
diff --git a/Configurator/Core/Classes/MySqlUpgradeHistoryManager.cs b/Configurator/Core/Classes/MySqlUpgradeHistoryManager.cs
new file mode 100644
index 0000000..50bc0c4
--- /dev/null
+++ b/Configurator/Core/Classes/MySqlUpgradeHistoryManager.cs
@@ -0,0 +1,135 @@
+/* Copyright (c) 2024, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0, as
+ published by the Free Software Foundation.
+
+ This program is designed to work with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms, as
+ designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have either included with
+ the program or referenced in the documentation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+using MySql.Configurator.Core.Classes.Logging;
+using MySql.Configurator.Core.Common;
+using MySql.Configurator.Core.Enums;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Web.Script.Serialization;
+
+namespace MySql.Configurator.Core.Classes
+{
+ ///
+ /// Handles the reading the mysql_upgrade_history server json file.
+ ///
+ public static class MySqlUpgradeHistoryManager
+ {
+ #region Constants
+
+ ///
+ /// The name of the ugprade history file.
+ ///
+ public const string UPGRADE_HISTORY_FILE_NAME = "mysql_upgrade_history";
+
+ #endregion
+
+ ///
+ /// Loads the specified upgrade history file.
+ ///
+ /// The directory path where the MySQL upgrade history file is located.
+ /// A tuple containing the version for the latest entry as well as a flag indicating
+ /// if the version is appended with a metadata string.
+ public static (Version, bool) GetUpgradeHistoryLatestVersion(string mysqlUpgradeHistoryFilePath)
+ {
+ if (string.IsNullOrEmpty(mysqlUpgradeHistoryFilePath))
+ {
+ throw new ArgumentNullException(nameof(mysqlUpgradeHistoryFilePath));
+ }
+
+ var filePath = Path.Combine(mysqlUpgradeHistoryFilePath, "Data", UPGRADE_HISTORY_FILE_NAME);
+ if (!File.Exists(filePath))
+ {
+ Logger.LogException(new FileNotFoundException(filePath));
+ return (null, false);
+ }
+
+ try
+ {
+ MySqlUpgradeHistory upgradeHistory;
+ using (StreamReader reader = new StreamReader(filePath))
+ {
+ var jsonString = reader.ReadToEnd();
+ var serializer = new JavaScriptSerializer();
+ upgradeHistory = serializer.Deserialize(jsonString);
+ }
+
+ if (upgradeHistory.Upgrade_History.Count == 0)
+ {
+ throw new ConfiguratorException(ConfiguratorError.UpgradeHistoryElementsNotFound);
+ }
+
+ var latestEntry = upgradeHistory.Upgrade_History.OrderByDescending(o => DateTime.Parse(o.Date)).First();
+ var versionItems = latestEntry.Version.Split('-');
+ var version = new Version(versionItems[0]);
+ return (version, versionItems.Length > 1);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogException(ex);
+ return (null, false);
+ }
+ }
+ }
+
+ ///
+ /// The upgrade history of a MySQL Server instance.
+ /// Represents the root element of the mysql_upgrade_history server file.
+ ///
+ public class MySqlUpgradeHistory
+ {
+ ///
+ /// Gets or sets the file format version number.
+ ///
+ public string File_Format { get; set; }
+ ///
+ /// Gets or sets a list containing the upgrade history.
+ ///
+ public List Upgrade_History { get; set; }
+ }
+
+ ///
+ /// Contains historical upgrade details for a MySQL Server instance.
+ ///
+ public class UpgradeHistory
+ {
+ ///
+ /// Gets or sets a value indicating the date of the upgrade.
+ ///
+ public string Date { get; set; }
+ ///
+ /// Gets or sets a value indicating the version number of the server instance.
+ ///
+ public string Version { get; set; }
+ ///
+ /// Gets or sets a value indicating the maturity (LTS or innovation) of the server instance..
+ ///
+ public string Maturity { get; set; }
+ ///
+ /// Gets or sets a value indicating if the data directory was initialized.
+ ///
+ public bool Initialize { get; set; }
+ }
+}
diff --git a/Configurator/Core/Classes/Utilities.cs b/Configurator/Core/Classes/Utilities.cs
index fb0d55e..5ea89fc 100644
--- a/Configurator/Core/Classes/Utilities.cs
+++ b/Configurator/Core/Classes/Utilities.cs
@@ -1106,9 +1106,7 @@ public static DataTable GetSchemaInformation(string connectionString, SchemaInfo
///
public static ServerMaturity GetServerMaturity(Version version)
{
- if (version.Major < 8
- || (version.Major == 8
- && version.Minor == 0))
+ if (version.Major < 8)
{
return ServerMaturity.Older;
}
diff --git a/Configurator/Core/Common/GeneralSettings.cs b/Configurator/Core/Common/GeneralSettings.cs
index f9409bb..8f797ed 100644
--- a/Configurator/Core/Common/GeneralSettings.cs
+++ b/Configurator/Core/Common/GeneralSettings.cs
@@ -22,6 +22,7 @@ You should have received a copy of the GNU General Public License
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
using MySql.Configurator.Core.Classes.Logging;
+using MySql.Configurator.Core.Enums;
using MySql.Configurator.Properties;
using System;
using System.IO;
@@ -52,6 +53,11 @@ public class GeneralSettings
///
public string IniDirectory { get; set; }
+ ///
+ /// Gets or sets the server installation type selected during a Server's configuration
+ ///
+ public ServerInstallationType ServerInstallationType { get; set; }
+
#endregion
}
diff --git a/Configurator/Core/Controllers/BaseServerSettings.cs b/Configurator/Core/Controllers/BaseServerSettings.cs
index fb595c8..c32be29 100644
--- a/Configurator/Core/Controllers/BaseServerSettings.cs
+++ b/Configurator/Core/Controllers/BaseServerSettings.cs
@@ -30,7 +30,10 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Core.Classes.Forms;
using MySql.Configurator.Core.Classes.Logging;
using MySql.Configurator.Core.Common;
+using MySql.Configurator.Core.Dialogs;
+using MySql.Configurator.Core.Enums;
using MySql.Configurator.Core.IniFile;
+using MySql.Configurator.Dialogs;
using MySql.Configurator.Properties;
using static MySql.Configurator.Core.Classes.Forms.InfoDialog;
@@ -136,7 +139,9 @@ public bool GeneralPropertiesChanged
}
[XmlIgnore]
- public string FullConfigFilePath => Path.Combine(IniDirectory, ConfigFile);
+ public string FullConfigFilePath => !string.IsNullOrEmpty(IniDirectory)
+ ? Path.Combine(IniDirectory, ConfigFile)
+ : null;
public string IniDirectory { get; set; }
@@ -248,11 +253,16 @@ public void FindConfigFile()
var foundConfigFile = false;
string[] configFileNames = new string[2] { DEFAULT_CONFIG_FILE_NAME, ALTERNATE_CONFIG_FILE_NAME };
- string[] possibleConfigFileLocations = new string[2] { DataDirectory, InstallDirectory };
+ string[] possibleConfigFileLocations = new string[3] { DataDirectory, InstallDirectory, IniDirectory };
foreach (var configFileName in configFileNames)
{
foreach (var directory in possibleConfigFileLocations)
{
+ if (string.IsNullOrEmpty(directory))
+ {
+ continue;
+ }
+
if (!File.Exists(Path.Combine(directory, configFileName)))
{
continue;
@@ -261,6 +271,7 @@ public void FindConfigFile()
ConfigFile = configFileName;
IniDirectory = directory;
foundConfigFile = true;
+ break;
}
if (foundConfigFile)
@@ -304,20 +315,39 @@ public virtual void LoadGeneralSettings()
if (!string.IsNullOrEmpty(_generalSettings.IniDirectory))
{
var iniFilePath = Path.Combine(_generalSettings.IniDirectory, BaseServerSettings.DEFAULT_CONFIG_FILE_NAME);
- if (File.Exists(iniFilePath))
+ var alternateIniFilePath = Path.Combine(_generalSettings.IniDirectory, BaseServerSettings.ALTERNATE_CONFIG_FILE_NAME);
+ var iniFileExists = File.Exists(iniFilePath);
+ var alternateIniFileExists = File.Exists(alternateIniFilePath);
+ if (!iniFileExists
+ && !alternateIniFileExists)
{
- // Load and parse ini file to get the data dir path.
- var iniFile = new IniFileEngine(iniFilePath).Load();
- var dataDirectory = iniFile.FindValue("mysqld", "datadir", false);
- if (!string.IsNullOrEmpty(dataDirectory)
- && Directory.Exists(dataDirectory))
+ using (var configurationFileDialog = new ConfigurationFileDialog())
{
- var parentDirectory = Directory.GetParent(dataDirectory);
- DataDirectory = parentDirectory != null
- ? parentDirectory.FullName
- : dataDirectory;
+ if (configurationFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ _generalSettings.IniDirectory = configurationFileDialog.ConfigurationFilePath;
+ }
+ else
+ {
+ throw new ConfiguratorException(ConfiguratorError.ConfigurationFileNotFound, _generalSettings.IniDirectory);
+ }
}
}
+
+ // Load and parse ini file to get the data dir path.
+ var path = iniFileExists
+ ? iniFilePath
+ : alternateIniFilePath;
+ var iniFile = new IniFileEngine(path).Load();
+ var dataDirectory = iniFile.FindValue("mysqld", "datadir", false);
+ if (!string.IsNullOrEmpty(dataDirectory)
+ && Directory.Exists(dataDirectory))
+ {
+ var parentDirectory = Directory.GetParent(dataDirectory);
+ DataDirectory = parentDirectory != null
+ ? parentDirectory.FullName
+ : dataDirectory;
+ }
}
this.SetPropertyValuesFrom(_generalSettings);
diff --git a/Configurator/Core/Controllers/ExtendedServerSettings.cs b/Configurator/Core/Controllers/ExtendedServerSettings.cs
deleted file mode 100644
index 988d2d7..0000000
--- a/Configurator/Core/Controllers/ExtendedServerSettings.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 2.0, as
- published by the Free Software Foundation.
-
- This program is designed to work with certain software (including
- but not limited to OpenSSL) that is licensed under separate terms, as
- designated in a particular file or component or in included license
- documentation. The authors of MySQL hereby grant you an additional
- permission to link the program and your derivative works with the
- separately licensed software that they have either included with
- the program or referenced in the documentation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License, version 2.0, for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Xml.Serialization;
-using MySql.Configurator.Core.Classes;
-using MySql.Configurator.Core.Classes.Logging;
-using MySql.Configurator.Core.Enums;
-
-namespace MySql.Configurator.Core.Controllers
-{
- ///
- /// Represents Server configuration values not stored in the Server's configuration file.
- ///
- [Serializable]
- public class ExtendedServerSettings
- {
- #region Properties
-
- ///
- /// Gets or sets a value indicating whether the Server is configured as a Service.
- ///
- public bool ConfigureAsService { get; set; }
-
- ///
- /// Gets or sets a value indicating if the Enterprise Firewall is enabled.
- ///
- public bool EnterpriseFirewallEnabled { get; set; }
-
- ///
- /// Gets or sets a value indicating whether an upgrade to system tables is pending to be performed.
- ///
- public bool PendingSystemTablesUpgrade { get; set; }
-
- #endregion Properties
-
- ///
- /// Deserializes the class.
- ///
- /// The location where the serialized file is located.
- public static ExtendedServerSettings Deserialize(string filePath)
- {
- ExtendedServerSettings extendedSettings = null;
- try
- {
- var serializer = new XmlSerializer(typeof(ExtendedServerSettings));
- using (var stream = new FileStream(filePath, FileMode.Open))
- {
- extendedSettings = (ExtendedServerSettings)serializer.Deserialize(stream);
- }
- }
- catch (Exception ex)
- {
- Logger.LogException(ex);
- }
-
- return extendedSettings;
- }
-
- ///
- /// Serializes the class.
- ///
- /// The location where the serialized file will be output.
- /// true if the serialization was done successfully, false otherwise.
- public bool Serialize(string filePath)
- {
- bool success = true;
- try
- {
- var serializer = new XmlSerializer(typeof(ExtendedServerSettings));
- using (var myWriter = new StreamWriter(filePath, false))
- {
- serializer.Serialize(myWriter, this);
- myWriter.Close();
- }
- }
- catch (Exception ex)
- {
- success = false;
- Logger.LogException(ex);
- }
-
- return success;
- }
- }
-}
diff --git a/Configurator/Core/Controls/PasswordStrengthLabel.Designer.cs b/Configurator/Core/Controls/PasswordStrengthLabel.Designer.cs
index 8cc3bba..05aa028 100644
--- a/Configurator/Core/Controls/PasswordStrengthLabel.Designer.cs
+++ b/Configurator/Core/Controls/PasswordStrengthLabel.Designer.cs
@@ -76,7 +76,7 @@ private void InitializeComponent()
this.ValueLabel.Name = "ValueLabel";
this.ValueLabel.Size = new System.Drawing.Size(36, 13);
this.ValueLabel.TabIndex = 30;
- this.ValueLabel.Text = "Max";
+ this.ValueLabel.Text = "Weak";
//
// PasswordStrengthLabel
//
diff --git a/Configurator/Core/Enums/ConfiguratorError.cs b/Configurator/Core/Enums/ConfiguratorError.cs
index 716a6a5..3515615 100644
--- a/Configurator/Core/Enums/ConfiguratorError.cs
+++ b/Configurator/Core/Enums/ConfiguratorError.cs
@@ -43,9 +43,9 @@ public enum ConfiguratorError : uint
VersionNotFound = 1,
///
- /// Version not found.
+ /// Version mismatch.
///
- [Description("The version provided does not match with the one installed.")]
+ [Description("Version for the mysql.exe and mysql_configurator.exe do not match.")]
VersionMismatch = 2,
///
@@ -99,7 +99,28 @@ public enum ConfiguratorError : uint
///
/// Invalid execution mode.
///
- [Description("An invalid exeuction mode was provided.")]
+ [Description("An invalid execution mode was provided.")]
InvalidExecutionMode = 11,
+
+ ///
+ /// Upgrade history elements not found in the server's upgrade history file.
+ ///
+ [Description("No upgrade history elements found in the mysql_upgrade_history file.")]
+ UpgradeHistoryElementsNotFound = 12,
+
+ ///
+ /// The mysqld.exe was not found in the same directory as mysql_configurator.exe.
+ ///
+ [Description("mysqld.exe not found at: '{0}'.")]
+ MysqldExeNotFound = 13,
+
+ ///
+ /// The server configuration file was not found.
+ ///
+ [Description("Configuration file not found at: '{0}'")]
+ ConfigurationFileNotFound = 14,
+
+ [Description("Failed to update the authentication plugin of the root user.")]
+ AuthenticationPluginUpdateFailed = 15
}
}
diff --git a/Configurator/Core/Enums/ExecutionMode.cs b/Configurator/Core/Enums/ExecutionMode.cs
index 70444ce..b1ecb48 100644
--- a/Configurator/Core/Enums/ExecutionMode.cs
+++ b/Configurator/Core/Enums/ExecutionMode.cs
@@ -29,8 +29,8 @@ namespace MySql.Configurator.Core.Enums
public enum ExecutionMode : uint
{
///
- /// Execution mode in which a server installation is configured, either as a new configuration, a
- /// reconfiguration or an upgrade.
+ /// Execution mode in which a server installation is configured, either as a new configuration or a
+ /// reconfiguration.
///
Configure = 0,
///
@@ -42,5 +42,9 @@ public enum ExecutionMode : uint
/// the Configurator is automatically closed and a warning is added to the log.
///
RemoveNoShow = 2,
+ ///
+ /// Execution mode in which a server installation is upgraded.
+ ///
+ Upgrade = 3
}
}
diff --git a/Configurator/Core/Enums/ServerInstallationType.cs b/Configurator/Core/Enums/ServerInstallationType.cs
index b412eea..0653799 100644
--- a/Configurator/Core/Enums/ServerInstallationType.cs
+++ b/Configurator/Core/Enums/ServerInstallationType.cs
@@ -25,6 +25,7 @@ namespace MySql.Configurator.Core.Enums
{
public enum ServerInstallationType
{
+ None = 0,
Dedicated = 1,
Server = 2,
Developer = 3,
diff --git a/Configurator/Core/IniFile/Template/IniTemplate.cs b/Configurator/Core/IniFile/Template/IniTemplate.cs
index cbf4cf2..b36dff2 100644
--- a/Configurator/Core/IniFile/Template/IniTemplate.cs
+++ b/Configurator/Core/IniFile/Template/IniTemplate.cs
@@ -63,7 +63,7 @@ public IniTemplate(Version serverVersion, ServerInstallationType iniServerType)
SetDefaults();
InitializeDeprecatedServerVariables();
ServerVersion = serverVersion;
- ServerType = iniServerType;
+ ServerInstallationType = iniServerType;
}
///
@@ -164,7 +164,7 @@ public List DeprecatedVariablesForVersion
public string LogError { get; set; }
public string LogOutput { get; set; }
public string LongQueryTime { get; set; }
- public uint LooseMySqlXPort { get; set; }
+ public uint MySqlXPort { get; set; }
public LowerCaseTableNamesTypes LowerCaseTableNames { get; set; }
public string MemoryName { get; set; }
public double MyisamUsage { get; set; }
@@ -180,7 +180,7 @@ public List DeprecatedVariablesForVersion
public Version ServerVersion { get; }
- public ServerInstallationType ServerType
+ public ServerInstallationType ServerInstallationType
{
get
{
@@ -470,7 +470,7 @@ public void ProcessTemplate(bool isReconfigure = false, bool writeTemplate = tru
_formulaEngine.AssignFormulaVariable("bitedness", Win32.Is64BitOs ? "0" : "1");
_formulaEngine.AssignFormulaVariable("secure_file_priv", SecureFilePriv);
_formulaEngine.AssignFormulaVariable("plugin_load", PluginLoad);
- _formulaEngine.AssignFormulaVariable("loose_mysqlx_port", LooseMySqlXPort.ToString());
+ _formulaEngine.AssignFormulaVariable("mysqlx_port", MySqlXPort.ToString());
_formulaEngine.AssignFormulaVariable("named_pipe_full_access_group", NamedPipeFullAccessGroup);
// In this case we don't want the existing file to be replaced.
@@ -1086,7 +1086,7 @@ private void SetDefaults()
SkipInnodb = false;
IsValid = false;
OutputExists = false;
- ServerType = ServerInstallationType.Developer;
+ ServerInstallationType = ServerInstallationType.Developer;
LongQueryTime = "10";
NamedPipeFullAccessGroup = string.Empty;
@@ -1118,7 +1118,9 @@ private void InitializeDeprecatedServerVariables()
new DeprecatedServerVariable("innodbclusterport", ServerSeriesType.S57 | ServerSeriesType.S80),
new DeprecatedServerVariable("innodbclustertypeselection", ServerSeriesType.S57 | ServerSeriesType.S80),
new DeprecatedServerVariable("sync_master_info", new Version(8,0,26)),
- new DeprecatedServerVariable("sync_relay_log_info=", new Version(8,0,34))
+ new DeprecatedServerVariable("sync_relay_log_info=", new Version(8,0,34)),
+ new DeprecatedServerVariable("loose_mysqlx_port", ServerSeriesType.All),
+ new DeprecatedServerVariable("server_type", ServerSeriesType.All)
};
}
}
diff --git a/Configurator/Core/Wizard/WizardPage.cs b/Configurator/Core/Wizard/WizardPage.cs
index 4599e37..f70c873 100644
--- a/Configurator/Core/Wizard/WizardPage.cs
+++ b/Configurator/Core/Wizard/WizardPage.cs
@@ -27,6 +27,7 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Core.Classes;
using MySql.Configurator.Core.Classes.Logging;
using MySql.Configurator.Core.Interfaces;
+using Action = System.Action;
using Utilities = MySql.Configurator.Core.Classes.Utilities;
namespace MySql.Configurator.Core.Wizard
@@ -47,7 +48,6 @@ public WizardPage()
InitializeComponent();
ErrorProperties = ErrorProviderProperties.Empty;
ErrorLabel = null;
- WorkDone = false;
PageVisible = true;
DisabledControlShowingTooltip = null;
SkipUpdateButtons = false;
@@ -82,6 +82,11 @@ public string Caption
public virtual bool NextOk => Wizard.CanGoNext
&& !ValidationsErrorProvider.HasErrors();
+ ///
+ /// Gets or sets a value indicating that the page is busy executing an operation.
+ ///
+ public bool OperationExecuting { get; set; }
+
public bool PageVisible { get; set; }
public string SubCaption
@@ -96,12 +101,6 @@ public string SubCaption
public IWizard Wizard { get; set; }
- ///
- /// Property that can be used to signal that a panel has done all its work and there is no
- /// need to ask the user if he agrees when closing the application.
- ///
- public bool WorkDone { get; set; }
-
///
/// Gets or sets to use with the .
///
@@ -138,6 +137,7 @@ public string SubCaption
public virtual void Activate()
{
Logger.LogInformation($"Beginning {Name}.");
+ OperationExecuting = false;
}
public virtual bool Back()
@@ -145,6 +145,15 @@ public virtual bool Back()
return true;
}
+ ///
+ /// Executes prep work needed before a long running operation.
+ ///
+ public virtual void BeginLongRunningOperation()
+ {
+ Cursor = Cursors.WaitCursor;
+ OperationExecuting = true;
+ }
+
public virtual bool Cancel()
{
return true;
@@ -155,10 +164,45 @@ public virtual void Deactivate()
Logger.LogInformation($"Finished {Name}.");
}
+ ///
+ /// Executes post work needed after a long running operation.
+ ///
+ public virtual void EndLongRunningOperation()
+ {
+ Cursor = Cursors.Default;
+ OperationExecuting = false;
+ }
+
public virtual void Execute()
{
}
+ ///
+ /// Executes a long running operation with optional pre and post actions.
+ ///
+ /// An action corresponding to the code that will be executed.
+ /// Flag to indicate if preparation tasks should be executed.
+ /// Flag to indicate if post tasks should be executed.
+ protected void ExecuteLongRunningOperation(Action longRunningOperation, bool executeBeforeTasks = true, bool executeAfterTasks = true)
+ {
+ try
+ {
+ if (executeBeforeTasks)
+ {
+ BeginLongRunningOperation();
+ }
+
+ longRunningOperation();
+ }
+ finally
+ {
+ if (executeBeforeTasks)
+ {
+ EndLongRunningOperation();
+ }
+ }
+ }
+
public virtual bool Finish()
{
return true;
@@ -169,6 +213,18 @@ public virtual bool Next()
return true;
}
+ ///
+ /// Subscribes custom events relavant to this wizard page.
+ ///
+ public virtual void SubscribeEvents()
+ {
+ }
+
+ /// Unsubscribes custom events relavant to this wizard page.
+ public virtual void UnsubscribeEvents()
+ {
+ }
+
public virtual void WizardShowing()
{
}
diff --git a/Configurator/Dialogs/AboutScreenForm.Designer.cs b/Configurator/Dialogs/AboutScreenForm.Designer.cs
index 54b3b2b..e0e826b 100644
--- a/Configurator/Dialogs/AboutScreenForm.Designer.cs
+++ b/Configurator/Dialogs/AboutScreenForm.Designer.cs
@@ -87,7 +87,7 @@ private void InitializeComponent()
this.CopyrightLabel.Name = "CopyrightLabel";
this.CopyrightLabel.Size = new System.Drawing.Size(241, 13);
this.CopyrightLabel.TabIndex = 1;
- this.CopyrightLabel.Text = "Copyright (c) 2023, 2024, Oracle and/or its affiliates.";
+ this.CopyrightLabel.Text = "Copyright (c) 2023, 2025, Oracle and/or its affiliates.";
this.CopyrightLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// RegisteredTrademarkLabel
diff --git a/Configurator/Dialogs/ConfigurationFileDialog.Designer.cs b/Configurator/Dialogs/ConfigurationFileDialog.Designer.cs
new file mode 100644
index 0000000..5b2f5a2
--- /dev/null
+++ b/Configurator/Dialogs/ConfigurationFileDialog.Designer.cs
@@ -0,0 +1,306 @@
+/* Copyright (c) 2024, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0, as
+ published by the Free Software Foundation.
+
+ This program is designed to work with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms, as
+ designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have either included with
+ the program or referenced in the documentation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+namespace MySql.Configurator.Dialogs
+{
+ partial class ConfigurationFileDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.DialogCancelButton = new System.Windows.Forms.Button();
+ this.OkButton = new System.Windows.Forms.Button();
+ this.ConfigurationFileErrorPictureBox = new System.Windows.Forms.PictureBox();
+ this.ConfigurationFileErrorLabel = new System.Windows.Forms.Label();
+ this.ConfigurationFileRevertButton = new System.Windows.Forms.Button();
+ this.ConfigurationFileBrowseButton = new System.Windows.Forms.Button();
+ this.ConfigurationFilePathLabel = new System.Windows.Forms.Label();
+ this.ConfigurationFileTextBox = new System.Windows.Forms.TextBox();
+ this.ConfigurationFilePathDescriptionLabel = new System.Windows.Forms.Label();
+ this.LogoPictureBox = new System.Windows.Forms.PictureBox();
+ this.TitleLabel = new System.Windows.Forms.Label();
+ this.ToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.ValidationsErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+ this.ValidationsTimer = new System.Windows.Forms.Timer(this.components);
+ this.ContentAreaPanel.SuspendLayout();
+ this.CommandAreaPanel.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.ConfigurationFileErrorPictureBox)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.LogoPictureBox)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.ValidationsErrorProvider)).BeginInit();
+ this.SuspendLayout();
+ //
+ // FootnoteAreaPanel
+ //
+ this.FootnoteAreaPanel.Location = new System.Drawing.Point(0, 449);
+ this.FootnoteAreaPanel.Size = new System.Drawing.Size(951, 0);
+ //
+ // ContentAreaPanel
+ //
+ this.ContentAreaPanel.Controls.Add(this.LogoPictureBox);
+ this.ContentAreaPanel.Controls.Add(this.TitleLabel);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFilePathDescriptionLabel);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFileErrorPictureBox);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFileErrorLabel);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFileRevertButton);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFileBrowseButton);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFilePathLabel);
+ this.ContentAreaPanel.Controls.Add(this.ConfigurationFileTextBox);
+ this.ContentAreaPanel.Size = new System.Drawing.Size(505, 220);
+ //
+ // CommandAreaPanel
+ //
+ this.CommandAreaPanel.Controls.Add(this.OkButton);
+ this.CommandAreaPanel.Controls.Add(this.DialogCancelButton);
+ this.CommandAreaPanel.Location = new System.Drawing.Point(0, 175);
+ this.CommandAreaPanel.Size = new System.Drawing.Size(505, 45);
+ //
+ // DialogCancelButton
+ //
+ this.DialogCancelButton.AccessibleDescription = "A button to dismiss the dialog";
+ this.DialogCancelButton.AccessibleName = "Cancel";
+ this.DialogCancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.DialogCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.DialogCancelButton.Location = new System.Drawing.Point(418, 10);
+ this.DialogCancelButton.Name = "DialogCancelButton";
+ this.DialogCancelButton.Size = new System.Drawing.Size(75, 23);
+ this.DialogCancelButton.TabIndex = 1;
+ this.DialogCancelButton.Text = "Cancel";
+ this.DialogCancelButton.UseVisualStyleBackColor = true;
+ //
+ // OkButton
+ //
+ this.OkButton.AccessibleDescription = "A button to apply the changes done to the advanced install options";
+ this.OkButton.AccessibleName = "OK";
+ this.OkButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.OkButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkButton.Enabled = false;
+ this.OkButton.Location = new System.Drawing.Point(337, 10);
+ this.OkButton.Name = "OkButton";
+ this.OkButton.Size = new System.Drawing.Size(75, 23);
+ this.OkButton.TabIndex = 0;
+ this.OkButton.Text = "OK";
+ this.OkButton.UseVisualStyleBackColor = true;
+ //
+ // ConfigurationFileErrorPictureBox
+ //
+ this.ConfigurationFileErrorPictureBox.AccessibleDescription = "A picture box displaying an error icon for an invalid configuration file path";
+ this.ConfigurationFileErrorPictureBox.AccessibleName = "Configuration File Error Icon";
+ this.ConfigurationFileErrorPictureBox.Image = global::MySql.Configurator.Properties.Resources.error_sign;
+ this.ConfigurationFileErrorPictureBox.Location = new System.Drawing.Point(15, 145);
+ this.ConfigurationFileErrorPictureBox.Name = "ConfigurationFileErrorPictureBox";
+ this.ConfigurationFileErrorPictureBox.Size = new System.Drawing.Size(16, 16);
+ this.ConfigurationFileErrorPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
+ this.ConfigurationFileErrorPictureBox.TabIndex = 57;
+ this.ConfigurationFileErrorPictureBox.TabStop = false;
+ this.ConfigurationFileErrorPictureBox.Visible = false;
+ //
+ // ConfigurationFileErrorLabel
+ //
+ this.ConfigurationFileErrorLabel.AccessibleDescription = "A label displaying a message about a warning or error in the configuration file p" +
+ "ath validation";
+ this.ConfigurationFileErrorLabel.AccessibleName = "Configuration File Validation Text";
+ this.ConfigurationFileErrorLabel.AutoSize = true;
+ this.ConfigurationFileErrorLabel.Location = new System.Drawing.Point(34, 146);
+ this.ConfigurationFileErrorLabel.Name = "ConfigurationFileErrorLabel";
+ this.ConfigurationFileErrorLabel.Size = new System.Drawing.Size(0, 25);
+ this.ConfigurationFileErrorLabel.TabIndex = 4;
+ this.ConfigurationFileErrorLabel.Visible = false;
+ //
+ // ConfigurationFileRevertButton
+ //
+ this.ConfigurationFileRevertButton.AccessibleDescription = "A button to revert the value of the configuration file path";
+ this.ConfigurationFileRevertButton.AccessibleName = "Configuration File Revert";
+ this.ConfigurationFileRevertButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.ConfigurationFileRevertButton.BackgroundImage = global::MySql.Configurator.Properties.Resources.Revert;
+ this.ConfigurationFileRevertButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
+ this.ConfigurationFileRevertButton.FlatAppearance.BorderSize = 0;
+ this.ConfigurationFileRevertButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.ConfigurationFileRevertButton.Location = new System.Drawing.Point(460, 99);
+ this.ConfigurationFileRevertButton.Margin = new System.Windows.Forms.Padding(0);
+ this.ConfigurationFileRevertButton.Name = "ConfigurationFileRevertButton";
+ this.ConfigurationFileRevertButton.Size = new System.Drawing.Size(29, 20);
+ this.ConfigurationFileRevertButton.TabIndex = 1;
+ this.ConfigurationFileRevertButton.UseVisualStyleBackColor = true;
+ this.ConfigurationFileRevertButton.Click += new System.EventHandler(this.ConfigurationFileRevertButton_Click);
+ //
+ // ConfigurationFileBrowseButton
+ //
+ this.ConfigurationFileBrowseButton.AccessibleDescription = "A button to open a dialog to browse through the file system and select the path t" +
+ "o the configuration file";
+ this.ConfigurationFileBrowseButton.AccessibleName = "Configuration File Browse";
+ this.ConfigurationFileBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.ConfigurationFileBrowseButton.Location = new System.Drawing.Point(461, 116);
+ this.ConfigurationFileBrowseButton.Name = "ConfigurationFileBrowseButton";
+ this.ConfigurationFileBrowseButton.Size = new System.Drawing.Size(29, 22);
+ this.ConfigurationFileBrowseButton.TabIndex = 3;
+ this.ConfigurationFileBrowseButton.Text = "...";
+ this.ConfigurationFileBrowseButton.UseVisualStyleBackColor = true;
+ this.ConfigurationFileBrowseButton.Click += new System.EventHandler(this.ConfigurationFileBrowseButton_Click);
+ //
+ // ConfigurationFilePathLabel
+ //
+ this.ConfigurationFilePathLabel.AccessibleDescription = "A label displaying the text configuration file path";
+ this.ConfigurationFilePathLabel.AccessibleName = "Configuration File Path Text";
+ this.ConfigurationFilePathLabel.AutoSize = true;
+ this.ConfigurationFilePathLabel.Location = new System.Drawing.Point(12, 95);
+ this.ConfigurationFilePathLabel.Name = "ConfigurationFilePathLabel";
+ this.ConfigurationFilePathLabel.Size = new System.Drawing.Size(195, 25);
+ this.ConfigurationFilePathLabel.TabIndex = 0;
+ this.ConfigurationFilePathLabel.Text = "Configuration File Path:";
+ //
+ // ConfigurationFileTextBox
+ //
+ this.ConfigurationFileTextBox.AccessibleDescription = "A text box to set the full absolute path of the server configuration file";
+ this.ConfigurationFileTextBox.AccessibleName = "Configuration File Path";
+ this.ConfigurationFileTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ConfigurationFileTextBox.Location = new System.Drawing.Point(12, 115);
+ this.ConfigurationFileTextBox.Name = "ConfigurationFileTextBox";
+ this.ConfigurationFileTextBox.Size = new System.Drawing.Size(443, 31);
+ this.ConfigurationFileTextBox.TabIndex = 2;
+ this.ConfigurationFileTextBox.TextChanged += new System.EventHandler(this.ConfigurationFileTextBox_TextChangedHandler);
+ this.ConfigurationFileTextBox.Validated += new System.EventHandler(this.ConfigurationFileTextBox_Validated);
+ //
+ // ConfigurationFilePathDescriptionLabel
+ //
+ this.ConfigurationFilePathDescriptionLabel.AccessibleDescription = "A label displaying a description about the need to provide the path to the server" +
+ " configuration file";
+ this.ConfigurationFilePathDescriptionLabel.AccessibleName = "Configuration file path description";
+ this.ConfigurationFilePathDescriptionLabel.Font = new System.Drawing.Font("Segoe UI", 9F);
+ this.ConfigurationFilePathDescriptionLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
+ this.ConfigurationFilePathDescriptionLabel.Location = new System.Drawing.Point(90, 46);
+ this.ConfigurationFilePathDescriptionLabel.Name = "ConfigurationFilePathDescriptionLabel";
+ this.ConfigurationFilePathDescriptionLabel.Size = new System.Drawing.Size(401, 44);
+ this.ConfigurationFilePathDescriptionLabel.TabIndex = 58;
+ this.ConfigurationFilePathDescriptionLabel.Text = "The server configuration file (my.ini or my.cnf) was not found. Please specify th" +
+ "e location of the file to continue.";
+ //
+ // LogoPictureBox
+ //
+ this.LogoPictureBox.AccessibleDescription = "A picture box displaying an icon related to the consumer application and the dial" +
+ "og\'s purpose";
+ this.LogoPictureBox.AccessibleName = "Icon";
+ this.LogoPictureBox.Image = global::MySql.Configurator.Properties.Resources.MainLogo;
+ this.LogoPictureBox.Location = new System.Drawing.Point(12, 15);
+ this.LogoPictureBox.Margin = new System.Windows.Forms.Padding(4, 6, 4, 6);
+ this.LogoPictureBox.Name = "LogoPictureBox";
+ this.LogoPictureBox.Size = new System.Drawing.Size(66, 65);
+ this.LogoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ this.LogoPictureBox.TabIndex = 60;
+ this.LogoPictureBox.TabStop = false;
+ //
+ // TitleLabel
+ //
+ this.TitleLabel.AccessibleDescription = "A generic title label";
+ this.TitleLabel.AccessibleName = "Title";
+ this.TitleLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.TitleLabel.AutoEllipsis = true;
+ this.TitleLabel.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.TitleLabel.ForeColor = System.Drawing.Color.Navy;
+ this.TitleLabel.Location = new System.Drawing.Point(91, 15);
+ this.TitleLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.TitleLabel.Name = "TitleLabel";
+ this.TitleLabel.Size = new System.Drawing.Size(402, 31);
+ this.TitleLabel.TabIndex = 59;
+ this.TitleLabel.Text = "Server Configuration File Not Found";
+ //
+ // ValidationsErrorProvider
+ //
+ this.ValidationsErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+ this.ValidationsErrorProvider.ContainerControl = this;
+ //
+ // ValidationsTimer
+ //
+ this.ValidationsTimer.Interval = 800;
+ this.ValidationsTimer.Tick += new System.EventHandler(this.ValidationsTimer_Tick);
+ //
+ // ConfigurationFileDialog
+ //
+ this.AcceptButton = this.OkButton;
+ this.AccessibleDescription = "A modal dialog showing a textbox to select the path of the server configuraiton f" +
+ "ile";
+ this.AccessibleName = "Configuration File Dialog";
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
+ this.CancelButton = this.DialogCancelButton;
+ this.ClientSize = new System.Drawing.Size(505, 220);
+ this.CommandAreaHeight = 45;
+ this.CommandAreaVisible = true;
+ this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.FootnoteAreaHeight = 0;
+ this.Name = "ConfigurationFileDialog";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "MySQL Configurator";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ConfigurationFileDialog_FormClosing);
+ this.ContentAreaPanel.ResumeLayout(false);
+ this.ContentAreaPanel.PerformLayout();
+ this.CommandAreaPanel.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.ConfigurationFileErrorPictureBox)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.LogoPictureBox)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.ValidationsErrorProvider)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ private System.Windows.Forms.Button DialogCancelButton;
+ private System.Windows.Forms.PictureBox ConfigurationFileErrorPictureBox;
+ private System.Windows.Forms.Label ConfigurationFileErrorLabel;
+ private System.Windows.Forms.Button ConfigurationFileRevertButton;
+ private System.Windows.Forms.Button ConfigurationFileBrowseButton;
+ private System.Windows.Forms.Label ConfigurationFilePathLabel;
+ private System.Windows.Forms.TextBox ConfigurationFileTextBox;
+ protected System.Windows.Forms.Button OkButton;
+ private System.Windows.Forms.Label ConfigurationFilePathDescriptionLabel;
+ private System.Windows.Forms.PictureBox LogoPictureBox;
+ private System.Windows.Forms.Label TitleLabel;
+ protected System.Windows.Forms.ToolTip ToolTip;
+ protected System.Windows.Forms.ErrorProvider ValidationsErrorProvider;
+ protected System.Windows.Forms.Timer ValidationsTimer;
+ }
+}
diff --git a/Configurator/Dialogs/ConfigurationFileDialog.cs b/Configurator/Dialogs/ConfigurationFileDialog.cs
new file mode 100644
index 0000000..5cb83e8
--- /dev/null
+++ b/Configurator/Dialogs/ConfigurationFileDialog.cs
@@ -0,0 +1,202 @@
+/* Copyright (c) 2024, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0, as
+ published by the Free Software Foundation.
+
+ This program is designed to work with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms, as
+ designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have either included with
+ the program or referenced in the documentation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+using MySql.Configurator.Core.Classes;
+using MySql.Configurator.Core.Forms;
+using Utilities = MySql.Configurator.Core.Classes.Utilities;
+using MySql.Configurator.Properties;
+using MySql.Configurator.Core.Controllers;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement;
+
+namespace MySql.Configurator.Dialogs
+{
+ ///
+ /// Dialog that enables to provide an updated path for the server configuration file.
+ ///
+ public partial class ConfigurationFileDialog : AutoStyleableBaseDialog
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ConfigurationFileDialog()
+ {
+ InitializeComponent();
+ }
+
+ #region Properties
+
+ ///
+ /// The path containing the my.ini or my.cnf server configuration file.
+ ///
+ public string ConfigurationFilePath { get; private set; }
+
+ #endregion Properties
+
+ ///
+ /// Checks that the path in the Configuration File textbox is valid and contains a server
+ /// configuration file.
+ ///
+ protected void CheckDirectory()
+ {
+ var path = ConfigurationFileTextBox.Text.Trim();
+ ConfigurationFileErrorLabel.Text = string.Empty;
+ ConfigurationFileErrorPictureBox.Visible = false;
+ if (string.IsNullOrEmpty(path))
+ {
+ OkButton.Enabled = false;
+ return;
+ }
+
+ var iniFilePath = Path.Combine(path, BaseServerSettings.DEFAULT_CONFIG_FILE_NAME);
+ var alternateIniFilePath = Path.Combine(path, BaseServerSettings.ALTERNATE_CONFIG_FILE_NAME);
+ if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0 || !Path.IsPathRooted(path))
+ {
+ ConfigurationFileErrorLabel.Text = Resources.PathInvalidError;
+ ConfigurationFileErrorPictureBox.Visible = true;
+ }
+
+ var errorMessage = Utilities.ValidateFilePath(path);
+ if (!string.IsNullOrEmpty(errorMessage))
+ {
+ ConfigurationFileErrorLabel.Text = errorMessage;
+ ConfigurationFileErrorPictureBox.Visible = true;
+ }
+
+ if (!File.Exists(iniFilePath)
+ && !File.Exists(alternateIniFilePath))
+ {
+ ConfigurationFileErrorLabel.Text = Resources.ConfigurationFileNotFound;
+ ConfigurationFileErrorPictureBox.Visible = true;
+ }
+
+ ConfigurationFileErrorLabel.Visible = !string.IsNullOrEmpty(ConfigurationFileErrorLabel.Text);
+ OkButton.Enabled = !ConfigurationFileErrorPictureBox.Visible;
+ }
+
+ ///
+ /// Handles the OnLoad event.
+ ///
+ /// The instance containing the event data.
+ protected override void OnLoad(EventArgs e)
+ {
+ Utilities.NormalizeFont(this);
+ base.OnLoad(e);
+ }
+
+ ///
+ /// Handles the FormClosing event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void ConfigurationFileDialog_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (DialogResult == DialogResult.Cancel)
+ {
+ return;
+ }
+
+ ConfigurationFilePath = ConfigurationFileTextBox.Text.Trim();
+ }
+
+ ///
+ /// Handles the Click event for the Browse button.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void ConfigurationFileBrowseButton_Click(object sender, EventArgs e)
+ {
+ using (var folderBrowserDialog = new FolderBrowserDialog())
+ {
+ folderBrowserDialog.SelectedPath = ConfigurationFileTextBox.Text;
+ if (folderBrowserDialog.ShowDialog() == DialogResult.Cancel)
+ {
+ return;
+ }
+
+ ConfigurationFileTextBox.Text = folderBrowserDialog.SelectedPath;
+ }
+
+ CheckDirectory();
+ }
+
+ ///
+ /// Handles the Click event for the Revert button.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void ConfigurationFileRevertButton_Click(object sender, EventArgs e)
+ {
+ ConfigurationFileTextBox.Clear();
+ CheckDirectory();
+ }
+
+ ///
+ /// Resets the validations timer.
+ ///
+ private void ResetValidationsTimer()
+ {
+ ValidationsTimer.Stop();
+ ValidationsTimer.Start();
+ }
+
+ ///
+ /// Handles the TextValidated event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ /// This event method is meant to be used with the event.
+ private void ConfigurationFileTextBox_Validated(object sender, EventArgs e)
+ {
+ CheckDirectory();
+ }
+
+ ///
+ /// Handles the TextChanged event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void ConfigurationFileTextBox_TextChangedHandler(object sender, EventArgs e)
+ {
+ ResetValidationsTimer();
+ }
+
+ ///
+ /// Handles the Tick event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void ValidationsTimer_Tick(object sender, EventArgs e)
+ {
+ var focusedTextBox = this.GetChildControlsOfType().FirstOrDefault(control => control.Focused);
+ if (focusedTextBox != null)
+ {
+ ConfigurationFileTextBox_Validated(focusedTextBox, EventArgs.Empty);
+ }
+ }
+ }
+}
diff --git a/Configurator/Dialogs/ConfigurationFileDialog.resx b/Configurator/Dialogs/ConfigurationFileDialog.resx
new file mode 100644
index 0000000..f351272
--- /dev/null
+++ b/Configurator/Dialogs/ConfigurationFileDialog.resx
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 25, 19
+
+
+ 148, 19
+
+
+ 407, 19
+
+
\ No newline at end of file
diff --git a/Configurator/Dialogs/MainForm.cs b/Configurator/Dialogs/MainForm.cs
index a537975..391ad7b 100644
--- a/Configurator/Dialogs/MainForm.cs
+++ b/Configurator/Dialogs/MainForm.cs
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
using System;
using System.Configuration;
using System.Drawing;
+using System.IO;
using System.Linq;
using System.Windows.Forms;
using MySql.Configurator.Core.Classes;
@@ -122,6 +123,68 @@ private void SetWindowPosition()
private void TryToLaunchWizard(bool launchedFromMainIcon)
{
+ // Update execution mode if current configuration needs to be upgraded.
+ var controller = _package.Controller as ServerConfigurationController;
+ if (controller == null)
+ {
+ throw new ArgumentNullException(nameof(controller));
+ }
+
+ var upgradeHistoryFileExists = false;
+ Version existingServerVersion = new Version();
+ if (_executionMode == ExecutionMode.Configure)
+ {
+ var path = Path.Combine(controller.DataDirectory, "Data", MySqlUpgradeHistoryManager.UPGRADE_HISTORY_FILE_NAME);
+ upgradeHistoryFileExists = File.Exists(path);
+
+ // TODO: Enable upgrade history file regeneration when server bug is fixed.
+ /*
+ // If upgrade history file does not exist, stop and start server to regenerate it.
+ if (!upgradeHistoryFileExists
+ && controller.IsThereServerDataFiles
+ && _package.Version.Major >= 8
+ && _package.Version.Minor >= 4)
+ {
+ var serverInstance = new LocalServerInstance(controller);
+ serverInstance.DataDir = controller.DataDirectory;
+ if (serverInstance.IsRunning)
+ {
+ serverInstance.StopInstance();
+ }
+
+ serverInstance.StartInstanceAsProcess("--upgrade=MINIMAL");
+ upgradeHistoryFileExists = File.Exists(path);
+ }
+ */
+
+ if (controller.IsThereServerDataFiles
+ && upgradeHistoryFileExists)
+ {
+ (Version, bool) result = MySqlUpgradeHistoryManager.GetUpgradeHistoryLatestVersion(controller.DataDirectory);
+ existingServerVersion = result.Item1;
+ bool hasMetadata = result.Item2;
+
+ // If the version is lower or if version is the same but we have metadata it means that this is
+ // an updated version of the current package and needs to be upgraded.
+ if (existingServerVersion != null
+ && (existingServerVersion < _package.Version)
+ || (existingServerVersion == _package.Version
+ && hasMetadata))
+ {
+ var validUpgrade = _package.Version.ServerSupportsInPlaceUpgrades(existingServerVersion);
+ if (validUpgrade == UpgradeViability.Supported
+ && _package.Version.Major == existingServerVersion.Major
+ && _package.Version.Minor == existingServerVersion.Minor)
+ {
+ Logger.LogInformation(Resources.ExecutionModeSwitch);
+ _executionMode = ExecutionMode.Upgrade;
+ controller.IsSameDirectoryUpgrade = true;
+ }
+ }
+ }
+ }
+
+ // Show wizard matching the selected execution mode.
ConfigurationType configurationType;
switch (_executionMode)
{
@@ -144,13 +207,25 @@ private void TryToLaunchWizard(bool launchedFromMainIcon)
removeWizard.ShowWizard(_package, this);
break;
+ case ExecutionMode.Upgrade:
+ configurationType = ConfigurationType.Upgrade;
+ configWizard = new ConfigWizard();
+ Controls.Add(configWizard);
+ configWizard.WizardCanceled += WizardClosed;
+ configWizard.WizardClosed += WizardClosed;
+ configWizard.ShowWizard(_package, this, configurationType);
+ break;
+
default:
throw new ConfiguratorException(ConfiguratorError.InvalidExecutionMode);
}
+ // Update status bar.
StatusStrip.Visible = true;
- VersionLabel.Text = $"MySQL Server {_package.VersionString}";
var controllerConfigurationType = _package.Controller.ConfigurationType;
+ VersionLabel.Text = controllerConfigurationType != ConfigurationType.Upgrade
+ ? $"MySQL Server {_package.VersionString}"
+ : $"MySQL Server {(upgradeHistoryFileExists ? existingServerVersion.ToString() : "Unknown")} -> {_package.VersionString}";
var stringConfigurationType = string.Empty;
switch (controllerConfigurationType)
{
@@ -165,7 +240,8 @@ private void TryToLaunchWizard(bool launchedFromMainIcon)
ConfigurationTypeLabel.Text = stringConfigurationType;
if (controllerConfigurationType == ConfigurationType.Reconfiguration
- || controllerConfigurationType == ConfigurationType.Remove)
+ || controllerConfigurationType == ConfigurationType.Remove
+ || controllerConfigurationType == ConfigurationType.Upgrade)
{
var serverController = _package.Controller as ServerConfigurationController;
DataDirectoryLabel.Text = $"Data Directory: {serverController.DataDirectory}";
@@ -218,11 +294,17 @@ public bool CanClose()
var wizard = Controls.OfType().FirstOrDefault();
if (wizard == null)
{
- // This is unexpected, a Wizard should be already in the Controls collection, but if not found just let the form close.
return true;
}
- return wizard.CanCancel;
+ if (wizard.CurrentPage.OperationExecuting)
+ {
+ var result = InfoDialog.ShowDialog(InfoDialogProperties.GetYesNoDialogProperties(InfoDialog.InfoType.Warning, Resources.MainFormOnGoingOperationTitle, Resources.MainFormOnGoingOperationDescription, Resources.MainFormOnGoingOperationDetail));
+ return result.DialogResult == DialogResult.OK
+ || result.DialogResult == DialogResult.Yes;
+ }
+
+ return true;
}
#region Event handling
diff --git a/Configurator/MySQLConfigurator.csproj b/Configurator/MySQLConfigurator.csproj
index 1c63c72..41c580e 100644
--- a/Configurator/MySQLConfigurator.csproj
+++ b/Configurator/MySQLConfigurator.csproj
@@ -2,6 +2,7 @@
Debug
+ 999.999.999
AnyCPU
9.0.30729
2.0
@@ -114,6 +115,7 @@
+
@@ -141,6 +143,7 @@
+
@@ -184,7 +187,6 @@
-
@@ -383,6 +385,12 @@
AboutScreenForm.cs
+
+ Form
+
+
+ ConfigurationFileDialog.cs
+
Form
@@ -646,6 +654,9 @@
AboutScreenForm.cs
+
+ ConfigurationFileDialog.cs
+
UpgradeFromServerPreGaWarningDialog.cs
@@ -685,6 +696,7 @@
ConfigureErrorPage.cs
+ Designer
RemoveErrorPage.cs
@@ -884,4 +896,18 @@
-->
+
+
+
+ <_Parameter1>$(Version)
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Configurator/Program.cs b/Configurator/Program.cs
index 25f80e4..b464ad1 100644
--- a/Configurator/Program.cs
+++ b/Configurator/Program.cs
@@ -64,10 +64,6 @@ public class Program
#endregion
- #region Properties
-
- #endregion
-
///
/// Customizes the looks of common dialogs.
///
@@ -126,15 +122,7 @@ For ZIP installations this path is whichever location where the server files wer
// Do not show form if running in removal mode and option --show-removal-warning was not provided.
Package package = null;
- try
- {
- package = ProductManager.LoadPackage(_version, _installDirPath);
- }
- catch (ConfiguratorException ex)
- {
- Logger.LogException(ex);
- }
-
+ package = ProductManager.LoadPackage(_version, _installDirPath);
if (executionMode == ExecutionMode.RemoveNoShow)
{
var controller = package.Controller as ServerConfigurationController;
@@ -237,29 +225,35 @@ private static ExecutionMode ProcessCommandLineArguments(string[] arguments)
_installDirPath = installDirPath;
#endif
+ if (string.IsNullOrEmpty(_installDirPath))
+ {
+ throw new ArgumentNullException(_installDirPath);
+ }
+
// Validate install dir.
var pathToMySqld = Path.Combine(_installDirPath, "bin\\mysqld.exe");
if (!Directory.Exists(_installDirPath)
|| !File.Exists(pathToMySqld))
{
- _installDirPath = null;
+ throw new ConfiguratorException(ConfiguratorError.MysqldExeNotFound, _installDirPath);
}
// Set version.
- FileVersionInfo versionInfo = null;
- Version versionItem = null;
- if (!string.IsNullOrEmpty(_installDirPath))
- {
- versionInfo = FileVersionInfo.GetVersionInfo(pathToMySqld);
- versionItem = new Version(versionInfo.FileVersion);
- }
- else
+ var versionInfo = FileVersionInfo.GetVersionInfo(pathToMySqld);
+ var mysqldExeVersion = new Version(versionInfo.FileVersion);
+ var assemblyVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
+ var configuratorVersion = new Version(versionInfo.FileVersion);
+ if (mysqldExeVersion != configuratorVersion)
{
- versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
- versionItem = new Version(versionInfo.FileVersion);
+ throw new ConfiguratorException(ConfiguratorError.VersionMismatch);
}
- _version = $"{versionItem.Major}.{versionItem.Minor}.{versionItem.Build}";
+ _version = $"{mysqldExeVersion.Major}.{mysqldExeVersion.Minor}.{mysqldExeVersion.Build}";
+ }
+ catch (ConfiguratorException ex)
+ {
+ Logger.LogException(ex);
+ throw ex;
}
catch (Exception ex)
{
diff --git a/Configurator/Properties/AssemblyInfo.cs b/Configurator/Properties/AssemblyInfo.cs
index 49b357e..1b56ae0 100644
--- a/Configurator/Properties/AssemblyInfo.cs
+++ b/Configurator/Properties/AssemblyInfo.cs
@@ -30,7 +30,7 @@ You should have received a copy of the GNU General Public License
[assembly: AssemblyTitle("The MySQL Configurator is designed to allow the configuration and/or upgrade of the MySQL Server product.")]
[assembly: AssemblyCompany("Oracle Corporation")]
[assembly: AssemblyProduct("MySQL Configurator")]
-[assembly: AssemblyCopyright("Copyright (c) 2023, 2024, Oracle and/or its affiliates.")]
+[assembly: AssemblyCopyright("Copyright (c) 2023, 2025, Oracle and/or its affiliates.")]
[assembly: AssemblyTrademark("Oracle®, Java, MySQL, and NetSuite are registered trademarks of Oracle and/or its affiliates.")]
// Setting ComVisible to false makes the types in this assembly not visible
@@ -51,5 +51,3 @@ You should have received a copy of the GNU General Public License
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("8.4.0.0")]
-[assembly: AssemblyFileVersion("8.4.0.0")]
diff --git a/Configurator/Properties/Resources.Designer.cs b/Configurator/Properties/Resources.Designer.cs
index 9163ce2..350d339 100644
--- a/Configurator/Properties/Resources.Designer.cs
+++ b/Configurator/Properties/Resources.Designer.cs
@@ -1,27 +1,4 @@
-/* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 2.0, as
- published by the Free Software Foundation.
-
- This program is designed to work with certain software (including
- but not limited to OpenSSL) that is licensed under separate terms, as
- designated in a particular file or component or in included license
- documentation. The authors of MySQL hereby grant you an additional
- permission to link the program and your derivative works with the
- separately licensed software that they have either included with
- the program or referenced in the documentation.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License, version 2.0, for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
@@ -608,6 +585,15 @@ public static string ConfigStepTakingTooLong {
}
}
+ ///
+ /// Looks up a localized string similar to A my.ini or my.cnf configuration file was not found at the specified location..
+ ///
+ public static string ConfigurationFileNotFound {
+ get {
+ return ResourceManager.GetString("ConfigurationFileNotFound", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to *WARNING*: A deprecated configuration setting is being used('{0}') and will be removed in a future release. Use any of the following keywords instead: {1}..
///
@@ -676,7 +662,7 @@ public static string ConfigureHasTimedOutTitle {
///
/// Looks up a localized string similar to The configuration for {0} was successful.
- ///Click Finish to continue..
+ ///Click Next to continue..
///
public static string ConfigureSuccess {
get {
@@ -1038,6 +1024,15 @@ public static byte[] example_databases {
}
}
+ ///
+ /// Looks up a localized string similar to MySQL Server needs to be upgraded. Switching to 'upgrade' mode..
+ ///
+ public static string ExecutionModeSwitch {
+ get {
+ return ResourceManager.GetString("ExecutionModeSwitch", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The data directory name will be renamed to
///"{0}" before the data is upgraded..
@@ -1338,6 +1333,33 @@ public static System.Drawing.Bitmap logo {
}
}
+ ///
+ /// Looks up a localized string similar to There is an ongoing operation and closing MySQL Configurator may result in a corrupt setup..
+ ///
+ public static string MainFormOnGoingOperationDescription {
+ get {
+ return ResourceManager.GetString("MainFormOnGoingOperationDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Do you still want to close MySQL Configurator?.
+ ///
+ public static string MainFormOnGoingOperationDetail {
+ get {
+ return ResourceManager.GetString("MainFormOnGoingOperationDetail", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to An operation is currently running.
+ ///
+ public static string MainFormOnGoingOperationTitle {
+ get {
+ return ResourceManager.GetString("MainFormOnGoingOperationTitle", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -2712,6 +2734,25 @@ public static string ServerConfigCheckingAccessToLogs {
}
}
+ ///
+ /// Looks up a localized string similar to A my.ini or my.cnf server configuration file was not found in the location as the data directory.
+ ///Provide a path for the server configuration file..
+ ///
+ public static string ServerConfigConfigurationFileNotFound {
+ get {
+ return ResourceManager.GetString("ServerConfigConfigurationFileNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The specified ini file could not be read. Provide a valid server configuration file or select a different file to continue..
+ ///
+ public static string ServerConfigConfigurationFileNotValid {
+ get {
+ return ResourceManager.GetString("ServerConfigConfigurationFileNotValid", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Failed to convert inherited permissions to explicit permissions..
///
@@ -3181,6 +3222,24 @@ public static string ServerConfigFailedToRetrieveLocalPrincipals {
}
}
+ ///
+ /// Looks up a localized string similar to Failed to revert the authentication plugin change for the root user with message: {0}..
+ ///
+ public static string ServerConfigFailedToRevertAuthenticationPluginChange {
+ get {
+ return ResourceManager.GetString("ServerConfigFailedToRevertAuthenticationPluginChange", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Failed to update the authentication plugin of the root user..
+ ///
+ public static string ServerConfigFailedToUpdateRootUserAuthPlugin {
+ get {
+ return ResourceManager.GetString("ServerConfigFailedToUpdateRootUserAuthPlugin", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to General settings file not found..
///
@@ -3307,6 +3366,16 @@ public static string ServerConfigInstanceRunning {
}
}
+ ///
+ /// Looks up a localized string similar to The 'root' user is configured to use the 'mysql_native_password' authentication plugin.
+ ///Proceeding with the upgrade will update the plugin to 'caching_sha2_password'..
+ ///
+ public static string ServerConfigInvalidAuthenticationPlugin {
+ get {
+ return ResourceManager.GetString("ServerConfigInvalidAuthenticationPlugin", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to One or more of the given security tokens is not valid. Please verify the list entered:.
///
@@ -3559,6 +3628,15 @@ public static string ServerConfigRevertDataDirRenameError {
}
}
+ ///
+ /// Looks up a localized string similar to Reverted the authentication plugin change for the root user..
+ ///
+ public static string ServerConfigRevertedAuthenticationPluginChange {
+ get {
+ return ResourceManager.GetString("ServerConfigRevertedAuthenticationPluginChange", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Reverted the data directory renaming..
///
@@ -3568,6 +3646,15 @@ public static string ServerConfigRevertedDataDirRename {
}
}
+ ///
+ /// Looks up a localized string similar to Reverting the authentication plugin change for the root user....
+ ///
+ public static string ServerConfigRevertingAuthenticationPluginChanged {
+ get {
+ return ResourceManager.GetString("ServerConfigRevertingAuthenticationPluginChanged", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Reverting the data directory renaming....
///
@@ -3847,6 +3934,15 @@ public static string ServerConfigUnspecifiedError {
}
}
+ ///
+ /// Looks up a localized string similar to Updated authentication plugin of the root user..
+ ///
+ public static string ServerConfigUpdatedRootUserAuthPlugin {
+ get {
+ return ResourceManager.GetString("ServerConfigUpdatedRootUserAuthPlugin", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Updating existing service....
///
@@ -3865,6 +3961,15 @@ public static string ServerConfigUpdatingExistingServiceWithNewName {
}
}
+ ///
+ /// Looks up a localized string similar to Updating the authentication plugin of the root user to: {0}..
+ ///
+ public static string ServerConfigUpdatingRootUserAuthPlugin {
+ get {
+ return ResourceManager.GetString("ServerConfigUpdatingRootUserAuthPlugin", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Unable to access the Active Directory of the domain. Confirm that.
///
@@ -4252,6 +4357,15 @@ public static string ServerStopProcessStep {
}
}
+ ///
+ /// Looks up a localized string similar to Updating authentication plugin for the root user.
+ ///
+ public static string ServerUpdateAuthenticationPluginStep {
+ get {
+ return ResourceManager.GetString("ServerUpdateAuthenticationPluginStep", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Updating example databases.
///
@@ -4433,20 +4547,11 @@ public static string SettingsFileReadError {
}
///
- /// Looks up a localized string similar to Setting up product configuration controller for new installation..
- ///
- public static string SettingUpNewInstallation {
- get {
- return ResourceManager.GetString("SettingUpNewInstallation", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Setting up product configuration controller for reconfiguration..
+ /// Looks up a localized string similar to Product configuration controller set to '{0}' configuration type..
///
- public static string SettingUpReconfiguration {
+ public static string SettingUpControllerMessage {
get {
- return ResourceManager.GetString("SettingUpReconfiguration", resourceCulture);
+ return ResourceManager.GetString("SettingUpControllerMessage", resourceCulture);
}
}
diff --git a/Configurator/Properties/Resources.resx b/Configurator/Properties/Resources.resx
index 5c16804..956b5ea 100644
--- a/Configurator/Properties/Resources.resx
+++ b/Configurator/Properties/Resources.resx
@@ -294,7 +294,7 @@ Click Finish to continue.
The configuration for {0} was successful.
-Click Finish to continue.
+Click Next to continue.
The removal for some products has failed or was cancelled by the user.
@@ -919,11 +919,8 @@ Provide a more complex password for stronger security.
Setting the instance as writable
-
- Setting up product configuration controller for new installation.
-
-
- Setting up product configuration controller for reconfiguration.
+
+ Product configuration controller set to '{0}' configuration type.
Setting up product configuration controller for upgrade.
@@ -1773,4 +1770,51 @@ the upgrade may result in an upgrade failure, proceed at your own risk.
Invalid action provided. Running in configuration mode.
+
+ MySQL Server needs to be upgraded. Switching to 'upgrade' mode.
+
+
+ A my.ini or my.cnf configuration file was not found at the specified location.
+
+
+ A my.ini or my.cnf server configuration file was not found in the location as the data directory.
+Provide a path for the server configuration file.
+
+
+ The specified ini file could not be read. Provide a valid server configuration file or select a different file to continue.
+
+
+ Failed to update the authentication plugin of the root user.
+
+
+ The 'root' user is configured to use the 'mysql_native_password' authentication plugin.
+Proceeding with the upgrade will update the plugin to 'caching_sha2_password'.
+
+
+ Updated authentication plugin of the root user.
+
+
+ Updating the authentication plugin of the root user to: {0}.
+
+
+ Updating authentication plugin for the root user
+
+
+ Failed to revert the authentication plugin change for the root user with message: {0}.
+
+
+ Reverted the authentication plugin change for the root user.
+
+
+ Reverting the authentication plugin change for the root user...
+
+
+ There is an ongoing operation and closing MySQL Configurator may result in a corrupt setup.
+
+
+ Do you still want to close MySQL Configurator?
+
+
+ An operation is currently running
+
\ No newline at end of file
diff --git a/Configurator/Resources/my-template-8.x.ini b/Configurator/Resources/my-template-8.x.ini
index 7afba2c..6f4b776 100644
--- a/Configurator/Resources/my-template-8.x.ini
+++ b/Configurator/Resources/my-template-8.x.ini
@@ -136,8 +136,6 @@ no-beep
# you have installed the server correctly (see above) so it reads this
# file.
#
-# [SERVER_TYPE]="server_type"
-# server_type=
[mysqld]
# The next three options are mutually exclusive to SERVER_PORT below.
diff --git a/Configurator/Wizards/Common/BaseConfigureRemoveApplyPage.cs b/Configurator/Wizards/Common/BaseConfigureRemoveApplyPage.cs
index 36983b3..6566bef 100644
--- a/Configurator/Wizards/Common/BaseConfigureRemoveApplyPage.cs
+++ b/Configurator/Wizards/Common/BaseConfigureRemoveApplyPage.cs
@@ -39,7 +39,6 @@ public partial class BaseConfigureRemoveApplyPage : WizardPage
#region Fields
protected ProductConfigurationController CurrentController;
- protected bool Executing;
protected Stopwatch StopWatch;
#endregion Fields
@@ -48,7 +47,6 @@ public BaseConfigureRemoveApplyPage()
{
InitializeComponent();
StopWatch = new Stopwatch();
- Executing = false;
}
public BaseConfigureRemoveApplyPage(ProductConfigurationController controller)
@@ -79,16 +77,9 @@ public override bool Finish()
{
string msg = string.Format(Resources.ConfirmFinishWithFailingConfig, CurrentController.Package.NameWithVersion);
result = InfoDialog.ShowDialog(InfoDialogProperties.GetYesNoDialogProperties(InfoDialog.InfoType.Warning, Resources.AppName, msg)).DialogResult;
- bool shouldClose = result == DialogResult.Yes;
- if (shouldClose)
- {
- DetachEvents();
- }
-
- return shouldClose;
+ return result == DialogResult.Yes;
}
- DetachEvents();
if (!RebootWhenDoneCheckBox.Checked)
{
return base.Finish();
@@ -144,15 +135,11 @@ public override bool FinishOk
{
SetControlVisibleStatus(Wizard.FinishButton, !Wizard.ExecuteButton.Visible);
SetControlVisibleStatus(Wizard.BackButton, Wizard.ExecuteButton.Visible);
- return !Executing;
+ return !OperationExecuting;
}
}
#endregion Properties
-
- protected virtual void DetachEvents()
- {
- }
protected void RebootWhenDoneCheckBox_CheckedChanged_1(object sender, EventArgs e)
{
diff --git a/Configurator/Wizards/ConfigWizard/ConfigApplyPage.cs b/Configurator/Wizards/ConfigWizard/ConfigApplyPage.cs
index be6fb1a..e73b071 100644
--- a/Configurator/Wizards/ConfigWizard/ConfigApplyPage.cs
+++ b/Configurator/Wizards/ConfigWizard/ConfigApplyPage.cs
@@ -35,6 +35,7 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Properties;
using MySql.Configurator.Wizards.Common;
using MySql.Configurator.Wizards.Server;
+using Action = System.Action;
namespace MySql.Configurator.Wizards.ConfigWizard
{
@@ -63,7 +64,7 @@ public override bool NextOk {
get
{
Wizard.FinishButton.Visible = false;
- return !Executing
+ return !OperationExecuting
&& !Wizard.ExecuteButton.Enabled;
}
}
@@ -117,17 +118,10 @@ public override bool Next()
{
string msg = string.Format(Resources.ConfirmFinishWithFailingConfig, CurrentController.Package.NameWithVersion);
result = InfoDialog.ShowDialog(InfoDialogProperties.GetYesNoDialogProperties(InfoDialog.InfoType.Warning, Resources.AppName, msg)).DialogResult;
- bool shouldClose = result == DialogResult.Yes;
- if (shouldClose)
- {
- DetachEvents();
- }
-
- return shouldClose;
+ return result == DialogResult.Yes;
}
Wizard.Log = LogContentsTextBox.Text;
- DetachEvents();
if (!RebootWhenDoneCheckBox.Checked)
{
return base.Finish();
@@ -154,44 +148,66 @@ public override bool Next()
public override void Execute()
{
- if (_callActivateOnExecute)
+ Action action;
+ action = delegate
{
- Activate();
- }
+ if (_callActivateOnExecute)
+ {
+ Activate();
+ }
- LogContentsTextBox.Clear();
- Executing = true;
- Wizard.ExecuteButton.Enabled = false;
- Wizard.CancelButton.Visible = true;
- ConfigurationResultLabel.Text = string.Empty;
- RetryButton.Visible = false;
+ LogContentsTextBox.Clear();
+ Wizard.ExecuteButton.Enabled = false;
+ Wizard.CancelButton.Visible = true;
+ ConfigurationResultLabel.Text = string.Empty;
+ RetryButton.Visible = false;
+
+ foreach (var configStepControl in ExecutionStepsTabPage.Controls.OfType())
+ {
+ configStepControl.SetStatus(ConfigStepControl.OPEN);
+ }
+
+ subCaptionLabel.Text = Resources.ConfigStepsAreExecuting;
+ if (Wizard is ConfigWizard configWizard)
+ {
+ CurrentController.ConfigurationType = configWizard.ConfigurationType;
+ }
- foreach (var configStepControl in ExecutionStepsTabPage.Controls.OfType())
+ CurrentController.Configure();
+ };
+
+ ExecuteLongRunningOperation(action, false, false);
+ }
+
+ ///
+ /// Subscribes custom events relavant to this wizard page.
+ ///
+ public override void SubscribeEvents()
+ {
+ base.SubscribeEvents();
+ if (CurrentController == null)
{
- configStepControl.SetStatus(ConfigStepControl.OPEN);
+ throw new ArgumentNullException(nameof(CurrentController));
}
- subCaptionLabel.Text = Resources.ConfigStepsAreExecuting;
- DetachEvents();
+ CurrentController.ConfigurationStarted += ConfigurationStarted;
CurrentController.ConfigurationEnded += ConfigurationEnded;
CurrentController.ConfigureTimedOut += ConfigureTimedOut;
CurrentController.ConfigurationStatusChanged += controller_ConfigurationStatusChanged;
- if (Wizard is ConfigWizard configWizard)
- {
- CurrentController.ConfigurationType = configWizard.ConfigurationType;
- }
-
- UpdateButtons();
-
- Wizard.BackButton.Visible = false;
- Wizard.ExecuteButton.Enabled = false;
- Wizard.CancelButton.Visible = true;
-
- CurrentController.Configure();
}
- protected override void DetachEvents()
+ ///
+ /// Unsubscribes custom events relavant to this wizard page.
+ ///
+ public override void UnsubscribeEvents()
{
+ base.UnsubscribeEvents();
+ if (CurrentController == null)
+ {
+ throw new ArgumentNullException(nameof(CurrentController));
+ }
+
+ CurrentController.ConfigurationStarted -= ConfigurationStarted;
CurrentController.ConfigurationEnded -= ConfigurationEnded;
CurrentController.ConfigureTimedOut -= ConfigureTimedOut;
CurrentController.ConfigurationStatusChanged -= controller_ConfigurationStatusChanged;
@@ -199,67 +215,86 @@ protected override void DetachEvents()
private void ConfigurationEnded(object sender, EventArgs e)
{
- Executing = false;
- subCaptionLabel.Text = Resources.ConfigStepsFinished;
- switch (CurrentController.CurrentState)
+ try
{
- case ConfigState.ConfigurationError:
- _callActivateOnExecute = true;
- ConfigurationResultLabel.Text = string.Format(Resources.ConfigureFailed, CurrentController.Package.NameWithVersion);
- RetryButton.Visible = true;
- Wizard.BackButton.Enabled = true;
- Wizard.BackButton.Visible = true;
-
- // Update step descriptions.
- var serverController = CurrentController as ServerConfigurationController;
- if (serverController != null)
- {
- var revertedSteps = serverController.RevertedSteps;
- if (revertedSteps == null)
- {
- break;
- }
-
- foreach (var revertedStep in revertedSteps)
+ subCaptionLabel.Text = Resources.ConfigStepsFinished;
+ switch (CurrentController.CurrentState)
+ {
+ case ConfigState.ConfigurationError:
+ _callActivateOnExecute = true;
+ ConfigurationResultLabel.Text = string.Format(Resources.ConfigureFailed, CurrentController.Package.NameWithVersion);
+ RetryButton.Visible = true;
+ Wizard.BackButton.Enabled = true;
+ Wizard.BackButton.Visible = true;
+
+ // Update step descriptions.
+ var serverController = CurrentController as ServerConfigurationController;
+ if (serverController != null)
{
- var control = ExecutionStepsTabPage.Controls.OfType().FirstOrDefault(configStepControl => configStepControl.Step.Description.Equals(revertedStep));
- if (control == null)
+ var revertedSteps = serverController.RevertedSteps;
+ if (revertedSteps == null)
{
- continue;
+ break;
}
- control.Label = $"{control.Step.Description} (REVERTED)";
- }
- }
+ foreach (var revertedStep in revertedSteps)
+ {
+ var control = ExecutionStepsTabPage.Controls.OfType().FirstOrDefault(configStepControl => configStepControl.Step.Description.Equals(revertedStep));
+ if (control == null)
+ {
+ continue;
+ }
- break;
+ control.Label = $"{control.Step.Description} (REVERTED)";
+ }
+ }
- case ConfigState.ConfigurationCancelled:
- _callActivateOnExecute = true;
- ConfigurationResultLabel.Text = string.Format(Resources.ConfigureCancelled, CurrentController.Package.NameWithVersion);
- RetryButton.Visible = true;
- break;
+ break;
+
+ case ConfigState.ConfigurationCancelled:
+ _callActivateOnExecute = true;
+ ConfigurationResultLabel.Text = string.Format(Resources.ConfigureCancelled, CurrentController.Package.NameWithVersion);
+ RetryButton.Visible = true;
+ break;
+
+ default:
+ _callActivateOnExecute = false;
+ ConfigurationResultLabel.Text = string.Format(Resources.ConfigureSuccess, CurrentController.Package.NameWithVersion);
+ ShowConfigurationSummaryTab();
+ Wizard.ExecuteButton.Visible = false;
+ Wizard.CancelButton.Visible = false;
+ Wizard.BackButton.Visible = false;
+ break;
+ }
- default:
- _callActivateOnExecute = false;
- ConfigurationResultLabel.Text = string.Format(Resources.ConfigureSuccess, CurrentController.Package.NameWithVersion);
- ShowConfigurationSummaryTab();
- Wizard.ExecuteButton.Visible = false;
- Wizard.CancelButton.Visible = false;
- Wizard.BackButton.Visible = false;
- break;
+ if (CurrentController.ConfigurationType == ConfigurationType.Reconfiguration
+ && CurrentController.RebootRequired)
+ {
+ ExecutionTabControl.Height -= RebootWhenDonePanel.Height;
+ RebootWhenDonePanel.Visible = true;
+ RebootWhenDoneCheckBox.Checked = true;
+ }
}
-
- if (CurrentController.ConfigurationType == ConfigurationType.Reconfiguration
- && CurrentController.RebootRequired)
+ finally
{
- ExecutionTabControl.Height -= RebootWhenDonePanel.Height;
- RebootWhenDonePanel.Visible = true;
- RebootWhenDoneCheckBox.Checked = true;
+ EndLongRunningOperation();
+ UpdateButtons();
+ Wizard.FinishButton.Visible = false;
}
+ }
+ ///
+ /// Event method triggered when the configuration operation starts.
+ ///
+ /// The sender object.
+ /// The evenet arugments.
+ private void ConfigurationStarted(object sender, EventArgs e)
+ {
+ BeginLongRunningOperation();
UpdateButtons();
- Wizard.FinishButton.Visible = false;
+ Wizard.BackButton.Visible = false;
+ Wizard.ExecuteButton.Enabled = false;
+ Wizard.CancelButton.Visible = true;
}
private void ConfigureTimedOut(object sender, EventArgs e)
diff --git a/Configurator/Wizards/ConfigWizard/ConfigCompletePage.cs b/Configurator/Wizards/ConfigWizard/ConfigCompletePage.cs
index 639945c..f58df06 100644
--- a/Configurator/Wizards/ConfigWizard/ConfigCompletePage.cs
+++ b/Configurator/Wizards/ConfigWizard/ConfigCompletePage.cs
@@ -62,7 +62,6 @@ public override bool BackOk
public override void Activate()
{
base.Activate();
- WorkDone = true; // This is the last page, no need to ask for confirmation to close.
if (!(Wizard is ConfigWizard configWizard))
{
return;
diff --git a/Configurator/Wizards/RemoveWizard/RemoveApplyPage.cs b/Configurator/Wizards/RemoveWizard/RemoveApplyPage.cs
index 2a09414..30aea4d 100644
--- a/Configurator/Wizards/RemoveWizard/RemoveApplyPage.cs
+++ b/Configurator/Wizards/RemoveWizard/RemoveApplyPage.cs
@@ -38,6 +38,7 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Core.Product;
using MySql.Configurator.Properties;
using MySql.Configurator.Wizards.Common;
+using Action = System.Action;
namespace MySql.Configurator.Wizards.RemoveWizard
{
@@ -178,7 +179,7 @@ public override void Activate()
public override bool Cancel()
{
if (PackageManager != null
- && Executing)
+ && !OperationExecuting)
{
PackageManager.Cancel();
}
@@ -192,30 +193,36 @@ public override bool Cancel()
///
public override void Execute()
{
- subCaptionLabel.Visible = false;
- Wizard.BackButton.Enabled = false;
- Wizard.ExecuteButton.Enabled = false;
-
- // Reset failed steps.
- foreach (var removeStepControl in RemoveStepsFlowLayoutPanel.Controls.OfType().Where(removeStepControl => removeStepControl.Controller.CurrentState == ConfigState.ConfigurationError))
+ Action action;
+ action = delegate
{
- removeStepControl.Controller.ResetState();
- removeStepControl.Step.Status = ConfigurationStepStatus.NotStarted;
- removeStepControl.SetStatus(ConfigStepControl.OPEN);
- if (removeStepControl.SubSteps == null
- || removeStepControl.SubSteps.Count == 0)
- {
- continue;
- }
+ subCaptionLabel.Visible = false;
+ Wizard.BackButton.Enabled = false;
+ Wizard.ExecuteButton.Enabled = false;
- foreach (var subStep in removeStepControl.SubSteps)
+ // Reset failed steps.
+ foreach (var removeStepControl in RemoveStepsFlowLayoutPanel.Controls.OfType().Where(removeStepControl => removeStepControl.Controller.CurrentState == ConfigState.ConfigurationError))
{
- subStep.Step.Status = ConfigurationStepStatus.NotStarted;
- subStep.SetStatus(ConfigStepControl.OPEN);
+ removeStepControl.Controller.ResetState();
+ removeStepControl.Step.Status = ConfigurationStepStatus.NotStarted;
+ removeStepControl.SetStatus(ConfigStepControl.OPEN);
+ if (removeStepControl.SubSteps == null
+ || removeStepControl.SubSteps.Count == 0)
+ {
+ continue;
+ }
+
+ foreach (var subStep in removeStepControl.SubSteps)
+ {
+ subStep.Step.Status = ConfigurationStepStatus.NotStarted;
+ subStep.SetStatus(ConfigStepControl.OPEN);
+ }
}
- }
- UninstallNextProduct();
+ UninstallNextProduct();
+ };
+
+ ExecuteLongRunningOperation(action, false, false);
}
///
@@ -307,12 +314,39 @@ public virtual void QueueFinished(object sender, EventArgs e)
}
///
- /// Unsubscribes events from the handlers.
+ /// Subscribes custom events relavant to this wizard page.
///
- protected override void DetachEvents()
+ public override void SubscribeEvents()
{
- if (_parentRemoveStepControl == null)
+ base.SubscribeEvents();
+ if (_parentRemoveStepControl == null
+ || _parentRemoveStepControl.Controller == null)
+ {
+ // We don't raise an exception because for this page the _parentRemoveStepControl
+ // is determined until the operation is ongoing and the control assinged
+ // to _parentRemoveStepControl changes based on the product currently being removed.
+ return;
+ }
+
+ _parentRemoveStepControl.Controller.ConfigurationStarted += ConfigurationStarted;
+ _parentRemoveStepControl.Controller.ConfigurationEnded += ConfigurationEnded;
+ _parentRemoveStepControl.Controller.ConfigureTimedOut += ConfigureTimedOut;
+ _parentRemoveStepControl.Controller.ConfigurationStatusChanged += controller_ConfigurationStatusChanged;
+ _parentRemoveStepControl.Controller.PackageUninstall += PackageUninstall;
+ }
+
+ ///
+ /// Unsubscribes custom events relavant to this wizard page.
+ ///
+ public override void UnsubscribeEvents()
+ {
+ base.UnsubscribeEvents();
+ if (_parentRemoveStepControl == null
+ || _parentRemoveStepControl.Controller == null)
{
+ // We don't raise an exception because for this page the _parentRemoveStepControl
+ // is determined until the operation is ongoing and the control assinged
+ // to _parentRemoveStepControl changes based on the product currently being removed.
return;
}
@@ -415,7 +449,6 @@ private void CollapseButton_Click(object sender, EventArgs e)
/// The instance containing the event data.
private void ConfigurationEnded(object sender, EventArgs e)
{
- Executing = false;
_currentProgress = 100;
SetProgress(100);
@@ -450,6 +483,7 @@ private void ConfigurationStarted(object sender, EventArgs e)
return;
}
+ BeginLongRunningOperation();
_currentProgress = 0;
var stepCount = _parentRemoveStepControl.SubSteps == null
|| _parentRemoveStepControl.SubSteps.Count == 0
@@ -806,55 +840,61 @@ private void StartStep(BaseStep step, string message)
///
private void TerminateUninstallOperation()
{
- subCaptionLabel.Text = Resources.RemoveStepsFinished;
- if (RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control =>
- control.Controller.CurrentState == ConfigState.ConfigurationCancelled
- || control.Controller.CurrentState == ConfigState.ConfigurationError))
+ try
{
- ConfigurationResultLabel.Text = Resources.RemoveFailed;
- RetryButton.Visible = true;
- RebootWhenDonePanel.Visible = true;
- RebootWhenDoneCheckBox.Visible = false;
- RebootWhenDoneLabel.Visible = false;
- Wizard.BackButton.Enabled = true;
- Wizard.BackButton.Visible = true;
- }
- else
- {
- ConfigurationResultLabel.Text = RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control =>
- control.HasFailedSubSteps(false) == true)
- ? Resources.RemoveSuccessWithErrors
- : Resources.RemoveSuccess;
- RetryButton.Visible = false;
- RebootWhenDonePanel.Visible = false;
- Wizard.ExecuteButton.Visible = false;
- Wizard.CancelButton.Visible = false;
- Wizard.BackButton.Visible = false;
- Wizard.FinishButton.Visible = true;
- RemoveStepsFlowLayoutPanel.Height -= HEIGHT_REDUCED_WHEN_UNINSTALL_COMPLETE;
- }
-
- if (UninstallInstallerPanel.Visible)
- {
- ExecutionTabControl.Height -= HEIGHT_REDUCED_WHEN_UNINSTALL_COMPLETE;
- }
-
- if (RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control => control.Controller.RebootRequired))
- {
- RebootWhenDonePanel.Visible = true;
- RebootWhenDoneCheckBox.Visible = true;
- RebootWhenDoneLabel.Visible = true;
- RebootWhenDoneCheckBox.Checked = true;
- ToolTip.SetToolTip(RebootWhenDoneCheckBox, GetRebootWhenDoneCheckBoxToolTip());
+ subCaptionLabel.Text = Resources.RemoveStepsFinished;
+ if (RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control =>
+ control.Controller.CurrentState == ConfigState.ConfigurationCancelled
+ || control.Controller.CurrentState == ConfigState.ConfigurationError))
+ {
+ ConfigurationResultLabel.Text = Resources.RemoveFailed;
+ RetryButton.Visible = true;
+ RebootWhenDonePanel.Visible = true;
+ RebootWhenDoneCheckBox.Visible = false;
+ RebootWhenDoneLabel.Visible = false;
+ Wizard.BackButton.Enabled = true;
+ Wizard.BackButton.Visible = true;
+ }
+ else
+ {
+ ConfigurationResultLabel.Text = RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control =>
+ control.HasFailedSubSteps(false) == true)
+ ? Resources.RemoveSuccessWithErrors
+ : Resources.RemoveSuccess;
+ RetryButton.Visible = false;
+ RebootWhenDonePanel.Visible = false;
+ Wizard.ExecuteButton.Visible = false;
+ Wizard.CancelButton.Visible = false;
+ Wizard.BackButton.Visible = false;
+ Wizard.FinishButton.Visible = true;
+ RemoveStepsFlowLayoutPanel.Height -= HEIGHT_REDUCED_WHEN_UNINSTALL_COMPLETE;
+ }
if (UninstallInstallerPanel.Visible)
{
ExecutionTabControl.Height -= HEIGHT_REDUCED_WHEN_UNINSTALL_COMPLETE;
- RebootWhenDonePanel.Location = new Point(RebootWhenDonePanel.Location.X, ExecutionTabControl.Location.Y + ExecutionTabControl.Height + 5);
}
- }
- Wizard.FinishButton.Enabled = FinishOk;
+ if (RemoveStepsFlowLayoutPanel.Controls.OfType().Any(control => control.Controller.RebootRequired))
+ {
+ RebootWhenDonePanel.Visible = true;
+ RebootWhenDoneCheckBox.Visible = true;
+ RebootWhenDoneLabel.Visible = true;
+ RebootWhenDoneCheckBox.Checked = true;
+ ToolTip.SetToolTip(RebootWhenDoneCheckBox, GetRebootWhenDoneCheckBoxToolTip());
+
+ if (UninstallInstallerPanel.Visible)
+ {
+ ExecutionTabControl.Height -= HEIGHT_REDUCED_WHEN_UNINSTALL_COMPLETE;
+ RebootWhenDonePanel.Location = new Point(RebootWhenDonePanel.Location.X, ExecutionTabControl.Location.Y + ExecutionTabControl.Height + 5);
+ }
+ }
+ }
+ finally
+ {
+ EndLongRunningOperation();
+ Wizard.FinishButton.Enabled = FinishOk;
+ }
}
///
@@ -863,7 +903,7 @@ private void TerminateUninstallOperation()
///
private bool UninstallNextProduct()
{
- DetachEvents();
+ UnsubscribeEvents();
var parentRemoveStepControl = RemoveStepsFlowLayoutPanel.Controls.OfType().FirstOrDefault(removeStepControl =>
removeStepControl.Step.Status == ConfigurationStepStatus.NotStarted
&& removeStepControl.Controller.CurrentState != ConfigState.ConfigurationError);
@@ -874,12 +914,12 @@ private bool UninstallNextProduct()
_parentRemoveStepControl = parentRemoveStepControl;
CurrentController = _parentRemoveStepControl.Controller;
- Executing = true;
CurrentController.ConfigurationStarted += ConfigurationStarted;
CurrentController.ConfigurationEnded += ConfigurationEnded;
CurrentController.ConfigureTimedOut += ConfigureTimedOut;
CurrentController.ConfigurationStatusChanged += controller_ConfigurationStatusChanged;
CurrentController.PackageUninstall += PackageUninstall;
+ SubscribeEvents();
CurrentController.Remove();
return true;
}
diff --git a/Configurator/Wizards/RemoveWizard/RemoveProductsWizard.cs b/Configurator/Wizards/RemoveWizard/RemoveProductsWizard.cs
index 5193e40..b5da66d 100644
--- a/Configurator/Wizards/RemoveWizard/RemoveProductsWizard.cs
+++ b/Configurator/Wizards/RemoveWizard/RemoveProductsWizard.cs
@@ -90,8 +90,6 @@ public void ShowWizard(Package package, MainForm parentMainForm)
WizardSideBar.ShowConfigPanel(package.NameWithVersion);
ClearPages();
package.Controller.ConfigurationType = ConfigurationType.Remove;
- package.Controller.UpdateRemoveSteps();
- package.Controller.SetPages();
var serverController = package.Controller as ServerConfigurationController;
if (serverController == null)
{
@@ -105,6 +103,8 @@ public void ShowWizard(Package package, MainForm parentMainForm)
return;
}
+ package.Controller.UpdateRemoveSteps();
+ package.Controller.SetPages();
ProductsToRemove.Add(package);
foreach (var page in package.Controller.Pages.Where(page => page.ValidForType(package.Controller.ConfigurationType)))
{
diff --git a/Configurator/Wizards/Server/MySqlServerSettings.cs b/Configurator/Wizards/Server/MySqlServerSettings.cs
index f75eca0..00cfd13 100644
--- a/Configurator/Wizards/Server/MySqlServerSettings.cs
+++ b/Configurator/Wizards/Server/MySqlServerSettings.cs
@@ -64,6 +64,7 @@ public MySqlServerSettings(Package p)
{
NewServerUsers = new List();
Plugins = new PluginsList(p.Version);
+ ServerInstallationType = ServerInstallationType.Developer;
}
#region Properties
@@ -217,7 +218,7 @@ public MySqlServerSettings(Package p)
[ControllerSetting("Optimizes settings depending on the intended use of the server instance.", "server_type", "servertype")]
[DefaultValue(ServerInstallationType.Developer)]
- public ServerInstallationType ServerInstallType { get; set; }
+ public ServerInstallationType ServerInstallationType { get; set; }
[ControllerSetting("The password of the Windows User Account used to run the Windows Service. Ignored if " +
"as_windows_service is false or if windows_service_user is not present.", "windows_service_password,win_service_pwd", "sapass")]
@@ -285,7 +286,7 @@ public void Save(IniTemplate template, bool skipExistingValues = false)
throw new Exception(Resources.InvalidServerTemplate);
}
- template.ServerType = ServerInstallType;
+ template.ServerInstallationType = ServerInstallationType;
template.EnableNetworking = EnableTcpIp;
template.Port = Port;
template.EnableNamedPipe = EnableNamedPipe;
@@ -310,7 +311,7 @@ public void Save(IniTemplate template, bool skipExistingValues = false)
template.LowerCaseTableNames = LowerCaseTableNames;
template.SecureFilePriv = string.IsNullOrEmpty(SecureFilePrivFolder) ? string.Empty : $"\"{SecureFilePrivFolder.Replace('\\', '/')}\"";
template.PluginLoad = string.IsNullOrEmpty(Plugins.ToString()) ? string.Empty : $"\"{Plugins}\"";
- template.LooseMySqlXPort = MySqlXPort == 0 ? X_PROTOCOL_DEFAULT_PORT : MySqlXPort;
+ template.MySqlXPort = MySqlXPort == 0 ? X_PROTOCOL_DEFAULT_PORT : MySqlXPort;
template.NamedPipeFullAccessGroup = NamedPipeFullAccessGroup;
template.ProcessTemplate(false, true, skipExistingValues);
SaveGeneralSettings();
@@ -383,7 +384,7 @@ public IniTemplate GetExistingIniFileTemplate()
if (configFileExists.HasValue && configFileExists.Value)
{
- t = new IniTemplate(InstallDirectory, DataDirectory, FullConfigFilePath, Package.Version, ServerInstallType, null);
+ t = new IniTemplate(InstallDirectory, DataDirectory, FullConfigFilePath, Package.Version, ServerInstallationType, null);
}
else
{
@@ -438,7 +439,7 @@ private void LoadIniSettings()
var iniFile = new IniFileEngine(fullIniPath).Load();
Logger.LogInformation("Server Settings - Load Ini Settings - IniTemplate Parsing");
- var t = new IniTemplate(Package.Version, ServerInstallType);
+ var t = new IniTemplate(Package.Version, ServerInstallationType);
t.ParseConfigurationFile(fullIniPath);
Logger.LogInformation("Server Settings - Load Ini Settings - getting settings from IniTemplate");
@@ -453,8 +454,14 @@ private void LoadIniSettings()
NamedPipeFullAccessGroup = t.NamedPipeFullAccessGroup;
Logger.LogInformation("Server Settings - Load Ini Settings - getting settings from IniFileEngine");
+
+
+ // Attempt to read the server installation type from the ini file for old configurations.
+ // Value is ignored if the extended settings file already contains an entry for the server installation type.
var serverType = iniFile.FindValue("mysql", "server_type", true);
- ServerInstallType = serverType == 1
+ if (serverType != 0)
+ {
+ ServerInstallationType = serverType == 1
? ServerInstallationType.Dedicated
: serverType == 2
? ServerInstallationType.Server
@@ -463,8 +470,9 @@ private void LoadIniSettings()
: serverType == 4
? ServerInstallationType.Manual
: ServerInstallationType.Developer;
- OpenFirewall = EnableTcpIp && IsRuleEnabled(Port.ToString());
+ }
+ OpenFirewall = EnableTcpIp && IsRuleEnabled(Port.ToString());
ErrorLogFileName = iniFile.FindValue("mysqld", "log-error", false);
EnableGeneralLog = iniFile.FindValue("mysqld", "general-log", false);
GeneralQueryLogFileName = iniFile.FindValue("mysqld", "general_log_file", false);
diff --git a/Configurator/Wizards/Server/MysqlSCM.cs b/Configurator/Wizards/Server/MysqlSCM.cs
index a18d536..5a6799a 100644
--- a/Configurator/Wizards/Server/MysqlSCM.cs
+++ b/Configurator/Wizards/Server/MysqlSCM.cs
@@ -414,7 +414,7 @@ public static void Restart(string serviceName, CancellationToken cancellationTok
public static bool ServiceExists(string serviceName)
{
var services = ServiceController.GetServices();
- var service = services.FirstOrDefault(s => s.ServiceName == serviceName);
+ var service = services.FirstOrDefault(s => s.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase));
return service != null;
}
diff --git a/Configurator/Wizards/Server/ServerConfigBackupPage.Designer.cs b/Configurator/Wizards/Server/ServerConfigBackupPage.Designer.cs
index 51b4a9e..a245182 100644
--- a/Configurator/Wizards/Server/ServerConfigBackupPage.Designer.cs
+++ b/Configurator/Wizards/Server/ServerConfigBackupPage.Designer.cs
@@ -56,13 +56,22 @@ private void InitializeComponent()
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ServerConfigBackupPage));
this.UpgradeDatabaseFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
this.UpgradeExternalPanel = new System.Windows.Forms.Panel();
- this.SkipBackupRadioButton = new System.Windows.Forms.RadioButton();
- this.RunBackupRadioButton = new System.Windows.Forms.RadioButton();
this.BackupDatabaseLabel = new System.Windows.Forms.Label();
+ this.RunBackupRadioButton = new System.Windows.Forms.RadioButton();
+ this.CredentialsPanel = new System.Windows.Forms.Panel();
+ this.ConnectDescriptionLabel = new System.Windows.Forms.Label();
+ this.ResultLabel = new System.Windows.Forms.Label();
+ this.RootUserLabel = new System.Windows.Forms.Label();
+ this.PasswordTextBox = new System.Windows.Forms.TextBox();
+ this.ConnectButton = new System.Windows.Forms.Button();
+ this.UserLabel = new System.Windows.Forms.Label();
+ this.RootPasswordLabel = new System.Windows.Forms.Label();
+ this.SkipBackupRadioButton = new System.Windows.Forms.RadioButton();
this.ConnectionErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
((System.ComponentModel.ISupportInitialize)(this.ValidationsErrorProvider)).BeginInit();
this.UpgradeDatabaseFlowLayoutPanel.SuspendLayout();
this.UpgradeExternalPanel.SuspendLayout();
+ this.CredentialsPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.ConnectionErrorProvider)).BeginInit();
this.SuspendLayout();
//
@@ -84,12 +93,15 @@ private void InitializeComponent()
//
this.UpgradeDatabaseFlowLayoutPanel.AccessibleDescription = "A panel containing inner panels with options appearing depending on the upgrading" +
" process handled by MySQL Server.";
- this.UpgradeDatabaseFlowLayoutPanel.AccessibleName = "Upgrade Database Flow Panel";
+ this.UpgradeDatabaseFlowLayoutPanel.AccessibleName = "Upgrade database flow layout";
this.UpgradeDatabaseFlowLayoutPanel.Controls.Add(this.UpgradeExternalPanel);
+ this.UpgradeDatabaseFlowLayoutPanel.Controls.Add(this.RunBackupRadioButton);
+ this.UpgradeDatabaseFlowLayoutPanel.Controls.Add(this.CredentialsPanel);
+ this.UpgradeDatabaseFlowLayoutPanel.Controls.Add(this.SkipBackupRadioButton);
this.UpgradeDatabaseFlowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
- this.UpgradeDatabaseFlowLayoutPanel.Location = new System.Drawing.Point(3, 58);
+ this.UpgradeDatabaseFlowLayoutPanel.Location = new System.Drawing.Point(27, 58);
this.UpgradeDatabaseFlowLayoutPanel.Name = "UpgradeDatabaseFlowLayoutPanel";
- this.UpgradeDatabaseFlowLayoutPanel.Size = new System.Drawing.Size(563, 510);
+ this.UpgradeDatabaseFlowLayoutPanel.Size = new System.Drawing.Size(514, 510);
this.UpgradeDatabaseFlowLayoutPanel.TabIndex = 1;
//
// UpgradeExternalPanel
@@ -97,58 +109,166 @@ private void InitializeComponent()
this.UpgradeExternalPanel.AccessibleDescription = "A panel containing controls for upgrading the system tables calling the external " +
"mysql_upgrade cllient.";
this.UpgradeExternalPanel.AccessibleName = "Upgrade External Group";
- this.UpgradeExternalPanel.Controls.Add(this.SkipBackupRadioButton);
- this.UpgradeExternalPanel.Controls.Add(this.RunBackupRadioButton);
this.UpgradeExternalPanel.Controls.Add(this.BackupDatabaseLabel);
this.UpgradeExternalPanel.Location = new System.Drawing.Point(3, 3);
this.UpgradeExternalPanel.Name = "UpgradeExternalPanel";
- this.UpgradeExternalPanel.Size = new System.Drawing.Size(560, 212);
+ this.UpgradeExternalPanel.Size = new System.Drawing.Size(511, 67);
this.UpgradeExternalPanel.TabIndex = 6;
//
- // SkipBackupRadioButton
+ // BackupDatabaseLabel
//
- this.SkipBackupRadioButton.AccessibleDescription = "An option to replace a selected MySQL Server installation, meaning its data direc" +
- "tory will be used for the installation being configured.";
- this.SkipBackupRadioButton.AccessibleName = "Replace MySQL Server installation option";
- this.SkipBackupRadioButton.AutoSize = true;
- this.SkipBackupRadioButton.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.SkipBackupRadioButton.Location = new System.Drawing.Point(26, 112);
- this.SkipBackupRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
- this.SkipBackupRadioButton.Name = "SkipBackupRadioButton";
- this.SkipBackupRadioButton.Size = new System.Drawing.Size(360, 29);
- this.SkipBackupRadioButton.TabIndex = 6;
- this.SkipBackupRadioButton.Text = "No thanks, I have already run a backup";
- this.SkipBackupRadioButton.UseVisualStyleBackColor = true;
+ this.BackupDatabaseLabel.AccessibleDescription = "A label displaying instructions about backing up the database before running the " +
+ "upgrade process";
+ this.BackupDatabaseLabel.AccessibleName = "Backup MySQL databases description";
+ this.BackupDatabaseLabel.Font = new System.Drawing.Font("Segoe UI", 9F);
+ this.BackupDatabaseLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
+ this.BackupDatabaseLabel.Location = new System.Drawing.Point(-1, 10);
+ this.BackupDatabaseLabel.Name = "BackupDatabaseLabel";
+ this.BackupDatabaseLabel.Size = new System.Drawing.Size(520, 79);
+ this.BackupDatabaseLabel.TabIndex = 0;
+ this.BackupDatabaseLabel.Text = resources.GetString("BackupDatabaseLabel.Text");
//
// RunBackupRadioButton
//
- this.RunBackupRadioButton.AccessibleDescription = "An option to replace a selected MySQL Server installation, meaning its data direc" +
- "tory will be used for the installation being configured.";
- this.RunBackupRadioButton.AccessibleName = "Replace MySQL Server installation option";
+ this.RunBackupRadioButton.AccessibleDescription = "An option to specify that a backup";
+ this.RunBackupRadioButton.AccessibleName = "Backup databses using mysqldump option";
this.RunBackupRadioButton.AutoSize = true;
this.RunBackupRadioButton.Checked = true;
this.RunBackupRadioButton.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.RunBackupRadioButton.Location = new System.Drawing.Point(26, 79);
+ this.RunBackupRadioButton.Location = new System.Drawing.Point(4, 78);
this.RunBackupRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.RunBackupRadioButton.Name = "RunBackupRadioButton";
this.RunBackupRadioButton.Size = new System.Drawing.Size(402, 29);
- this.RunBackupRadioButton.TabIndex = 5;
+ this.RunBackupRadioButton.TabIndex = 1;
this.RunBackupRadioButton.TabStop = true;
this.RunBackupRadioButton.Text = "Run a mysqldump backup prior to upgrade";
this.RunBackupRadioButton.UseVisualStyleBackColor = true;
+ this.RunBackupRadioButton.CheckedChanged += new System.EventHandler(this.BackupDatabaseCheckBox_CheckedChanged);
+ this.RunBackupRadioButton.Validated += new System.EventHandler(this.ValidatedHandler);
//
- // BackupDatabaseLabel
+ // CredentialsPanel
//
- this.BackupDatabaseLabel.AccessibleDescription = "A label displaying instructions about backing up the database before running the " +
- "upgrade process";
- this.BackupDatabaseLabel.AccessibleName = "Backup MySQL Database Description";
- this.BackupDatabaseLabel.Font = new System.Drawing.Font("Segoe UI", 9F);
- this.BackupDatabaseLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
- this.BackupDatabaseLabel.Location = new System.Drawing.Point(21, 4);
- this.BackupDatabaseLabel.Name = "BackupDatabaseLabel";
- this.BackupDatabaseLabel.Size = new System.Drawing.Size(520, 79);
- this.BackupDatabaseLabel.TabIndex = 0;
- this.BackupDatabaseLabel.Text = resources.GetString("BackupDatabaseLabel.Text");
+ this.CredentialsPanel.AccessibleDescription = "A panel containing the controls to connect to the MySQL Server instance that is b" +
+ "eing upgraded.";
+ this.CredentialsPanel.AccessibleName = "Credentials";
+ this.CredentialsPanel.Controls.Add(this.ConnectDescriptionLabel);
+ this.CredentialsPanel.Controls.Add(this.ResultLabel);
+ this.CredentialsPanel.Controls.Add(this.RootUserLabel);
+ this.CredentialsPanel.Controls.Add(this.PasswordTextBox);
+ this.CredentialsPanel.Controls.Add(this.ConnectButton);
+ this.CredentialsPanel.Controls.Add(this.UserLabel);
+ this.CredentialsPanel.Controls.Add(this.RootPasswordLabel);
+ this.CredentialsPanel.Location = new System.Drawing.Point(3, 115);
+ this.CredentialsPanel.Name = "CredentialsPanel";
+ this.CredentialsPanel.Size = new System.Drawing.Size(511, 151);
+ this.CredentialsPanel.TabIndex = 9;
+ //
+ // ConnectDescriptionLabel
+ //
+ this.ConnectDescriptionLabel.AccessibleDescription = "A label displaying a description about the need to provide the credentials for th" +
+ "e root user.";
+ this.ConnectDescriptionLabel.AccessibleName = "Need for credentials description";
+ this.ConnectDescriptionLabel.Font = new System.Drawing.Font("Segoe UI", 9F);
+ this.ConnectDescriptionLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
+ this.ConnectDescriptionLabel.Location = new System.Drawing.Point(17, 3);
+ this.ConnectDescriptionLabel.Name = "ConnectDescriptionLabel";
+ this.ConnectDescriptionLabel.Size = new System.Drawing.Size(494, 44);
+ this.ConnectDescriptionLabel.TabIndex = 9;
+ this.ConnectDescriptionLabel.Text = "To create the backup, a connection to the MySQL Server instance must be made. Ple" +
+ "ase provide the password for the root user and then click the Connect button:";
+ //
+ // ResultLabel
+ //
+ this.ResultLabel.AccessibleDescription = "A label displaying the result of the root credentials check";
+ this.ResultLabel.AccessibleName = "Root Credentials Check Result";
+ this.ResultLabel.AutoSize = true;
+ this.ResultLabel.Location = new System.Drawing.Point(146, 116);
+ this.ResultLabel.Name = "ResultLabel";
+ this.ResultLabel.Size = new System.Drawing.Size(0, 25);
+ this.ResultLabel.TabIndex = 7;
+ //
+ // RootUserLabel
+ //
+ this.RootUserLabel.AccessibleDescription = "A text with the word root";
+ this.RootUserLabel.AccessibleName = "Root text";
+ this.RootUserLabel.AutoSize = true;
+ this.RootUserLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.RootUserLabel.Location = new System.Drawing.Point(88, 48);
+ this.RootUserLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.RootUserLabel.Name = "RootUserLabel";
+ this.RootUserLabel.Size = new System.Drawing.Size(46, 25);
+ this.RootUserLabel.TabIndex = 3;
+ this.RootUserLabel.Text = "root";
+ //
+ // PasswordTextBox
+ //
+ this.PasswordTextBox.AccessibleDescription = "A field to input the password of the root user.";
+ this.PasswordTextBox.AccessibleName = "Root password";
+ this.PasswordTextBox.Location = new System.Drawing.Point(90, 73);
+ this.PasswordTextBox.Name = "PasswordTextBox";
+ this.PasswordTextBox.PasswordChar = '*';
+ this.PasswordTextBox.Size = new System.Drawing.Size(126, 31);
+ this.PasswordTextBox.TabIndex = 5;
+ this.PasswordTextBox.TextChanged += new System.EventHandler(this.TextChangedHandler);
+ this.PasswordTextBox.Validated += new System.EventHandler(this.ValidatedHandler);
+ //
+ // ConnectButton
+ //
+ this.ConnectButton.AccessibleDescription = "A button to connect to the existing MySQL Server instance.";
+ this.ConnectButton.AccessibleName = "Connect";
+ this.ConnectButton.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.ConnectButton.Location = new System.Drawing.Point(20, 110);
+ this.ConnectButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.ConnectButton.Name = "ConnectButton";
+ this.ConnectButton.Size = new System.Drawing.Size(97, 28);
+ this.ConnectButton.TabIndex = 6;
+ this.ConnectButton.Text = "Connect";
+ this.ToolTip.SetToolTip(this.ConnectButton, "Tests the connection to the MySQL Server installation to upgrade.");
+ this.ConnectButton.UseVisualStyleBackColor = true;
+ this.ConnectButton.Click += new System.EventHandler(this.ConnectButton_Click);
+ //
+ // UserLabel
+ //
+ this.UserLabel.AccessibleDescription = "A text to specify the user that will connect to the MySQL Server instance.";
+ this.UserLabel.AccessibleName = "User text";
+ this.UserLabel.AutoSize = true;
+ this.UserLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.UserLabel.Location = new System.Drawing.Point(18, 48);
+ this.UserLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.UserLabel.Name = "UserLabel";
+ this.UserLabel.Size = new System.Drawing.Size(51, 25);
+ this.UserLabel.TabIndex = 2;
+ this.UserLabel.Text = "User:";
+ //
+ // RootPasswordLabel
+ //
+ this.RootPasswordLabel.AccessibleDescription = "A text to ask for the password of the root user.";
+ this.RootPasswordLabel.AccessibleName = "Root password text";
+ this.RootPasswordLabel.AutoSize = true;
+ this.RootPasswordLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.RootPasswordLabel.Location = new System.Drawing.Point(18, 77);
+ this.RootPasswordLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ this.RootPasswordLabel.Name = "RootPasswordLabel";
+ this.RootPasswordLabel.Size = new System.Drawing.Size(91, 25);
+ this.RootPasswordLabel.TabIndex = 4;
+ this.RootPasswordLabel.Text = "Password:";
+ //
+ // SkipBackupRadioButton
+ //
+ this.SkipBackupRadioButton.AccessibleDescription = "An option to replace a selected MySQL Server installation, meaning its data direc" +
+ "tory will be used for the installation being configured.";
+ this.SkipBackupRadioButton.AccessibleName = "Skip backup option";
+ this.SkipBackupRadioButton.AutoSize = true;
+ this.SkipBackupRadioButton.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.SkipBackupRadioButton.Location = new System.Drawing.Point(4, 274);
+ this.SkipBackupRadioButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.SkipBackupRadioButton.Name = "SkipBackupRadioButton";
+ this.SkipBackupRadioButton.Size = new System.Drawing.Size(370, 29);
+ this.SkipBackupRadioButton.TabIndex = 8;
+ this.SkipBackupRadioButton.Text = "No thanks, I have already run a backup";
+ this.SkipBackupRadioButton.UseVisualStyleBackColor = true;
+ this.SkipBackupRadioButton.CheckedChanged += new System.EventHandler(this.BackupDatabaseCheckBox_CheckedChanged);
+ this.SkipBackupRadioButton.Validated += new System.EventHandler(this.ValidatedHandler);
//
// ConnectionErrorProvider
//
@@ -157,9 +277,8 @@ private void InitializeComponent()
//
// ServerConfigBackupPage
//
- this.AccessibleDescription = "A configuration wizard page to upgrade the database upon a server upgrade or recr" +
- "eate an existing sandbox cluster";
- this.AccessibleName = "Check And Upgrade Database Page";
+ this.AccessibleDescription = "A configuration wizard page to backup the existing databases";
+ this.AccessibleName = "Backup Page";
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Caption = "Backup Data";
this.Controls.Add(this.UpgradeDatabaseFlowLayoutPanel);
@@ -172,8 +291,10 @@ private void InitializeComponent()
this.Controls.SetChildIndex(this.captionLabel, 0);
((System.ComponentModel.ISupportInitialize)(this.ValidationsErrorProvider)).EndInit();
this.UpgradeDatabaseFlowLayoutPanel.ResumeLayout(false);
+ this.UpgradeDatabaseFlowLayoutPanel.PerformLayout();
this.UpgradeExternalPanel.ResumeLayout(false);
- this.UpgradeExternalPanel.PerformLayout();
+ this.CredentialsPanel.ResumeLayout(false);
+ this.CredentialsPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.ConnectionErrorProvider)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -186,7 +307,15 @@ private void InitializeComponent()
private System.Windows.Forms.Panel UpgradeExternalPanel;
private System.Windows.Forms.Label BackupDatabaseLabel;
private System.Windows.Forms.ErrorProvider ConnectionErrorProvider;
- private System.Windows.Forms.RadioButton SkipBackupRadioButton;
private System.Windows.Forms.RadioButton RunBackupRadioButton;
+ private System.Windows.Forms.Panel CredentialsPanel;
+ private System.Windows.Forms.Label UserLabel;
+ private System.Windows.Forms.Label RootPasswordLabel;
+ private System.Windows.Forms.RadioButton SkipBackupRadioButton;
+ private System.Windows.Forms.Button ConnectButton;
+ private System.Windows.Forms.TextBox PasswordTextBox;
+ private System.Windows.Forms.Label RootUserLabel;
+ private System.Windows.Forms.Label ResultLabel;
+ private System.Windows.Forms.Label ConnectDescriptionLabel;
}
}
diff --git a/Configurator/Wizards/Server/ServerConfigBackupPage.cs b/Configurator/Wizards/Server/ServerConfigBackupPage.cs
index d1ea970..ec4ed4d 100644
--- a/Configurator/Wizards/Server/ServerConfigBackupPage.cs
+++ b/Configurator/Wizards/Server/ServerConfigBackupPage.cs
@@ -22,7 +22,12 @@ You should have received a copy of the GNU General Public License
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
using System;
+using MySql.Configurator.Core.Classes;
+using MySql.Configurator.Core.Enums;
+using System.Windows.Forms;
using MySql.Configurator.Core.Wizard;
+using MySql.Configurator.Properties;
+using Action = System.Action;
namespace MySql.Configurator.Wizards.Server
{
@@ -33,6 +38,11 @@ public partial class ServerConfigBackupPage : ConfigWizardPage
{
#region Fields
+ ///
+ /// The connection result obtained when pressing the Connect button.
+ ///
+ private ConnectionResultType _connectionResult;
+
///
/// The used to perform actions.
///
@@ -48,6 +58,7 @@ public ServerConfigBackupPage(ServerConfigurationController controller)
{
BackupDatabase = true;
InitializeComponent();
+ _connectionResult = ConnectionResultType.None;
_controller = controller;
}
@@ -58,6 +69,16 @@ public ServerConfigBackupPage(ServerConfigurationController controller)
///
public bool BackupDatabase { get; private set; }
+ ///
+ /// Gets a value indicating if it is allowed to go to the next configuration page.
+ ///
+ public override bool NextOk => ((_controller.IsSameDirectoryUpgrade
+ && ((RunBackupRadioButton.Checked
+ && _connectionResult == ConnectionResultType.ConnectionSuccess)
+ || SkipBackupRadioButton.Checked))
+ || !_controller.IsSameDirectoryUpgrade)
+ && base.NextOk;
+
#endregion Properties
///
@@ -65,6 +86,7 @@ public ServerConfigBackupPage(ServerConfigurationController controller)
///
public override void Activate()
{
+ CredentialsPanel.Visible = !_controller.RootUserCredentialsSet;
base.Activate();
}
@@ -76,17 +98,96 @@ public override bool Next()
{
_controller.IsBackupDatabaseStepNeeded = RunBackupRadioButton.Checked;
_controller.UpdateUpgradeConfigSteps();
+ if (!_controller.RootUserCredentialsSet)
+ {
+ _controller.Settings.ExistingRootPassword = PasswordTextBox.Text;
+ }
+
return base.Next();
}
///
/// Event delegate method fired when the checked property changes.
///
- /// Sender object.
- /// Event arguments.
+ /// The sender object.
+ /// The event arguments.
private void BackupDatabaseCheckBox_CheckedChanged(object sender, EventArgs e)
{
BackupDatabase = RunBackupRadioButton.Checked;
+ ValidationsErrorProvider.Clear();
+ ValidatedHandler(sender, e);
+ }
+
+ ///
+ /// Event delegate method fired when the Connect button is clicked.
+ ///
+ /// The sender object.
+ /// The event arguments.
+ private void ConnectButton_Click(object sender, EventArgs e)
+ {
+ Action action;
+ action = delegate
+ {
+ ResultLabel.Text = Resources.StartingServerAndTestingConnection;
+ var providerProperties = new ErrorProviderProperties(Resources.StartingServerAndTestingConnection, Resources.Config_InProgressIcon, true);
+ ConnectionErrorProvider.SetProperties(ConnectButton, providerProperties);
+ _connectionResult = LocalServerInstance.CanConnect(_controller, out string errorMessage, PasswordTextBox.Text, true, true);
+ providerProperties.ErrorMessage = string.IsNullOrEmpty(errorMessage)
+ ? _connectionResult.GetDescription()
+ : errorMessage;
+ providerProperties.ErrorIcon = _connectionResult == ConnectionResultType.ConnectionSuccess
+ ? Resources.Config_DoneIcon
+ : Resources.Config_ErrorIcon;
+ ConnectionErrorProvider.SetProperties(ConnectButton, providerProperties);
+ ResultLabel.Text = providerProperties.ErrorMessage;
+ UpdateButtons();
+ };
+
+ ExecuteLongRunningOperation(action);
+ }
+
+ ///
+ /// Handles the TextChanged event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected override void TextChangedHandler(object sender, EventArgs e)
+ {
+ // Looks like we could get rid of this empty override, but it is necessary to avoid an error of:
+ // The method 'xxx' cannot be the method for an event because a class this class derives from already defines the method
+ base.TextChangedHandler(sender, e);
+ }
+
+ ///
+ /// Handles the TextValidated event.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ /// This event method is meant to be used with the event.
+ protected override void ValidatedHandler(object sender, EventArgs e)
+ {
+ // Looks like we could get rid of this empty override, but it is necessary to avoid an error of:
+ // The method 'xxx' cannot be the method for an event because a class this class derives from already defines the method
+ base.ValidatedHandler(sender, e);
+ }
+
+ ///
+ /// Contains calls to methods that validate the given control's value.
+ ///
+ /// An error message or null / if everything is valid.
+ protected override string ValidateFields()
+ {
+ string errorMessage = base.ValidateFields();
+ switch (ErrorProviderControl.Name)
+ {
+ case nameof(PasswordTextBox):
+ _connectionResult = ConnectionResultType.None;
+ ConnectionErrorProvider.Clear();
+ ResultLabel.Text = string.Empty;
+ break;
+ }
+
+ return errorMessage;
}
}
}
diff --git a/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.Designer.cs b/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.Designer.cs
index 2b699bf..1a472e7 100644
--- a/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.Designer.cs
+++ b/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.Designer.cs
@@ -128,7 +128,6 @@ private void InitializeComponent()
// DataDirectoryBrowserDialog
//
this.DataDirectoryBrowserDialog.Description = "Select the MySQL Server data directory";
- this.DataDirectoryBrowserDialog.RootFolder = System.Environment.SpecialFolder.CommonApplicationData;
//
// ServerConfigDataDirectoryPage
//
diff --git a/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.cs b/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.cs
index 88469ab..1ac6de3 100644
--- a/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.cs
+++ b/Configurator/Wizards/Server/ServerConfigDataDirectoryPage.cs
@@ -131,7 +131,7 @@ private void DataDirectoryBrowseButton_Click(object sender, EventArgs e)
private void DataDirectoryRevertButton_Click(object sender, EventArgs e)
{
- DataDirectoryTextBox.Text = _controller.Settings.DataDirectory;
+ DataDirectoryTextBox.Text = _controller.Settings.DefaultDataDirectory;
}
#endregion Event Handlers
diff --git a/Configurator/Wizards/Server/ServerConfigLocalMachinePage.cs b/Configurator/Wizards/Server/ServerConfigLocalMachinePage.cs
index 5756662..f625268 100644
--- a/Configurator/Wizards/Server/ServerConfigLocalMachinePage.cs
+++ b/Configurator/Wizards/Server/ServerConfigLocalMachinePage.cs
@@ -104,19 +104,19 @@ public override bool Next()
switch (ConfigTypeComboBox.SelectedIndex)
{
case 0:
- _settings.ServerInstallType = ServerInstallationType.Developer;
+ _settings.ServerInstallationType = ServerInstallationType.Developer;
break;
case 1:
- _settings.ServerInstallType = ServerInstallationType.Server;
+ _settings.ServerInstallationType = ServerInstallationType.Server;
break;
case 2:
- _settings.ServerInstallType = ServerInstallationType.Dedicated;
+ _settings.ServerInstallationType = ServerInstallationType.Dedicated;
break;
case 3:
- _settings.ServerInstallType = ServerInstallationType.Manual;
+ _settings.ServerInstallationType = ServerInstallationType.Manual;
break;
}
@@ -167,7 +167,7 @@ public override void WizardShowing()
ConfigTypeComboBox.SelectedIndex = 0;
if (_controller.ConfigurationType == ConfigurationType.Reconfiguration)
{
- switch(_settings.ServerInstallType)
+ switch(_settings.ServerInstallationType)
{
case ServerInstallationType.Dedicated:
ConfigTypeComboBox.SelectedIndex = 2;
diff --git a/Configurator/Wizards/Server/ServerConfigSecurityPage.cs b/Configurator/Wizards/Server/ServerConfigSecurityPage.cs
index e68c063..cb364c5 100644
--- a/Configurator/Wizards/Server/ServerConfigSecurityPage.cs
+++ b/Configurator/Wizards/Server/ServerConfigSecurityPage.cs
@@ -131,7 +131,8 @@ public override void Activate()
AddItemToListView(FullControlListView, _controller.Settings.ServiceAccountUsername, false, true);
}
- if (!_controller.Settings.ServiceAccountUsername.Equals(_currentServiceAccountUsername, StringComparison.InvariantCultureIgnoreCase))
+ if (!string.IsNullOrEmpty(_controller.Settings.ServiceAccountUsername)
+ && !_controller.Settings.ServiceAccountUsername.Equals(_currentServiceAccountUsername, StringComparison.InvariantCultureIgnoreCase))
{
FullControlListView.Items.RemoveByKey(_currentServiceAccountUsername);
}
@@ -173,7 +174,8 @@ public override bool Next()
var fullControlDictionary = new Dictionary();
if (YesRadioButton.Checked)
{
- if (_controller.Settings.ConfigureAsService)
+ if (_controller.Settings.ConfigureAsService
+ && !string.IsNullOrEmpty(_controller.Settings.ServiceAccountUsername))
{
var serviceAccountUsername = _controller.Settings.ServiceAccountUsername.StartsWith(".")
? _controller.Settings.ServiceAccountUsername.Replace(".", Environment.MachineName)
diff --git a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.Designer.cs b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.Designer.cs
index e72f089..333e865 100644
--- a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.Designer.cs
+++ b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.Designer.cs
@@ -91,6 +91,7 @@ private void InitializeComponent()
this.DataDirectoryRenameWarningProvider = new System.Windows.Forms.ErrorProvider(this.components);
this.VersionErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
this.VersionWarningProvider = new System.Windows.Forms.ErrorProvider(this.components);
+ this.UserWarningProvider = new System.Windows.Forms.ErrorProvider(this.components);
((System.ComponentModel.ISupportInitialize)(this.ValidationsErrorProvider)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ConnectionErrorProvider)).BeginInit();
this.InstallationTypeFlowLayoutPanel.SuspendLayout();
@@ -356,7 +357,7 @@ private void InitializeComponent()
this.NameLabel.AccessibleName = "Selected MySQL server named pipe or shared memory label";
this.NameLabel.AutoSize = true;
this.NameLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.NameLabel.Location = new System.Drawing.Point(408, 52);
+ this.NameLabel.Location = new System.Drawing.Point(422, 52);
this.NameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.NameLabel.Name = "NameLabel";
this.NameLabel.Size = new System.Drawing.Size(63, 25);
@@ -369,7 +370,7 @@ private void InitializeComponent()
"rver instance.";
this.PipeOrSharedMemoryNameTextBox.AccessibleName = "Pipe shared memory name";
this.PipeOrSharedMemoryNameTextBox.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.PipeOrSharedMemoryNameTextBox.Location = new System.Drawing.Point(479, 46);
+ this.PipeOrSharedMemoryNameTextBox.Location = new System.Drawing.Point(493, 46);
this.PipeOrSharedMemoryNameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.PipeOrSharedMemoryNameTextBox.Name = "PipeOrSharedMemoryNameTextBox";
this.PipeOrSharedMemoryNameTextBox.Size = new System.Drawing.Size(251, 31);
@@ -384,7 +385,7 @@ private void InitializeComponent()
this.PortLabel.AccessibleName = "Existing MySQL Server port number label";
this.PortLabel.AutoSize = true;
this.PortLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.PortLabel.Location = new System.Drawing.Point(408, 52);
+ this.PortLabel.Location = new System.Drawing.Point(415, 52);
this.PortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.PortLabel.Name = "PortLabel";
this.PortLabel.Size = new System.Drawing.Size(48, 25);
@@ -487,7 +488,7 @@ private void InitializeComponent()
this.ConnectButton.AccessibleDescription = "A button to connect to the existing MySQL Server instance.";
this.ConnectButton.AccessibleName = "Connect";
this.ConnectButton.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.ConnectButton.Location = new System.Drawing.Point(413, 97);
+ this.ConnectButton.Location = new System.Drawing.Point(445, 97);
this.ConnectButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.ConnectButton.Name = "ConnectButton";
this.ConnectButton.Size = new System.Drawing.Size(111, 41);
@@ -649,6 +650,11 @@ private void InitializeComponent()
this.VersionWarningProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
this.VersionWarningProvider.ContainerControl = this;
//
+ // UserWarningProvider
+ //
+ this.UserWarningProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+ this.UserWarningProvider.ContainerControl = this;
+ //
// ServerConfigServerInstallationsPage
//
this.AccessibleDescription = "A configuration wizard page used to select the type of server installation";
@@ -678,6 +684,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.DataDirectoryRenameWarningProvider)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.VersionErrorProvider)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.VersionWarningProvider)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.UserWarningProvider)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -724,5 +731,6 @@ private void InitializeComponent()
private System.Windows.Forms.ErrorProvider DataDirectoryRenameWarningProvider;
private System.Windows.Forms.ErrorProvider VersionErrorProvider;
private System.Windows.Forms.ErrorProvider VersionWarningProvider;
+ private System.Windows.Forms.ErrorProvider UserWarningProvider;
}
}
diff --git a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.cs b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.cs
index 34eb384..1562bf1 100644
--- a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.cs
+++ b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.cs
@@ -31,12 +31,14 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Core.Controllers;
using MySql.Configurator.Core.Enums;
using MySql.Configurator.Core.IniFile;
+using MySql.Configurator.Core.IniFile.Template;
using MySql.Configurator.Core.Package;
using MySql.Configurator.Core.Product;
using MySql.Configurator.Core.Wizard;
using MySql.Configurator.Dialogs;
using MySql.Configurator.Properties;
using MySql.Data.MySqlClient;
+using Action = System.Action;
namespace MySql.Configurator.Wizards.Server
{
@@ -72,6 +74,11 @@ public partial class ServerConfigServerInstallationsPage : ConfigWizardPage
///
private bool _rootPasswordOk;
+ ///
+ /// A flag indicating whether the controller needs to be recalculated.
+ ///
+ private bool _resetController;
+
#endregion Fields
///
@@ -83,6 +90,7 @@ public ServerConfigServerInstallationsPage(ServerConfigurationController control
InitializeComponent();
_controller = controller;
_package = _controller.Package;
+ _resetController = true;
_rootPasswordOk = false;
_originalPagesVisibility = new Dictionary();
PortTextBox.Text = BaseServerSettings.DEFAULT_PORT.ToString();
@@ -129,43 +137,56 @@ public override void Activate()
public override bool Next()
{
- if (ReplaceServerInstallationRadioButton.Checked)
+ if (!_resetController)
{
- var existingPackage = ProductManager.LoadPackage(_existingServerInstallationInstance.ServerVersion.ToString(), _existingServerInstallationInstance.BaseDir);
- var oldController = (ServerConfigurationController) existingPackage.Controller;
- oldController.LoadState();
- _controller.Settings.OldSettings = oldController.Settings;
- _controller.ConfigurationType = ConfigurationType.Upgrade;
- var dataDirectory = new DirectoryInfo(ExistingDataDirectoryTextBox.Text);
- _controller.Settings.DataDirectory = dataDirectory.Parent.FullName;
- _controller.Settings.ExistingRootPassword = RootPasswordTextBox.Text;
- _controller.IsRemoveExistingServerInstallationStepNeeded = true;
- _controller.IsDataDirectoryRenameNeeded = DataDirectoryRenameWarningProvider.HasErrors();
- _controller.ExistingServerInstallationInstance = _existingServerInstallationInstance;
-
- // Find if existing instance is configured as service.
- var serviceNames = MySqlServiceControlManager.FindServiceNamesWithBaseDirectory(_existingServerInstallationInstance.BaseDir);
- if (serviceNames.Length > 0)
- {
- _existingServerInstallationInstance.ServiceName = serviceNames[0];
- }
-
- _controller.IsServiceRenameNeeded = _existingServerInstallationInstance.IsServiceNameDefault(
- _existingServerInstallationInstance.ServiceName,
- _existingServerInstallationInstance.ServerVersion);
- DetermineExistingServerPersistedVariablesToReset();
+ return base.Next();
}
- else
+
+ Action action;
+ action = delegate
{
- _controller.Package = _package;
- _controller.LoadState();
- _controller.ConfigurationType = ConfigurationType.New;
- _controller.Settings.DataDirectory = NewDataDirectoryTextBox.Text;
- _controller.ExistingServerInstallationInstance = null;
- _controller.IsDataDirectoryRenameNeeded = false;
- _controller.IsRemoveExistingServerInstallationStepNeeded = false;
- _controller.PrepareForConfigure();
- }
+ if (ReplaceServerInstallationRadioButton.Checked)
+ {
+ var existingPackage = ProductManager.LoadPackage(_existingServerInstallationInstance.ServerVersion.ToString(), _existingServerInstallationInstance.BaseDir);
+ var oldController = (ServerConfigurationController)existingPackage.Controller;
+ oldController.LoadState();
+ _controller.Settings.OldSettings = oldController.Settings;
+ _controller.ConfigurationType = ConfigurationType.Upgrade;
+ var dataDirectory = new DirectoryInfo(ExistingDataDirectoryTextBox.Text);
+ _controller.Settings.DataDirectory = dataDirectory.Parent.FullName;
+ _controller.Settings.ExistingRootPassword = RootPasswordTextBox.Text;
+ _controller.Settings.IniDirectory = new FileInfo(ExistingConfigFilePathTextBox.Text).DirectoryName;
+ _controller.IsRemoveExistingServerInstallationStepNeeded = true;
+ _controller.IsDataDirectoryRenameNeeded = DataDirectoryRenameWarningProvider.HasErrors();
+ _controller.ExistingServerInstallationInstance = _existingServerInstallationInstance;
+
+ // Find if existing instance is configured as service.
+ var serviceNames = MySqlServiceControlManager.FindServiceNamesWithBaseDirectory(_existingServerInstallationInstance.BaseDir);
+ if (serviceNames.Length > 0)
+ {
+ _existingServerInstallationInstance.ServiceName = serviceNames[0];
+ }
+
+ _controller.IsServiceRenameNeeded = _existingServerInstallationInstance.IsServiceNameDefault(
+ _existingServerInstallationInstance.ServiceName,
+ _existingServerInstallationInstance.ServerVersion);
+ DetermineExistingServerPersistedVariablesToReset();
+ }
+ else
+ {
+ _controller.Package = _package;
+ _controller.LoadState();
+ _controller.ConfigurationType = ConfigurationType.New;
+ _controller.Settings.DataDirectory = NewDataDirectoryTextBox.Text;
+ _controller.Settings.IniDirectory = _controller.Settings.DataDirectory;
+ _controller.ExistingServerInstallationInstance = null;
+ _controller.IsDataDirectoryRenameNeeded = false;
+ _controller.IsRemoveExistingServerInstallationStepNeeded = false;
+ _controller.PrepareForConfigure();
+ }
+ };
+ ExecuteLongRunningOperation(action);
+ _resetController = false;
if (Wizard is ConfigWizard.ConfigWizard configWizard)
{
@@ -334,6 +355,7 @@ private void RefreshConfigurationPagesVisibility()
private void ResetConnectionTest()
{
ConnectionErrorProvider.Clear();
+ UserWarningProvider.Clear();
DataDirectoryRenameWarningProvider.Clear();
ValidationsErrorProvider.Clear();
VersionErrorProvider.Clear();
@@ -344,6 +366,7 @@ private void ResetConnectionTest()
ExistingDataDirectoryTextBox.Text = string.Empty;
ExistingConfigFilePathTextBox.Text = string.Empty;
_existingServerInstallationInstance = null;
+ _resetController = true;
_rootPasswordOk = false;
ConnectButton.Enabled = ConnectEnabled;
}
@@ -363,6 +386,7 @@ private void UpdateExistingServerInstallationInstance()
throw new ArgumentNullException(nameof(_existingServerInstallationInstance.Controller));
}
+ // Determine if the upgrade is supported.
VersionTextBox.Text = _existingServerInstallationInstance.ServerVersion?.ToString();
string versionErrorMessage = null;
var newVersion = _controller.Package.Version;
@@ -371,7 +395,7 @@ private void UpdateExistingServerInstallationInstance()
switch (upgradeViability)
{
case UpgradeViability.UnsupportedWithWarning:
- versionErrorMessage = Resources.UpgradeNotSupportedWithWarningError;
+ versionErrorMessage = string.Format(Resources.UpgradeNotSupportedWithWarningError, oldVersion, newVersion);
break;
case UpgradeViability.Unsupported:
if (oldVersion.Major < 8)
@@ -416,6 +440,7 @@ private void UpdateExistingServerInstallationInstance()
VersionWarningProvider.Clear();
}
+ // Populate server details.
InstallDirectoryTextBox.Text = _existingServerInstallationInstance.BaseDir;
ExistingDataDirectoryTextBox.Text = _existingServerInstallationInstance.DataDir;
DataDirectoryRenameWarningProvider.SetProperties(ExistingDataDirectoryTextBox, new ErrorProviderProperties(_existingServerInstallationInstance.IsDataDirNameDefault(_controller.ServerVersion)
@@ -424,7 +449,8 @@ private void UpdateExistingServerInstallationInstance()
ValidationsErrorProvider.SetProperties(ExistingDataDirectoryTextBox, new ErrorProviderProperties(string.IsNullOrEmpty(_existingServerInstallationInstance.DataDir)
? Resources.ServerInstanceFailedToRetrieveDataDir :
string.Empty));
-
+
+ var configFileIsValid = false;
if (!string.IsNullOrEmpty(_existingServerInstallationInstance.DataDir))
{
string dataDirectory = null;
@@ -436,11 +462,21 @@ private void UpdateExistingServerInstallationInstance()
dataDirectory = new DirectoryInfo(_existingServerInstallationInstance.DataDir).Parent.FullName;
var defaultConfigFile = Path.Combine(dataDirectory, BaseServerSettings.DEFAULT_CONFIG_FILE_NAME);
var alternateConfigFile = Path.Combine(dataDirectory, BaseServerSettings.ALTERNATE_CONFIG_FILE_NAME);
- ExistingConfigFilePathTextBox.Text = File.Exists(defaultConfigFile)
+
+ var configFile = File.Exists(defaultConfigFile)
? defaultConfigFile
: File.Exists(alternateConfigFile)
? alternateConfigFile
: null;
+ configFileIsValid = configFile != null
+ ? ValidateExistingServerInstallationInstanceConfigurationFile(configFile)
+ : false;
+ if (!configFileIsValid)
+ {
+ ValidationsErrorProvider.SetProperties(ExistingConfigFileBrowseButton, new ErrorProviderProperties(Resources.ServerConfigConfigurationFileNotValid));
+ }
+
+ ExistingConfigFilePathTextBox.Text = configFile;
}
else
{
@@ -463,11 +499,45 @@ private void UpdateExistingServerInstallationInstance()
_existingServerInstallationInstance.Controller.Settings.ConfigureAsService = true;
}
- // Load ini template and set data dir and error log paths.
- var iniFile = new IniFileEngine(ExistingConfigFilePathTextBox.Text).Load();
- _existingServerInstallationInstance.Controller.Settings.DataDirectory = new DirectoryInfo(iniFile.FindValue("mysqld", "datadir", false)).Parent.FullName;
- _existingServerInstallationInstance.Controller.Settings.ErrorLogFileName = iniFile.FindValue("mysqld", "log-error", false);
+ if (!string.IsNullOrEmpty(ExistingConfigFilePathTextBox.Text)
+ && configFileIsValid)
+ {
+ var iniFile = new IniFileEngine(ExistingConfigFilePathTextBox.Text).Load();
+ _existingServerInstallationInstance.Controller.Settings.DataDirectory = new DirectoryInfo(iniFile.FindValue("mysqld", "datadir", false)).Parent.FullName;
+ _existingServerInstallationInstance.Controller.Settings.ErrorLogFileName = iniFile.FindValue("mysqld", "log-error", false);
+ }
+ else
+ {
+ ValidationsErrorProvider.SetProperties(ExistingConfigFileBrowseButton, new ErrorProviderProperties(Resources.ServerConfigConfigurationFileNotFound));
+ }
+ }
+ }
+
+ ///
+ /// Checks that the server configuration file can be successfully parsed.
+ ///
+ ///
+ /// true if the provided server configuration file is valid; otherwise, false.
+ private bool ValidateExistingServerInstallationInstanceConfigurationFile(string serverConfigurationFilePath)
+ {
+ if (string.IsNullOrEmpty(serverConfigurationFilePath))
+ {
+ throw new ArgumentNullException(nameof(serverConfigurationFilePath));
+ }
+
+ if (!File.Exists(serverConfigurationFilePath))
+ {
+ throw new FileNotFoundException(serverConfigurationFilePath);
}
+
+ var template = new IniTemplate(_existingServerInstallationInstance.BaseDir,
+ _existingServerInstallationInstance.DataDir,
+ serverConfigurationFilePath,
+ _existingServerInstallationInstance.Controller.ServerVersion,
+ _existingServerInstallationInstance.Controller.Settings.ServerInstallationType,
+ null);
+
+ return template.IsValid;
}
#region Event Handlers
@@ -586,12 +656,25 @@ private void ExistingConfigFileBrowseButton_Click(object sender, EventArgs e)
if (ConfigFileDialog.ShowDialog() == DialogResult.OK)
{
- ExistingConfigFilePathTextBox.Text = ConfigFileDialog.FileName;
+ var valid = ValidateExistingServerInstallationInstanceConfigurationFile(ConfigFileDialog.FileName);
+ if (!valid)
+ {
+ ValidationsErrorProvider.SetProperties(ExistingConfigFileBrowseButton, new ErrorProviderProperties(Resources.ServerConfigConfigurationFileNotValid));
+ }
+ else
+ {
+ ValidatedHandler(sender, e);
+ }
+
+ ExistingConfigFilePathTextBox.Text = valid
+ ? ConfigFileDialog.FileName
+ : string.Empty;
}
}
private void InstallationRadioButtonsCheckedChanged(object sender, EventArgs e)
{
+ _resetController = true;
ReplaceInstallationControlsPanel.Enabled = ReplaceServerInstallationRadioButton.Checked;
ReplaceInstallationControlsPanel.Visible = ReplaceServerInstallationRadioButton.Checked;
SideBySideInstallationControlsPanel.Enabled = SideBySideInstallationRadioButton.Checked;
diff --git a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.resx b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.resx
index a0c2bfc..da71520 100644
--- a/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.resx
+++ b/Configurator/Wizards/Server/ServerConfigServerInstallationsPage.resx
@@ -121,27 +121,33 @@
17, 17
- 105, 17
+ 140, 17
- 243, 17
+ 338, 17
- 17, 108
+ 1089, 17
+
+
+ 119
- 289, 162
+ 17, 65
- 727, 243
+ 310, 65
- 1287, 365
+ 506, 65
- 1319, 39
+ 858, 17
- 624, 26
+ 597, 17
+
+
+ 884, 65
\ No newline at end of file
diff --git a/Configurator/Wizards/Server/ServerConfigUserAccountsPage.cs b/Configurator/Wizards/Server/ServerConfigUserAccountsPage.cs
index 1dcd6a9..27a52f3 100644
--- a/Configurator/Wizards/Server/ServerConfigUserAccountsPage.cs
+++ b/Configurator/Wizards/Server/ServerConfigUserAccountsPage.cs
@@ -31,6 +31,7 @@ You should have received a copy of the GNU General Public License
using MySql.Configurator.Core.Enums;
using MySql.Configurator.Core.Wizard;
using MySql.Configurator.Properties;
+using Action = System.Action;
namespace MySql.Configurator.Wizards.Server
{
@@ -126,19 +127,24 @@ public override bool Next()
private void PasswordCheckButton_Click(object sender, EventArgs e)
{
- Cursor = Cursors.WaitCursor;
- _rootPasswordOk = false;
- var providerProperties = new ErrorProviderProperties(Resources.ConnectionTestingText, Resources.Config_InProgressIcon, true);
- ConnectionErrorProvider.SetProperties(PasswordCheckButton, providerProperties);
- var connectionResult = LocalServerInstance.CanConnect(_controller, CurrentRootPasswordTextBox.Text, _controller.ConfigurationType == ConfigurationType.Reconfiguration);
- _rootPasswordOk = connectionResult == ConnectionResultType.ConnectionSuccess;
- providerProperties.ErrorIcon = _rootPasswordOk
- ? Resources.Config_DoneIcon
- : Resources.Config_ErrorIcon;
- providerProperties.ErrorMessage = connectionResult.GetDescription();
- ConnectionErrorProvider.SetProperties(PasswordCheckButton, providerProperties);
- Cursor = Cursors.Default;
- UpdateButtons();
+ Action action;
+ action = delegate
+ {
+ _rootPasswordOk = false;
+ var providerProperties = new ErrorProviderProperties(Resources.ConnectionTestingText, Resources.Config_InProgressIcon, true);
+ ConnectionErrorProvider.SetProperties(PasswordCheckButton, providerProperties);
+ var connectionResult = LocalServerInstance.CanConnect(_controller, CurrentRootPasswordTextBox.Text, _controller.ConfigurationType == ConfigurationType.Reconfiguration);
+ _rootPasswordOk = connectionResult == ConnectionResultType.ConnectionSuccess;
+ providerProperties.ErrorIcon = _rootPasswordOk
+ ? Resources.Config_DoneIcon
+ : Resources.Config_ErrorIcon;
+ providerProperties.ErrorMessage = connectionResult.GetDescription();
+ ConnectionErrorProvider.SetProperties(PasswordCheckButton, providerProperties);
+ Cursor = Cursors.Default;
+ UpdateButtons();
+ };
+
+ ExecuteLongRunningOperation(action);
}
private string CheckPasswords()
diff --git a/Configurator/Wizards/Server/ServerConfigurationController.cs b/Configurator/Wizards/Server/ServerConfigurationController.cs
index 260771d..e1af85a 100644
--- a/Configurator/Wizards/Server/ServerConfigurationController.cs
+++ b/Configurator/Wizards/Server/ServerConfigurationController.cs
@@ -288,8 +288,9 @@ public List FirewallRulesList {
///
/// Gets a value indicating if there are configuration files that need to be deleted.
///
- public bool IsDeleteConfigurationFileStepNeeded => File.Exists(Path.Combine(InstallDirectory, GeneralSettingsManager.CONFIGURATOR_SETTINGS_FILE_NAME))
- || File.Exists(Settings.FullConfigFilePath);
+ public bool IsDeleteConfigurationFileStepNeeded => (!string.IsNullOrEmpty(InstallDirectory)
+ && File.Exists(Path.Combine(InstallDirectory, GeneralSettingsManager.CONFIGURATOR_SETTINGS_FILE_NAME)))
+ || File.Exists(Settings.FullConfigFilePath);
///
/// Gets a value indicating whether the removal step that deletes the data directory needs to run.
@@ -301,14 +302,20 @@ public List FirewallRulesList {
///
public bool IsDeleteServiceStepNeeded => MySqlServiceControlManager.ServiceExists(Settings?.ServiceName);
+ ///
+ /// Gets or sets a value indicating if the upgrade is reusing the existing installation and data directories.
+ ///
+ public bool IsSameDirectoryUpgrade { get; set; }
+
///
/// Gets a value indicating if there are steps that require to be executed for a server removal.
///
- public bool IsRemovalExecutionNeeded => IsDeleteDataDirectoryStepNeeded
- || IsDeleteConfigurationFileStepNeeded
- || IsDeleteServiceStepNeeded
- || IsRemoveFirewallRuleStepNeeded
- || IsStopServerConfigurationStepNeeded;
+ public bool IsRemovalExecutionNeeded => IsDataDirectoryConfigured
+ && (IsDeleteDataDirectoryStepNeeded
+ || IsDeleteConfigurationFileStepNeeded
+ || IsDeleteServiceStepNeeded
+ || IsRemoveFirewallRuleStepNeeded
+ || IsStopServerConfigurationStepNeeded);
///
/// Gets a value indicating whether the removal step that deletes the firewall rules needs to run.
@@ -412,7 +419,8 @@ public bool IsStopServerConfigurationStepNeeded
&& ConfigurationType != ConfigurationType.New
&& (!Settings.ConfigureAsService
|| OldSettings.ServiceName != Settings.ServiceName))
- || Settings.ConfigureAsService;
+ || Settings.ConfigureAsService
+ && ConfigurationType != ConfigurationType.Upgrade;
///
/// Gets a value indicating wheter the configuration step to update settings for the MySQL process needs to run.
@@ -458,6 +466,11 @@ public bool IsStopServerConfigurationStepNeeded
public RoleDefinitions RolesDefined { get; private set; }
+ ///
+ /// Gets a value indicating if the credentials of the root user have been provided and validated.
+ ///
+ public bool RootUserCredentialsSet => !string.IsNullOrEmpty(Settings.ExistingRootPassword);
+
///
/// Gets or sets the value of the password used for the root account.
///
@@ -882,9 +895,7 @@ public override void SetPages()
return;
}
- Logger.LogInformation(ConfigurationType == ConfigurationType.Reconfiguration
- ? Resources.SettingUpReconfiguration
- : Resources.SettingUpNewInstallation);
+ Logger.LogInformation(string.Format(Resources.SettingUpControllerMessage, ConfigurationType.GetDescription()));
// New configuration pages.
if (ConfigurationType == ConfigurationType.New)
@@ -907,7 +918,12 @@ public override void SetPages()
}
// Upgrade pages.
- Pages.Add(new ServerConfigBackupPage(this) { PageVisible = false });
+ Pages.Add(new ServerConfigBackupPage(this) { PageVisible = ConfigurationType == ConfigurationType.Upgrade });
+ if (ConfigurationType == ConfigurationType.Upgrade)
+ {
+ Pages.Add(new ServerConfigSecurityPage(this) { PageVisible = !ValidateServerFilesHaveRecommendedPermissions() });
+ return;
+ }
// New configuration and reconfiguration pages.
Pages.Add(new ServerConfigLocalMachinePage(this));
@@ -968,8 +984,10 @@ public void UpdateUpgradeConfigSteps()
_removeExistingServerInstallationStep.Execute = IsRemoveExistingServerInstallationStepNeeded;
_resetPersistedVariablesStep.Execute = PersistedVariablesToReset?.Count > 0;
_renameExistingDataDirectoryStep.Execute = IsDataDirectoryRenameNeeded;
- _updateAccessPermissions.Execute = IsUpdateServerFilesPermissionsStepNeeded;
_startAndUpgradeServerConfigStep.Execute = IsStartAndUpgradeConfigurationStepNeeded;
+ _stopServerConfigurationStep.Execute = IsSameDirectoryUpgrade;
+ _stopExistingServerInstanceStep.Execute = !IsSameDirectoryUpgrade;
+ _updateAccessPermissions.Execute = IsUpdateServerFilesPermissionsStepNeeded;
ConfigurationSteps = StandAloneServerSteps;
}
@@ -1095,14 +1113,17 @@ private bool AddUserToSpecialUsersRegistryKey()
///
private void BackupDatabase()
{
- if (ExistingServerInstallationInstance == null)
+ if (!IsSameDirectoryUpgrade)
{
- throw new Exception(Resources.ExistingServerInstanceNotSetError);
- }
+ if (ExistingServerInstallationInstance == null)
+ {
+ throw new Exception(Resources.ExistingServerInstanceNotSetError);
+ }
- if (!ExistingServerInstallationInstance.IsRunning)
- {
- throw new Exception(Resources.ExistingServerInstanceNotRunningError);
+ if (!ExistingServerInstallationInstance.IsRunning)
+ {
+ throw new Exception(Resources.ExistingServerInstanceNotRunningError);
+ }
}
var success = false;
@@ -1123,7 +1144,9 @@ private void BackupDatabase()
if (!string.IsNullOrEmpty(backupFile))
{
ReportStatus(string.Format(Resources.ServerConfigBackupDatabaseDumpRunning, backupFile));
- var binDirectory = Path.Combine(ExistingServerInstallationInstance.BaseDir, BINARY_DIRECTORY_NAME);
+ var binDirectory = Path.Combine(IsSameDirectoryUpgrade
+ ? InstallDirectory
+ : ExistingServerInstallationInstance.BaseDir, BINARY_DIRECTORY_NAME);
var user = GetUserAccountToConnectBeforeUpdatingRootUser();
var connectionOptions = string.Empty;
bool sendingPasswordInCommandLine = false;
@@ -1993,9 +2016,6 @@ private void LoadSelfContainedUpgradeSteps()
_updateAccessPermissions,
_updateWindowsServiceStep,
_startAndUpgradeServerConfigStep,
- //_prepareAuthenticationPluginChangeStep,
- _stopServerConfigurationStep,
- _startServerConfigurationStep,
_updateSecurityStep,
_updateStartMenuLinksStep,
_removeExistingServerInstallationStep
@@ -2055,8 +2075,8 @@ private IniTemplate LoadTemplate()
string templateBase = "my-template{0}.ini";
var version = Package.Version;
string templateFile = null;
- if (version.Major >= 8
- && version.Minor > 0)
+ if ((version.Major >= 8
+ && version.Minor > 0))
{
templateFile = string.Format(templateBase, $"-{version.Major}.x");
}
@@ -2071,7 +2091,7 @@ private IniTemplate LoadTemplate()
Settings.IniDirectory,
!string.IsNullOrEmpty(Settings.ConfigFile) ? Settings.ConfigFile : BaseServerSettings.DEFAULT_CONFIG_FILE_NAME,
version,
- Settings.ServerInstallType,
+ Settings.ServerInstallationType,
_revertController);
}
@@ -2202,7 +2222,8 @@ private void RemoveFirewallRulesStep()
ReportStatus(string.Format(Resources.RemovingFirewallRuleText, Settings.Port));
var removedXProtocolFirewallRule = true;
- if (Settings.OpenFirewallForXProtocol)
+ if (Settings.OpenFirewallForXProtocol
+ && Settings.MySqlXPort != 0)
{
removedXProtocolFirewallRule = RemoveFirewallRule(Settings.MySqlXPort);
}
@@ -2518,7 +2539,14 @@ private void StopServerSafe(bool useOldSettings)
CancellationToken.ThrowIfCancellationRequested();
var serverInstanceInfo = new LocalServerInstance(this, ReportStatus);
serverInstanceInfo.UseOldSettings = useOldSettings;
- if (ConfigurationType == ConfigurationType.Remove)
+
+ // Set the data directory to allow the call to the ShutdownInstance method to correctly validate
+ // if the server is actually running before attempting to stop it.
+ // Other scenarios do not need this property to be set because the server is expected to be running
+ // allowing the DataDir property getter to query the database for that value.
+ if (ConfigurationType == ConfigurationType.Remove
+ || (ConfigurationType == ConfigurationType.Upgrade
+ && IsSameDirectoryUpgrade))
{
serverInstanceInfo.DataDir = DataDirectory;
}
@@ -3066,7 +3094,8 @@ private void UpdateWindowsFirewall()
if ((ConfigurationType == ConfigurationType.Reconfiguration
|| isDataDirectoryConfigured)
&& OldSettings != null
- && OldSettings.OpenFirewall)
+ && OldSettings.OpenFirewallForXProtocol
+ && OldSettings.MySqlXPort != 0)
{
RemoveFirewallRule(OldSettings.Port);
}
@@ -3092,7 +3121,8 @@ private void UpdateWindowsFirewall()
}
CancellationToken.ThrowIfCancellationRequested();
- if (Settings.OpenFirewallForXProtocol)
+ if (Settings.OpenFirewallForXProtocol
+ && Settings.MySqlXPort != 0)
{
CreateFirewallRule(Settings.MySqlXPort);
}
diff --git a/Configurator/Wizards/Wizard.Designer.cs b/Configurator/Wizards/Wizard.Designer.cs
index a77a5e0..5f9d7ec 100644
--- a/Configurator/Wizards/Wizard.Designer.cs
+++ b/Configurator/Wizards/Wizard.Designer.cs
@@ -43,6 +43,7 @@ protected override void Dispose(bool disposing)
components.Dispose();
}
+ Pages.ForEach(p => p.UnsubscribeEvents());
base.Dispose(disposing);
}
diff --git a/Configurator/Wizards/Wizard.cs b/Configurator/Wizards/Wizard.cs
index bacddf8..e908bd5 100644
--- a/Configurator/Wizards/Wizard.cs
+++ b/Configurator/Wizards/Wizard.cs
@@ -147,12 +147,14 @@ public void AddPage(WizardPage page)
Controls.Add(page);
page.Location = new System.Drawing.Point(220, 0);
page.Wizard = this;
+ page.SubscribeEvents();
AddSideBarTabForPage(page);
}
public void ClearPages()
{
WizardSideBar.Tabs.Clear();
+ Pages.ForEach(p => p.UnsubscribeEvents());
Pages.ForEach(p => p.Dispose());
Pages.Clear();
}
diff --git a/Configurator/app.manifest b/Configurator/app.manifest
index 0e1a299..a7de836 100644
--- a/Configurator/app.manifest
+++ b/Configurator/app.manifest
@@ -1,6 +1,6 @@
-
+
diff --git a/LICENSE b/LICENSE
index dee23d1..f65f7a2 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
Licensing Information User Manual
-MySQL 8.4.0 Community
+MySQL 8.4.5 Community
__________________________________________________________________
Introduction
@@ -8,18 +8,18 @@ Introduction
This License Information User Manual contains Oracle's product license
and other licensing information, including licensing information for
third-party software which may be included in this distribution of
- MySQL 8.4.0 Community.
+ MySQL 8.4.5 Community.
- Last updated: March 2024
+ Last updated: March 2025
Licensing Information
- This release of MySQL 8.4.0 Community is brought to you by the MySQL
+ This release of MySQL 8.4.5 Community is brought to you by the MySQL
team at Oracle. This software is released under version 2 of the GNU
General Public License (GPLv2), as set forth below, with the following
additional permissions:
- This distribution of MySQL 8.4.0 Community is designed to work with
+ This distribution of MySQL 8.4.5 Community is designed to work with
certain software (including but not limited to OpenSSL) that is
licensed under separate terms, as designated in a particular file or
component or in the license documentation. Without limiting your rights
@@ -36,7 +36,7 @@ Licensing Information
reproduced below and can also be found along with its FAQ at
http://oss.oracle.com/licenses/universal-foss-exception.
- Copyright (c) 1997, 2024, Oracle and/or its affiliates.
+ Copyright (c) 1997, 2025, Oracle and/or its affiliates.
Election of GPLv2
@@ -820,483 +820,6 @@ of parameters between 7-parameter geocentric transformation methods.
======================================================================
======================================================================
-Expect.pm
-
-Expect.pm is licensed under the Perl license, which is essentially a dual
-license.
-
-Oracle may use, redistribute and/or modify this code under the terms of
-either:
-
- a) the GNU General Public License as published by the Free Software
-Foundation; either version 1, or (at your option) any later version, or
-
- b) the "Artistic License" which comes with the Expect/pr code.
-
-Oracle elects to use the Artistic license for all versions of MySQL
-
-A copy of the GPLv2 and the Artistic License (Perl) 1.0 must be included with
-any distribution:
-
-The GNU General Public License (GPL-2.0)
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is intended
-to guarantee your freedom to share and change free software--to make sure the
-software is free for all its users. This General Public License applies to
-most of the Free Software Foundation's software and to any other program
-whose authors commit to using it. (Some other Free Software Foundation
-software is covered by the GNU Library General Public License instead.) You
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom
-to distribute copies of free software (and charge for this service if you
-wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or
-for a fee, you must give the recipients all the rights that you have. You
-must make sure that they, too, receive or can get the source code. And you
-must show them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If the
-software is modified by someone else and passed on, we want its recipients to
-know that what they have is not the original, so that any problems introduced
-by others will not reflect on the original authors' reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will
-individually obtain patent licenses, in effect making the program
-proprietary. To prevent this, we have made it clear that any patent must be
-licensed for everyone's free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-placed by the copyright holder saying it may be distributed under the terms
-of this General Public License. The "Program", below, refers to any such
-program or work, and a "work based on the Program" means either the Program
-or any derivative work under copyright law: that is to say, a work containing
-the Program or a portion of it, either verbatim or with modifications and/or
-translated into another language. (Hereinafter, translation is included
-without limitation in the term "modification".) Each licensee is addressed as
-"you".
-
-Activities other than copying, distribution and modification are not covered
-by this License; they are outside its scope. The act of running the Program
-is not restricted, and the output from the Program is covered only if its
-contents constitute a work based on the Program (independent of having been
-made by running the Program). Whether that is true depends on what the
-Program does.
-
-1. You may copy and distribute verbatim copies of the Program's source code
-as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this
-License and to the absence of any warranty; and give any other recipients of
-the Program a copy of this License along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and you may
-at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
-thus forming a work based on the Program, and copy and distribute such
-modifications or work under the terms of Section 1 above, provided that you
-also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices stating
-that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in whole
-or in part contains or is derived from the Program or any part thereof, to be
-licensed as a whole at no charge to all third parties under the terms of this
-License.
-
- c) If the modified program normally reads commands interactively when
-run, you must cause it, when started running for such interactive use in the
-most ordinary way, to print or display an announcement including an
-appropriate copyright notice and a notice that there is no warranty (or else,
-saying that you provide a warranty) and that users may redistribute the
-program under these conditions, and telling the user how to view a copy of
-this License. (Exception: if the Program itself is interactive but does not
-normally print such an announcement, your work based on the Program is not
-required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If identifiable
-sections of that work are not derived from the Program, and can be reasonably
-considered independent and separate works in themselves, then this License,
-and its terms, do not apply to those sections when you distribute them as
-separate works. But when you distribute the same sections as part of a whole
-which is a work based on the Program, the distribution of the whole must be
-on the terms of this License, whose permissions for other licensees extend to
-the entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest your
-rights to work written entirely by you; rather, the intent is to exercise the
-right to control the distribution of derivative or collective works based on
-the Program.
-
-In addition, mere aggregation of another work not based on the Program with
-the Program (or with a work based on the Program) on a volume of a storage or
-distribution medium does not bring the other work under the scope of this
-License.
-
-3. You may copy and distribute the Program (or a work based on it, under
-Section 2) in object code or executable form under the terms of Sections 1
-and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable source
-code, which must be distributed under the terms of Sections 1 and 2 above on
-a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three years, to
-give any third party, for a charge no more than your cost of physically
-performing source distribution, a complete machine-readable copy of the
-corresponding source code, to be distributed under the terms of Sections 1
-and 2 above on a medium customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer to
-distribute corresponding source code. (This alternative is allowed only for
-noncommercial distribution and only if you received the program in object
-code or executable form with such an offer, in accord with Subsection b
-above.)
-
-The source code for a work means the preferred form of the work for making
-modifications to it. For an executable work, complete source code means all
-the source code for all modules it contains, plus any associated interface
-definition files, plus the scripts used to control compilation and
-installation of the executable. However, as a special exception, the source
-code distributed need not include anything that is normally distributed (in
-either source or binary form) with the major components (compiler, kernel,
-and so on) of the operating system on which the executable runs, unless that
-component itself accompanies the executable.
-
-If distribution of executable or object code is made by offering access to
-copy from a designated place, then offering equivalent access to copy the
-source code from the same place counts as distribution of the source code,
-even though third parties are not compelled to copy the source along with the
-object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-expressly provided under this License. Any attempt otherwise to copy, modify,
-sublicense or distribute the Program is void, and will automatically
-terminate your rights under this License. However, parties who have received
-copies, or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-5. You are not required to accept this License, since you have not signed it.
-However, nothing else grants you permission to modify or distribute the
-Program or its derivative works. These actions are prohibited by law if you
-do not accept this License. Therefore, by modifying or distributing the
-Program (or any work based on the Program), you indicate your acceptance of
-this License to do so, and all its terms and conditions for copying,
-distributing or modifying the Program or works based on it.
-
-6. Each time you redistribute the Program (or any work based on the Program),
-the recipient automatically receives a license from the original licensor to
-copy, distribute or modify the Program subject to these terms and conditions.
-You may not impose any further restrictions on the recipients' exercise of
-the rights granted herein. You are not responsible for enforcing compliance
-by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not excuse
-you from the conditions of this License. If you cannot distribute so as to
-satisfy simultaneously your obligations under this License and any other
-pertinent obligations, then as a consequence you may not distribute the
-Program at all. For example, if a patent license would not permit
-royalty-free redistribution of the Program by all those who receive copies
-directly or indirectly through you, then the only way you could satisfy both
-it and this License would be to refrain entirely from distribution of the
-Program.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply and
-the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any patents
-or other property right claims or to contest validity of any such claims;
-this section has the sole purpose of protecting the integrity of the free
-software distribution system, which is implemented by public license
-practices. Many people have made generous contributions to the wide range of
-software distributed through that system in reliance on consistent
-application of that system; it is up to the author/donor to decide if he or
-she is willing to distribute software through any other system and a licensee
-cannot impose that choice.
-
-This section is intended to make thoroughly clear what is believed to be a
-consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
-countries either by patents or by copyrighted interfaces, the original
-copyright holder who places the Program under this License may add an
-explicit geographical distribution limitation excluding those countries, so
-that distribution is permitted only in or among countries not thus excluded.
-In such case, this License incorporates the limitation as if written in the
-body of this License.
-
-9. The Free Software Foundation may publish revised and/or new versions of
-the General Public License from time to time. Such new versions will be
-similar in spirit to the present version, but may differ in detail to address
-new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any later
-version", you have the option of following the terms and conditions either of
-that version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of this License,
-you may choose any version ever published by the Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
-whose distribution conditions are different, write to the author to ask for
-permission. For software which is copyrighted by the Free Software
-Foundation, write to the Free Software Foundation; we sometimes make
-exceptions for this. Our decision will be guided by the two goals of
-preserving the free status of all derivatives of our free software and of
-promoting the sharing and reuse of software generally.
-
-NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
-THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
-STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
-PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
-YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
-LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
-THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible
-use to the public, the best way to achieve this is to make it free software
-which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach
-them to the start of each source file to most effectively convey the
-exclusion of warranty; and each file should have at least the "copyright"
-line and a pointer to where the full notice is found.
-
- One line to give the program's name and a brief idea of what it does.
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your option) any
-later version.
-
- This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
- You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc., 59
-Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this when
-it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author Gnomovision
-comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free
-software, and you are welcome to redistribute it under certain conditions;
-type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may be
-called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-`Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- signature of Ty Coon, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General Public
-License instead of this License.
-
-________________________________________________________
-
-The "Artistic License"
-
-Preamble
-
-The intent of this document is to state the conditions under which a
-Package may be copied, such that the Copyright Holder maintains some
-semblance of artistic control over the development of the package,
-while giving the users of the package the right to use and distribute
-the Package in a more-or-less customary fashion, plus the right to make
-reasonable modifications.
-
-Definitions:
-
- "Package" refers to the collection of files distributed by the
- Copyright Holder, and derivatives of that collection of files
- created through textual modification.
-
- "Standard Version" refers to such a Package if it has not been
- modified, or has been modified in accordance with the wishes
- of the Copyright Holder as specified below.
-
- "Copyright Holder" is whoever is named in the copyright or
- copyrights for the package.
-
- "You" is you, if you're thinking about copying or distributing
- this Package.
-
- "Reasonable copying fee" is whatever you can justify on the
- basis of media cost, duplication charges, time of people involved,
- and so on. (You will not be required to justify it to the
- Copyright Holder, but only to the computing community at large
- as a market that must bear the fee.)
-
- "Freely Available" means that no fee is charged for the item
- itself, though there may be fees involved in handling the item.
- It also means that recipients of the item may redistribute it
- under the same conditions they received it.
-
-1. You may make and give away verbatim copies of the source form of the
-Standard Version of this Package without restriction, provided that you
-duplicate all of the original copyright notices and associated disclaimers.
-
-2. You may apply bug fixes, portability fixes and other modifications
-derived from the Public Domain or from the Copyright Holder. A Package
-modified in such a way shall still be considered the Standard Version.
-
-3. You may otherwise modify your copy of this Package in any way, provided
-that you insert a prominent notice in each changed file stating how and
-when you changed that file, and provided that you do at least ONE of the
-following:
-
- a) place your modifications in the Public Domain or otherwise make them
- Freely Available, such as by posting said modifications to Usenet or
- an equivalent medium, or placing the modifications on a major archive
- site such as uunet.uu.net, or by allowing the Copyright Holder to include
- your modifications in the Standard Version of the Package.
-
- b) use the modified Package only within your corporation or organization.
-
- c) rename any non-standard executables so the names do not conflict
- with standard executables, which must also be provided, and provide
- a separate manual page for each non-standard executable that clearly
- documents how it differs from the Standard Version.
-
- d) make other distribution arrangements with the Copyright Holder.
-
-4. You may distribute the programs of this Package in object code or
-executable form, provided that you do at least ONE of the following:
-
- a) distribute a Standard Version of the executables and library files,
- together with instructions (in the manual page or equivalent) on where
- to get the Standard Version.
-
- b) accompany the distribution with the machine-readable source of
- the Package with your modifications.
-
- c) give non-standard executables non-standard names, and clearly
- document the differences in manual pages (or equivalent), together
- with instructions on where to get the Standard Version.
-
- d) make other distribution arrangements with the Copyright Holder.
-
-5. You may charge a reasonable copying fee for any distribution of this
-Package. You may charge any fee you choose for support of this
-Package. You may not charge a fee for this Package itself. However,
-you may distribute this Package in aggregate with other (possibly
-commercial) programs as part of a larger (possibly commercial) software
-distribution provided that you do not advertise this Package as a
-product of your own. You may embed this Package's interpreter within
-an executable of yours (by linking); this shall be construed as a mere
-form of aggregation, provided that the complete Standard Version of the
-interpreter is so embedded.
-
-6. The scripts and library files supplied as input to or produced as
-output from the programs of this Package do not automatically fall
-under the copyright of this Package, but belong to whoever generated
-them, and may be sold commercially, and may be aggregated with this
-Package. If such scripts or library files are aggregated with this
-Package via the so-called "undump" or "unexec" methods of producing a
-binary executable image, then distribution of such an image shall
-neither be construed as a distribution of this Package nor shall it
-fall under the restrictions of Paragraphs 3 and 4, provided that you do
-not represent such an executable image as a Standard Version of this
-Package.
-
-7. C subroutines (or comparably compiled subroutines in other
-languages) supplied by you and linked into this Package in order to
-emulate subroutines and variables of the language defined by this
-Package shall not be considered part of this Package, but are the
-equivalent of input as in Paragraph 6, provided these subroutines do
-not change the language in any way that would cause it to fail the
-regression tests for the language.
-
-8. Aggregation of this Package with a commercial distribution is always
-permitted provided that the use of this Package is embedded; that is,
-when no overt attempt is made to make this Package's interfaces visible
-to the end user of the commercial distribution. Such use shall not be
-construed as a distribution of this Package.
-
-9. The name of the Copyright Holder may not be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
- The End
-
- ======================================================================
- ======================================================================
-
Facebook Fast Checksum Patch
Facebook Fast Checksum Patch
@@ -1519,6 +1042,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Google Protocol Buffers
+You may be receiving a copy of abseil-cpp as part of this product in object code
+ form.
+The terms of the Oracle license do NOT apply to abseil-cpp.
+abseil-cpp is licensed under the Apache 2.0 license, separate from the Oracle pr
+oduct.
+If you do not wish to install this library, you may remove it, but the Oracle pr
+ogram
+might not operate properly or at all without it.
+
Copyright 2008 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -2147,7 +1679,14 @@ SUCH DAMAGE.
Kerberos5
-Kerberos5
+You may be receiving a copy of the kerberos documentation as part of this
+product. The terms of the Oracle license do NOT apply to Kerberos documentation.
+
+Kerberos documentation is licensed under the CC-BY-SA 3.0 license, separate from
+
+the Oracle product.
+If you do not wish to install this library, you may remove it, but
+the Oracle program might not operate properly or at all without it.
Copyright (C) 1985-2019 by the Massachusetts Institute of Technology.
@@ -4435,6 +3974,35 @@ SOFTWARE.
======================================================================
======================================================================
+xxHash
+
+Copyright (c) 2012-2021 Yann Collet
+All rights reserved.
+BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Some source files include the above license with different copyright years:
+Copyright (C) 2012-2023 Yann Collet
+Copyright (C) 2020-2024 Yann Collet
+
+ ======================================================================
+ ======================================================================
+
zlib
Oracle gratefully acknowledges the contributions of Jean-loup Gailly
diff --git a/MySQLConfigurator.Test/MySQLConfigurator.Test.csproj b/MySQLConfigurator.Test/MySQLConfigurator.Test.csproj
index 09bde43..2ca4f89 100644
--- a/MySQLConfigurator.Test/MySQLConfigurator.Test.csproj
+++ b/MySQLConfigurator.Test/MySQLConfigurator.Test.csproj
@@ -4,6 +4,7 @@
Debug
+ 999.999.999
AnyCPU
{5304B25D-746B-465D-B866-48606D9B6F68}
Library
@@ -71,4 +72,18 @@
+
+
+
+ <_Parameter1>$(Version)
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MySQLConfigurator.Test/Properties/AssemblyInfo.cs b/MySQLConfigurator.Test/Properties/AssemblyInfo.cs
index 7b3eae0..803dc83 100644
--- a/MySQLConfigurator.Test/Properties/AssemblyInfo.cs
+++ b/MySQLConfigurator.Test/Properties/AssemblyInfo.cs
@@ -32,8 +32,4 @@ You should have received a copy of the GNU General Public License
[assembly: ComVisible(false)]
-[assembly: Guid("5304b25d-746b-465d-b866-48606d9b6f68")]
-
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("8.4.0.0")]
-[assembly: AssemblyFileVersion("8.4.0.0")]
+[assembly: Guid("5304b25d-746b-465d-b866-48606d9b6f68")]
\ No newline at end of file
diff --git a/README.md b/README.md
index 00e4ca8..71178a8 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ It performs the initial configuration, a reconfiguration, and also functions as
## Licensing
-Please refer to the license files, available in this repository, and [Legal Notices in documentation](https://dev.mysql.com/doc/refman/8.1/en/preface.html) for further details.
+Please refer to the license files, available in this repository, and [Legal Notices in documentation](https://dev.mysql.com/doc/refman/8.4/en/preface.html) for further details.
## Download and build
@@ -49,3 +49,9 @@ This directory is expected to contain the bin, share, etc and other server direc
For MSI installations this path is usually "C:\Program Files\MySQL\MySQL Server 8.4" or the custom path set during installation.
For ZIP installations this path is whichever location where the server files were extracted to.
+
+### Report a bug
+
+To report a bug, access the [MySQL Bugs Tracking System](https://bugs.mysql.com/). Before reporting the bug please read the **Report a Bug** section for tips. If the bug hasn't been reported yet click the **Report a bug** tab and provide relevant details. The category corresponding to **MySQL Configurator** is **MySQL Sever: Install Configuration Tool**, this will ensure that the bug is routed to the appropriate team.
+
+
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..8b94f40
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,30 @@
+# Reporting security vulnerabilities
+
+Oracle values the independent security research community and believes that
+responsible disclosure of security vulnerabilities helps us ensure the security
+and privacy of all our users.
+
+Please do NOT raise a GitHub Issue to report a security vulnerability. If you
+believe you have found a security vulnerability, please submit a report to
+secalert_us@oracle.com preferably with a proof of concept. Please review
+some additional information on how to report security vulnerabilities to Oracle
+(see https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html)
+We encourage people who contact Oracle Security to use email encryption using
+our encryption key (see https://www.oracle.com/security-alerts/encryptionkey.html)
+
+We ask that you do not use other channels or contact the project maintainers
+directly.
+
+## Security updates, alerts and bulletins
+
+Security updates will be released on a regular cadence. Many of our projects
+will typically release security fixes in conjunction with the Oracle Critical Patch
+Update program. Additional information, including past advisories, is available on our
+security alerts page at https://www.oracle.com/security-alerts/
+
+# Security-related information
+
+We will provide security related information such as a threat model, considerations
+for secure use, or any known security issues in our documentation. Please note
+that labs and sample code are intended to demonstrate a concept and may not be
+sufficiently hardened for production use.
\ No newline at end of file
diff --git a/common/MySql.Data.dll b/common/MySql.Data.dll
index c018073..c5064bc 100644
Binary files a/common/MySql.Data.dll and b/common/MySql.Data.dll differ