private static CLIExitCode IsUpgradeViable()

in Configurator/Core/CLI/CommandLine.cs [323:487]


    private static CLIExitCode IsUpgradeViable(ServerInstallation serverInstallation)
    {
      // Check there are running instances.
      var fullInstallDir = Path.GetFullPath(serverInstallation.Controller.Settings.InstallDirectory).TrimEnd('\\');
      var otherServersRunning = Utilities.GetRunningProcessses("mysqld").Where(p => string.Compare(Path.GetDirectoryName(p.MainModule.FileName).TrimEnd('\\'),
                                                                                                                fullInstallDir,
                                                                                                                StringComparison.InvariantCultureIgnoreCase) != 0);

      // If other instances are running, allow to perform an upgrade.
      if (otherServersRunning.Count() == 0)
      {
        return new CLIExitCode(ExitCode.NoRunningInstancesFound);
      }

      // Build existing server installation instance and perform connection check.
      var controller = new ServerConfigurationController();
      controller.ServerInstallation = ServerInstallationManager.LoadGenericServerInstallation();
      controller.Init();
      controller.PrepareForConfigure();
      _existingServerInstallationInstance = new MySqlServerInstance(controller, null, serverInstallation.Controller.Settings.OldInstancePort);
      _existingServerInstallationInstance.UserAccount.Password = serverInstallation.Controller.Settings.OldInstancePassword;
      _existingServerInstallationInstance.Controller.Settings.ExistingRootPassword = _existingServerInstallationInstance.UserAccount.Password;
      _existingServerInstallationInstance.ConnectionProtocol = serverInstallation.Controller.Settings.OldInstanceProtocol;
      _existingServerInstallationInstance.Controller.Settings.Port = serverInstallation.Controller.Settings.OldInstancePort;
      _existingServerInstallationInstance.PipeOrSharedMemoryName = serverInstallation.Controller.Settings.OldInstanceProtocol == MySqlConnectionProtocol.Pipe
        || serverInstallation.Controller.Settings.OldInstanceProtocol == MySqlConnectionProtocol.NamedPipe
        ? serverInstallation.Controller.Settings.OldInstancePipeName
        : serverInstallation.Controller.Settings.OldInstanceProtocol == MySqlConnectionProtocol.Memory
          || serverInstallation.Controller.Settings.OldInstanceProtocol == MySqlConnectionProtocol.SharedMemory
          ? serverInstallation.Controller.Settings.OldInstanceMemoryName
          : null;

      switch (serverInstallation.Controller.Settings.OldInstanceProtocol)
      {
        case MySqlConnectionProtocol.Sockets:
          controller.Settings.Port = serverInstallation.Controller.Settings.OldInstancePort;
          controller.Settings.EnableTcpIp = true;
          break;
        case MySqlConnectionProtocol.Pipe:
          controller.Settings.PipeName = serverInstallation.Controller.Settings.OldInstancePipeName;
          controller.Settings.EnableNamedPipe = true;
          break;
        case MySqlConnectionProtocol.SharedMemory:
          controller.Settings.SharedMemoryName = serverInstallation.Controller.Settings.OldInstanceMemoryName;
          controller.Settings.EnableSharedMemory = true;
          break;
      }

      var connectionResult = _existingServerInstallationInstance.CanConnect();
      if (connectionResult != ConnectionResultType.ConnectionSuccess)
      {
        return new CLIExitCode(ExitCode.FailedConnectionTestDuringReconfiguration, connectionResult.GetDescription());
      }

      Console.WriteLine(Resources.CLISuccessfulConnection);

      // Determine if the upgrade is supported.
      string versionErrorMessage = null;
      var newVersion = serverInstallation.Controller.ServerInstallation.Version;
      var oldVersion = _existingServerInstallationInstance.ServerVersion;
      var upgradeViability = newVersion.ServerSupportsInPlaceUpgrades(oldVersion);
      switch (upgradeViability)
      {
        case UpgradeViability.UnsupportedWithWarning:
          versionErrorMessage = string.Format(Resources.UpgradeNotSupportedWithWarningError, oldVersion, newVersion);
          break;
        case UpgradeViability.Unsupported:
          if (oldVersion.Major < 8)
          {
            versionErrorMessage = Resources.UpgradeOldServerNotSupportedError;
          }
          else if (oldVersion == newVersion)
          {
            versionErrorMessage = Resources.SameVersionError;
          }
          else
          {
            versionErrorMessage = string.Format(Resources.UpgradeNotSupportedError, oldVersion, newVersion);
          }

          break;
      }

      if (!string.IsNullOrEmpty(versionErrorMessage))
      {
        return new CLIExitCode(ExitCode.UnsupportedUpgrade, versionErrorMessage);
      }

      // Validations.
      var configFileIsValid = false;
      var dataDirectory = new DirectoryInfo(_existingServerInstallationInstance.DataDir).Parent.FullName;
      var defaultConfigFile = Path.Combine(dataDirectory, MySqlServerSettings.DEFAULT_CONFIG_FILE_NAME);
      var alternateConfigFile = Path.Combine(dataDirectory, MySqlServerSettings.ALTERNATE_CONFIG_FILE_NAME);
      var configFile = File.Exists(defaultConfigFile)
        ? defaultConfigFile
        : File.Exists(alternateConfigFile)
          ? alternateConfigFile
          : null;
      if (configFile != null)
      {
        var template = new IniTemplate(_existingServerInstallationInstance.BaseDir,
          _existingServerInstallationInstance.DataDir,
          configFile,
          _existingServerInstallationInstance.ServerVersion,
          _existingServerInstallationInstance.Controller.Settings.ServerInstallationType,
          null);

        configFileIsValid = template.IsValid;
      }

      if (!configFileIsValid)
      {
        return new CLIExitCode(ExitCode.InvalidIniFile);
      }

      // Get authentication plugin.
      serverInstallation.Controller.RootUserAuthenticationPlugin = _existingServerInstallationInstance.GetUserAuthenticationPlugin(MySqlServerUser.ROOT_USERNAME);
      if (serverInstallation.Controller.RootUserAuthenticationPlugin == MySqlAuthenticationPluginType.MysqlNativePassword)
      {
        Console.WriteLine(Resources.ServerConfigInvalidAuthenticationPlugin);
      }

      // Set upgrade details.
      var existingServerInstallation = ServerInstallationManager.LoadServerInstallation(_existingServerInstallationInstance.ServerVersion.ToString(), _existingServerInstallationInstance.BaseDir);
      var oldController = existingServerInstallation.Controller;
      oldController.LoadState();
      serverInstallation.Controller.Settings.OldSettings = oldController.Settings;
      serverInstallation.Controller.ConfigurationType = ConfigurationType.Upgrade;
      serverInstallation.Controller.Settings.DataDirectory = dataDirectory;
      serverInstallation.Controller.Settings.IniDirectory = new FileInfo(configFile).DirectoryName;
      serverInstallation.Controller.IsRemoveExistingServerInstallationStepNeeded = true;
      serverInstallation.Controller.IsDataDirectoryRenameNeeded = _existingServerInstallationInstance.IsDataDirNameDefault(serverInstallation.Controller.ServerVersion);
      serverInstallation.Controller.ExistingServerInstallationInstance = _existingServerInstallationInstance;

      // Find if existing instance is configured as service.
      var serviceNames = MySqlServiceControlManager.FindServiceNamesWithBaseDirectory(_existingServerInstallationInstance.BaseDir);
      if (serviceNames != null
          && serviceNames.Length > 0)
      {
        _existingServerInstallationInstance.ServiceName = serviceNames[0];
      }

      serverInstallation.Controller.IsServiceRenameNeeded = _existingServerInstallationInstance.IsServiceNameDefault(
        _existingServerInstallationInstance.ServiceName,
        _existingServerInstallationInstance.ServerVersion);
      DetermineExistingServerPersistedVariablesToReset(serverInstallation);

      // Set existing instance relevant properties for rollback.
      _existingServerInstallationInstance.Controller.ServerVersion = _existingServerInstallationInstance.ServerVersion;
      _existingServerInstallationInstance.Controller.ServerInstallation.VersionString = _existingServerInstallationInstance.Controller.ServerVersion.ToString();
      if (!string.IsNullOrEmpty(_existingServerInstallationInstance.BaseDir))
      {
        if (serviceNames.Length > 0)
        {
          _existingServerInstallationInstance.Controller.Settings.ServiceName = serviceNames[0];
          _existingServerInstallationInstance.Controller.Settings.ConfigureAsService = true;
        }

        var iniFile = new IniFileEngine(configFile).Load();
        _existingServerInstallationInstance.Controller.Settings.DataDirectory = new DirectoryInfo(iniFile.FindValue("mysqld", "datadir", false)).Parent.FullName;
        _existingServerInstallationInstance.Controller.Settings.ErrorLogFileName = iniFile.FindValue("mysqld", "log-error", false);
      }

      return new CLIExitCode(ExitCode.Success);
    }