mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-20 07:26:03 +01:00
Merge pull request #1514 from MihaelaStoica/REQ-411
CP-21504: Updates wizard: Automated mode for new versions that are available as updates
This commit is contained in:
commit
09fd140026
@ -42,6 +42,8 @@ using XenAdmin.Core;
|
|||||||
|
|
||||||
namespace XenAdmin.Wizards.PatchingWizard
|
namespace XenAdmin.Wizards.PatchingWizard
|
||||||
{
|
{
|
||||||
|
public enum WizardMode { SingleUpdate, AutomatedUpdates, NewVersion }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remember that equals for patches dont work across connections because
|
/// Remember that equals for patches dont work across connections because
|
||||||
/// we are not allow to override equals. YOU SHOULD NOT USE ANY OPERATION THAT IMPLIES CALL EQUALS OF Pool_path or Host_patch
|
/// we are not allow to override equals. YOU SHOULD NOT USE ANY OPERATION THAT IMPLIES CALL EQUALS OF Pool_path or Host_patch
|
||||||
@ -106,7 +108,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
|
|
||||||
if (prevPageType == typeof(PatchingWizard_SelectPatchPage))
|
if (prevPageType == typeof(PatchingWizard_SelectPatchPage))
|
||||||
{
|
{
|
||||||
var wizardIsInAutomatedUpdatesMode = PatchingWizard_SelectPatchPage.IsInAutomatedUpdatesMode;
|
var wizardMode = PatchingWizard_SelectPatchPage.WizardMode;
|
||||||
|
var wizardIsInAutomatedUpdatesMode = wizardMode == WizardMode.AutomatedUpdates;
|
||||||
|
|
||||||
var updateType = wizardIsInAutomatedUpdatesMode ? UpdateType.NewRetail : PatchingWizard_SelectPatchPage.SelectedUpdateType;
|
var updateType = wizardIsInAutomatedUpdatesMode ? UpdateType.NewRetail : PatchingWizard_SelectPatchPage.SelectedUpdateType;
|
||||||
var newPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedNewPatch;
|
var newPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedNewPatch;
|
||||||
@ -114,24 +117,23 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
var alertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedUpdateAlert;
|
var alertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.SelectedUpdateAlert;
|
||||||
var fileFromDiskAlertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.FileFromDiskAlert;
|
var fileFromDiskAlertPatch = wizardIsInAutomatedUpdatesMode ? null : PatchingWizard_SelectPatchPage.FileFromDiskAlert;
|
||||||
|
|
||||||
PatchingWizard_SelectServers.IsInAutomaticMode = wizardIsInAutomatedUpdatesMode;
|
PatchingWizard_SelectServers.WizardMode = wizardMode;
|
||||||
PatchingWizard_SelectServers.SelectedUpdateType = updateType;
|
PatchingWizard_SelectServers.SelectedUpdateType = updateType;
|
||||||
PatchingWizard_SelectServers.Patch = existPatch;
|
PatchingWizard_SelectServers.Patch = existPatch;
|
||||||
PatchingWizard_SelectServers.SelectedUpdateAlert = alertPatch;
|
PatchingWizard_SelectServers.SelectedUpdateAlert = alertPatch;
|
||||||
PatchingWizard_PrecheckPage.UpdateAlert = alertPatch ?? fileFromDiskAlertPatch;
|
|
||||||
PatchingWizard_SelectServers.FileFromDiskAlert = fileFromDiskAlertPatch;
|
PatchingWizard_SelectServers.FileFromDiskAlert = fileFromDiskAlertPatch;
|
||||||
|
|
||||||
RemovePage(PatchingWizard_UploadPage);
|
RemovePage(PatchingWizard_UploadPage);
|
||||||
RemovePage(PatchingWizard_ModePage);
|
RemovePage(PatchingWizard_ModePage);
|
||||||
RemovePage(PatchingWizard_PatchingPage);
|
RemovePage(PatchingWizard_PatchingPage);
|
||||||
RemovePage(PatchingWizard_AutomatedUpdatesPage);
|
RemovePage(PatchingWizard_AutomatedUpdatesPage);
|
||||||
if (!wizardIsInAutomatedUpdatesMode)
|
if (wizardMode == WizardMode.SingleUpdate)
|
||||||
{
|
{
|
||||||
AddAfterPage(PatchingWizard_SelectServers, PatchingWizard_UploadPage);
|
AddAfterPage(PatchingWizard_SelectServers, PatchingWizard_UploadPage);
|
||||||
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_ModePage);
|
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_ModePage);
|
||||||
AddAfterPage(PatchingWizard_ModePage, PatchingWizard_PatchingPage);
|
AddAfterPage(PatchingWizard_ModePage, PatchingWizard_PatchingPage);
|
||||||
}
|
}
|
||||||
else
|
else // AutomatedUpdates or NewVersion
|
||||||
{
|
{
|
||||||
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_AutomatedUpdatesPage);
|
AddAfterPage(PatchingWizard_PrecheckPage, PatchingWizard_AutomatedUpdatesPage);
|
||||||
}
|
}
|
||||||
@ -142,17 +144,18 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
PatchingWizard_UploadPage.SelectedUpdateAlert = alertPatch;
|
PatchingWizard_UploadPage.SelectedUpdateAlert = alertPatch;
|
||||||
|
|
||||||
PatchingWizard_ModePage.Patch = existPatch;
|
PatchingWizard_ModePage.Patch = existPatch;
|
||||||
PatchingWizard_ModePage.SelectedUpdateAlert = alertPatch;
|
|
||||||
|
|
||||||
PatchingWizard_PrecheckPage.IsInAutomatedUpdatesMode = wizardIsInAutomatedUpdatesMode;
|
|
||||||
PatchingWizard_PrecheckPage.Patch = existPatch;
|
|
||||||
PatchingWizard_PatchingPage.Patch = existPatch;
|
|
||||||
|
|
||||||
PatchingWizard_PrecheckPage.SelectedUpdateType = updateType;
|
|
||||||
|
|
||||||
PatchingWizard_ModePage.SelectedUpdateType = updateType;
|
PatchingWizard_ModePage.SelectedUpdateType = updateType;
|
||||||
|
|
||||||
|
PatchingWizard_PrecheckPage.WizardMode = wizardMode;
|
||||||
|
PatchingWizard_PrecheckPage.Patch = existPatch;
|
||||||
|
PatchingWizard_PrecheckPage.SelectedUpdateType = updateType;
|
||||||
|
PatchingWizard_PrecheckPage.UpdateAlert = alertPatch ?? fileFromDiskAlertPatch;
|
||||||
|
|
||||||
|
PatchingWizard_AutomatedUpdatesPage.WizardMode = wizardMode;
|
||||||
|
PatchingWizard_AutomatedUpdatesPage.UpdateAlert = alertPatch ?? fileFromDiskAlertPatch;
|
||||||
|
|
||||||
PatchingWizard_PatchingPage.SelectedUpdateType = updateType;
|
PatchingWizard_PatchingPage.SelectedUpdateType = updateType;
|
||||||
|
PatchingWizard_PatchingPage.Patch = existPatch;
|
||||||
PatchingWizard_PatchingPage.SelectedNewPatch = newPatch;
|
PatchingWizard_PatchingPage.SelectedNewPatch = newPatch;
|
||||||
}
|
}
|
||||||
else if (prevPageType == typeof(PatchingWizard_SelectServers))
|
else if (prevPageType == typeof(PatchingWizard_SelectServers))
|
||||||
@ -328,11 +331,9 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
|
|
||||||
private void RemoveDownloadedPatches()
|
private void RemoveDownloadedPatches()
|
||||||
{
|
{
|
||||||
var isInAutomaticMode = PatchingWizard_SelectPatchPage.IsInAutomatedUpdatesMode;
|
|
||||||
|
|
||||||
List<string> listOfDownloadedFiles = new List<string>();
|
List<string> listOfDownloadedFiles = new List<string>();
|
||||||
|
|
||||||
if (isInAutomaticMode)
|
if (PatchingWizard_SelectPatchPage.WizardMode != WizardMode.SingleUpdate) // AutomatedUpdates or NewVersion
|
||||||
{
|
{
|
||||||
listOfDownloadedFiles.AddRange(PatchingWizard_AutomatedUpdatesPage.AllDownloadedPatches.Values);
|
listOfDownloadedFiles.AddRange(PatchingWizard_AutomatedUpdatesPage.AllDownloadedPatches.Values);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ using XenAdmin.Core;
|
|||||||
using XenAdmin.Network;
|
using XenAdmin.Network;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using XenAdmin.Alerts;
|
||||||
|
|
||||||
namespace XenAdmin.Wizards.PatchingWizard
|
namespace XenAdmin.Wizards.PatchingWizard
|
||||||
{
|
{
|
||||||
@ -62,6 +63,9 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
|
|
||||||
public List<Pool> SelectedPools { private get; set; }
|
public List<Pool> SelectedPools { private get; set; }
|
||||||
|
|
||||||
|
public XenServerPatchAlert UpdateAlert { private get; set; }
|
||||||
|
public WizardMode WizardMode { private get; set; }
|
||||||
|
|
||||||
private List<PoolPatchMapping> patchMappings = new List<PoolPatchMapping>();
|
private List<PoolPatchMapping> patchMappings = new List<PoolPatchMapping>();
|
||||||
public Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
|
public Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
|
||||||
|
|
||||||
@ -135,6 +139,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Assert(WizardMode != WizardMode.NewVersion || (WizardMode == WizardMode.NewVersion && UpdateAlert != null), "For version updates the UpdateAlert shouldn't be null");
|
||||||
|
|
||||||
foreach (var pool in SelectedPools)
|
foreach (var pool in SelectedPools)
|
||||||
{
|
{
|
||||||
var master = Helpers.GetMaster(pool.Connection);
|
var master = Helpers.GetMaster(pool.Connection);
|
||||||
@ -147,9 +153,9 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
delayedActionsByHost.Add(host, new List<PlanAction>());
|
delayedActionsByHost.Add(host, new List<PlanAction>());
|
||||||
}
|
}
|
||||||
|
|
||||||
var hosts = pool.Connection.Cache.Hosts;
|
var us = WizardMode == WizardMode.NewVersion
|
||||||
|
? Updates.GetUpgradeSequence(pool.Connection, UpdateAlert, true)
|
||||||
var us = Updates.GetUpgradeSequence(pool.Connection);
|
: Updates.GetUpgradeSequence(pool.Connection);
|
||||||
|
|
||||||
Debug.Assert(us != null, "Update sequence should not be null.");
|
Debug.Assert(us != null, "Update sequence should not be null.");
|
||||||
|
|
||||||
|
@ -45,8 +45,6 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
{
|
{
|
||||||
private bool _tooltipShowing;
|
private bool _tooltipShowing;
|
||||||
|
|
||||||
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
|
|
||||||
|
|
||||||
public PatchingWizard_ModePage()
|
public PatchingWizard_ModePage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -56,7 +56,6 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
private BackgroundWorker _worker = null;
|
private BackgroundWorker _worker = null;
|
||||||
public List<Host> SelectedServers = new List<Host>();
|
public List<Host> SelectedServers = new List<Host>();
|
||||||
public List<Problem> ProblemsResolvedPreCheck = new List<Problem>();
|
public List<Problem> ProblemsResolvedPreCheck = new List<Problem>();
|
||||||
public bool IsInAutomatedUpdatesMode { get; set; }
|
|
||||||
private AsyncAction resolvePrechecksAction = null;
|
private AsyncAction resolvePrechecksAction = null;
|
||||||
|
|
||||||
protected List<Pool> SelectedPools
|
protected List<Pool> SelectedPools
|
||||||
@ -68,6 +67,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
}
|
}
|
||||||
|
|
||||||
public XenServerPatchAlert UpdateAlert { private get; set; }
|
public XenServerPatchAlert UpdateAlert { private get; set; }
|
||||||
|
public WizardMode WizardMode { private get; set; }
|
||||||
|
|
||||||
public PatchingWizard_PrecheckPage()
|
public PatchingWizard_PrecheckPage()
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
if (direction == PageLoadedDirection.Back)
|
if (direction == PageLoadedDirection.Back)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsInAutomatedUpdatesMode)
|
if (WizardMode == WizardMode.AutomatedUpdates)
|
||||||
{
|
{
|
||||||
labelPrechecksFirstLine.Text = Messages.PATCHINGWIZARD_PRECHECKPAGE_FIRSTLINE_AUTOMATED_UPDATES_MODE;
|
labelPrechecksFirstLine.Text = Messages.PATCHINGWIZARD_PRECHECKPAGE_FIRSTLINE_AUTOMATED_UPDATES_MODE;
|
||||||
}
|
}
|
||||||
@ -385,14 +385,19 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Disk space check for automated updates
|
//Disk space check for automated updates
|
||||||
if (IsInAutomatedUpdatesMode)
|
if (WizardMode != WizardMode.SingleUpdate)
|
||||||
{
|
{
|
||||||
checks.Add(new KeyValuePair<string, List<Check>>(Messages.PATCHINGWIZARD_PRECHECKPAGE_CHECKING_DISK_SPACE, new List<Check>()));
|
checks.Add(new KeyValuePair<string, List<Check>>(Messages.PATCHINGWIZARD_PRECHECKPAGE_CHECKING_DISK_SPACE, new List<Check>()));
|
||||||
checkGroup = checks[checks.Count - 1].Value;
|
checkGroup = checks[checks.Count - 1].Value;
|
||||||
|
|
||||||
foreach (Pool pool in SelectedPools)
|
foreach (Pool pool in SelectedPools)
|
||||||
{
|
{
|
||||||
var us = Updates.GetUpgradeSequence(pool.Connection);
|
var us = WizardMode == WizardMode.NewVersion
|
||||||
|
? Updates.GetUpgradeSequence(pool.Connection, UpdateAlert, true)
|
||||||
|
: Updates.GetUpgradeSequence(pool.Connection);
|
||||||
|
|
||||||
|
if (us == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
bool elyOrGreater = Helpers.ElyOrGreater(pool.Connection);
|
bool elyOrGreater = Helpers.ElyOrGreater(pool.Connection);
|
||||||
|
|
||||||
@ -434,7 +439,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Checking if the host needs a reboot
|
//Checking if the host needs a reboot
|
||||||
if (!IsInAutomatedUpdatesMode)
|
if (WizardMode != WizardMode.SingleUpdate)
|
||||||
{
|
{
|
||||||
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
|
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
|
||||||
checkGroup = checks[checks.Count - 1].Value;
|
checkGroup = checks[checks.Count - 1].Value;
|
||||||
@ -483,7 +488,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Checking if the host needs a reboot
|
//Checking if the host needs a reboot
|
||||||
if (!IsInAutomatedUpdatesMode)
|
if (WizardMode == WizardMode.SingleUpdate)
|
||||||
{
|
{
|
||||||
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
|
checks.Add(new KeyValuePair<string, List<Check>>(Messages.CHECKING_SERVER_NEEDS_REBOOT, new List<Check>()));
|
||||||
checkGroup = checks[checks.Count - 1].Value;
|
checkGroup = checks[checks.Count - 1].Value;
|
||||||
|
@ -156,7 +156,24 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInAutomatedUpdatesMode { get { return AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked; } }
|
private bool IsInAutomatedUpdatesMode { get { return AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked; } }
|
||||||
|
|
||||||
|
public WizardMode WizardMode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (AutomatedUpdatesRadioButton.Visible && AutomatedUpdatesRadioButton.Checked)
|
||||||
|
return WizardMode.AutomatedUpdates;
|
||||||
|
var updateAlert = downloadUpdateRadioButton.Checked && dataGridViewPatches.SelectedRows.Count > 0
|
||||||
|
? (XenServerPatchAlert) ((PatchGridViewRow) dataGridViewPatches.SelectedRows[0]).UpdateAlert
|
||||||
|
: selectFromDiskRadioButton.Checked
|
||||||
|
? GetAlertFromFileName(fileNameTextBox.Text.ToLowerInvariant())
|
||||||
|
: null;
|
||||||
|
if (updateAlert != null && updateAlert.NewServerVersion != null)
|
||||||
|
return WizardMode.NewVersion;
|
||||||
|
return WizardMode.SingleUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void PageLeave(PageLoadedDirection direction, ref bool cancel)
|
public override void PageLeave(PageLoadedDirection direction, ref bool cancel)
|
||||||
{
|
{
|
||||||
|
@ -60,8 +60,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
private bool poolSelectionOnly;
|
private bool poolSelectionOnly;
|
||||||
|
|
||||||
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
|
public XenServerPatchAlert SelectedUpdateAlert { private get; set; }
|
||||||
|
|
||||||
public XenServerPatchAlert FileFromDiskAlert { private get; set; }
|
public XenServerPatchAlert FileFromDiskAlert { private get; set; }
|
||||||
|
public WizardMode WizardMode { private get; set; }
|
||||||
|
|
||||||
public PatchingWizard_SelectServers()
|
public PatchingWizard_SelectServers()
|
||||||
{
|
{
|
||||||
@ -95,8 +95,8 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
base.PageLoaded(direction);
|
base.PageLoaded(direction);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
poolSelectionOnly = IsInAutomaticMode || SelectedUpdateAlert != null || FileFromDiskAlert != null;
|
poolSelectionOnly = WizardMode == WizardMode.AutomatedUpdates || SelectedUpdateAlert != null || FileFromDiskAlert != null;
|
||||||
label1.Text = IsInAutomaticMode
|
label1.Text = WizardMode == WizardMode.AutomatedUpdates
|
||||||
? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_AUTOMATED_MODE
|
? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_AUTOMATED_MODE
|
||||||
: poolSelectionOnly ? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_POOL_SELECTION : Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT;
|
: poolSelectionOnly ? Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_POOL_SELECTION : Messages.PATCHINGWIZARD_SELECTSERVERPAGE_RUBRIC_DEFAULT;
|
||||||
|
|
||||||
@ -142,16 +142,14 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
{
|
{
|
||||||
dataGridViewHosts.Select();
|
dataGridViewHosts.Select();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInAutomaticMode { set; get; }
|
|
||||||
|
|
||||||
private void EnabledRow(Host host, UpdateType type, int index)
|
private void EnabledRow(Host host, UpdateType type, int index)
|
||||||
{
|
{
|
||||||
var row = (PatchingHostsDataGridViewRow)dataGridViewHosts.Rows[index];
|
var row = (PatchingHostsDataGridViewRow)dataGridViewHosts.Rows[index];
|
||||||
|
|
||||||
var poolOfOne = Helpers.GetPoolOfOne(host.Connection);
|
var poolOfOne = Helpers.GetPoolOfOne(host.Connection);
|
||||||
|
|
||||||
if (IsInAutomaticMode)
|
if (WizardMode == WizardMode.AutomatedUpdates)
|
||||||
{
|
{
|
||||||
// This check is first because it generally can't be fixed, it's a property of the host
|
// This check is first because it generally can't be fixed, it's a property of the host
|
||||||
if (poolOfOne != null && poolOfOne.IsAutoUpdateRestartsForbidden) // Forbids update auto restarts
|
if (poolOfOne != null && poolOfOne.IsAutoUpdateRestartsForbidden) // Forbids update auto restarts
|
||||||
@ -475,7 +473,7 @@ namespace XenAdmin.Wizards.PatchingWizard
|
|||||||
{
|
{
|
||||||
if (poolSelectionOnly)
|
if (poolSelectionOnly)
|
||||||
{
|
{
|
||||||
if (IsInAutomaticMode)
|
if (WizardMode != WizardMode.SingleUpdate)
|
||||||
//prechecks will fail in automated updates mode if one of the hosts is unreachable
|
//prechecks will fail in automated updates mode if one of the hosts is unreachable
|
||||||
return SelectedPools.SelectMany(p => p.Connection.Cache.Hosts).ToList();
|
return SelectedPools.SelectMany(p => p.Connection.Cache.Hosts).ToList();
|
||||||
//prechecks will issue warning but allow updates to be installed on the reachable hosts only
|
//prechecks will issue warning but allow updates to be installed on the reachable hosts only
|
||||||
|
Loading…
Reference in New Issue
Block a user