This built contains the functionality to set hard quota on the website content folder. It requires FSRM to be installed on the File Server, Name of the share where the home folders are create should contain the drive name preceeded by _ e.g. SharedConfig_C. Quota is retrieved from OS disk space quota, quota unit is retrieved from quota description field in the quotas table, this info is fed to Dirquota command and the quota is set accordingly.

This commit is contained in:
Haya Nmeir 2012-09-16 02:22:05 +03:00
parent cfb58e3423
commit f7d7bcfafc
13 changed files with 347 additions and 22 deletions

View file

@ -912,5 +912,76 @@ namespace WebsitePanel.EnterpriseServer
return users.ToArray();
}
public static int SetFolderQuota(int packageId, string path)
{
// check account
int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
if (accountCheck < 0) return accountCheck;
// check package
int packageCheck = SecurityContext.CheckPackage(packageId, DemandPackage.IsActive);
if (packageCheck < 0) return packageCheck;
// place log record
TaskManager.StartTask("FILES", "SET_QUOTA_ON_FOLDER", path);
TaskManager.ItemId = packageId;
try
{
// file server cluster name
string fileServerClusterName = String.Empty;
// Share Name where home folders are created
string shareName = String.Empty;
string[] splits = GetHomeFolder(packageId).Split('\\');
if (splits.Length > 4)
{
fileServerClusterName = splits[2];
shareName = splits[3];
}
// disk space quota
QuotaValueInfo diskSpaceQuota = PackageController.GetPackageQuota(packageId, Quotas.OS_DISKSPACE);
// bat file pat
string cmdFilePath = @"\\" + fileServerClusterName + @"\" + shareName + @"\" + "Process.bat";
#region figure Quota Unit
// Quota Unit
string unit = String.Empty;
if (diskSpaceQuota.QuotaDescription.ToLower().Contains("gb"))
unit = "GB";
else if (diskSpaceQuota.QuotaDescription.ToLower().Contains("mb"))
unit = "MB";
else
unit = "KB";
#endregion
OS.OperatingSystem os = GetOS(packageId);
os.SetQuotaLimitOnFolder(cmdFilePath, fileServerClusterName, path, diskSpaceQuota.QuotaAllocatedValue.ToString() + unit, 0, String.Empty, String.Empty);
return 0;
}
catch (Exception ex)
{
//Log and return a generic error rather than throwing an exception
TaskManager.WriteError(ex);
return BusinessErrorCodes.ERROR_FILE_GENERIC_LOGGED;
}
finally
{
TaskManager.CompleteTask();
}
}
}
}

View file

@ -377,6 +377,9 @@ namespace WebsitePanel.EnterpriseServer
// CREATE WEB SITE
siteId = web.CreateSite(site);
// Set hard quota on the website content folder
FilesController.SetFolderQuota(packageId, site.DataPath);
// register item
site.ServiceId = serviceId;
site.PackageId = packageId;

View file

@ -1,56 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3" />
<section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3"/>
</configSections>
<!-- Connection strings -->
<connectionStrings>
<add name="EnterpriseServer" connectionString="server=HSTPROV01;database=WebsitePanelMerge;uid=WebsitePanel;pwd=aj7ep6fyhmw3b5qeth7c;" providerName="System.Data.SqlClient" />
<add name="EnterpriseServer" connectionString="server=localhost\sqlexpress;database=WebsitePanelBeta;uid=WebsitePanel;pwd=bdeznsrsyce58m0bc61j;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<appSettings>
<!-- Encryption util settings -->
<add key="WebsitePanel.CryptoKey" value="3x7eqt7zabc5n5afs6dg" />
<add key="WebsitePanel.CryptoKey" value="84lc71526qnp8mlqx0gk"/>
<!-- A1D4KDHUE83NKHddF -->
<add key="WebsitePanel.EncryptionEnabled" value="true" />
<add key="WebsitePanel.EncryptionEnabled" value="true"/>
<!-- Web Applications -->
<add key="WebsitePanel.EnterpriseServer.WebApplicationsPath" value="~/WebApplications" />
<add key="WebsitePanel.EnterpriseServer.WebApplicationsPath" value="~/WebApplications"/>
<!-- Communication settings -->
<!-- Maximum waiting time when sending request to the remote server
The value is in seconds. "-1" - infinite. -->
<add key="WebsitePanel.EnterpriseServer.ServerRequestTimeout" value="3600" />
<add key="WebsitePanel.EnterpriseServer.ServerRequestTimeout" value="3600"/>
</appSettings>
<system.web>
<!-- Disable any authentication -->
<authentication mode="None" />
<authentication mode="None"/>
<!-- Correct HTTP runtime settings -->
<httpRuntime executionTimeout="3600" maxRequestLength="16384" />
<httpRuntime executionTimeout="3600" maxRequestLength="16384"/>
<!-- Set globalization settings -->
<globalization culture="en-US" uiCulture="en" requestEncoding="UTF-8" responseEncoding="UTF-8" fileEncoding="UTF-8" />
<globalization culture="en-US" uiCulture="en" requestEncoding="UTF-8" responseEncoding="UTF-8" fileEncoding="UTF-8"/>
<!-- Web Services settings -->
<webServices>
<protocols>
<remove name="HttpPost" />
<remove name="HttpPostLocalhost" />
<remove name="HttpGet" />
<remove name="HttpPost"/>
<remove name="HttpPostLocalhost"/>
<remove name="HttpGet"/>
</protocols>
<soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3" />
<soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3"/>
</webServices>
<compilation targetFramework="4.0" />
<compilation targetFramework="4.0" debug="true"/>
</system.web>
<!-- WSE 3.0 settings -->
<microsoft.web.services3>
<diagnostics>
<trace enabled="false" input="InputTrace.webinfo" output="OutputTrace.webinfo" />
<trace enabled="false" input="InputTrace.webinfo" output="OutputTrace.webinfo"/>
</diagnostics>
<messaging>
<maxMessageLength value="-1" />
<mtom clientMode="On" />
<maxMessageLength value="-1"/>
<mtom clientMode="On"/>
</messaging>
<security>
<securityTokenManager>
<add type="WebsitePanel.EnterpriseServer.ServiceUsernameTokenManager, WebsitePanel.EnterpriseServer" namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken" />
<add type="WebsitePanel.EnterpriseServer.ServiceUsernameTokenManager, WebsitePanel.EnterpriseServer" namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken"/>
</securityTokenManager>
</security>
<policy fileName="WsePolicyCache.Config" />
<policy fileName="WsePolicyCache.Config"/>
</microsoft.web.services3>
</configuration>

View file

@ -19,6 +19,11 @@
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -410,6 +415,7 @@
<Content Include="esWebApplicationGallery.asmx" />
<EmbeddedResource Include="Images\logo.png" />
<Content Include="SystemEventHandlers.config" />
<None Include="Properties\PublishProfiles\Profile1.pubxml" />
<None Include="TaskEventHandlers.config" />
<None Include="WsePolicyCache.Config" />
</ItemGroup>

View file

@ -81,5 +81,6 @@ namespace WebsitePanel.Providers.OS
// Synchronizing
FolderGraph GetFolderGraph(string path);
void ExecuteSyncActions(FileSyncAction[] actions);
void SetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword);
}
}

View file

@ -92,6 +92,11 @@
<Compile Include="HostedSolution\LyncUsersPaged.cs" />
<Compile Include="HostedSolution\LyncVoicePolicyType.cs" />
<Compile Include="HostedSolution\TransactionAction.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="ResultObjects\HeliconApe.cs" />
<Compile Include="HostedSolution\ExchangeMobileDevice.cs" />
<Compile Include="HostedSolution\IOCSEdgeServer.cs" />
@ -312,6 +317,10 @@
<Compile Include="Web\WebVirtualDirectory.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="WebsitePanel.snk" />
</ItemGroup>
<ItemGroup>

View file

@ -209,6 +209,17 @@ namespace WebsitePanel.Providers.OS
SecurityUtils.GrantGroupNtfsPermissions(path, users, resetChildPermissions,
ServerSettings, usersOU, null);
}
public virtual void SetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword)
{
FileUtils.SetQuotaLimitOnFolder(cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword);
}
public static void DeleteDirRecursive(DirectoryInfo treeRoot)
{
FileUtils.DeleteDirectoryRecursive(treeRoot);
}
#endregion
#region ODBC DSNs

View file

@ -62,6 +62,8 @@ namespace WebsitePanel.Providers.OS {
private System.Threading.SendOrPostCallback FileExistsOperationCompleted;
private System.Threading.SendOrPostCallback SetQuotaLimitOnFolderOperationCompleted;
private System.Threading.SendOrPostCallback DirectoryExistsOperationCompleted;
private System.Threading.SendOrPostCallback GetFileOperationCompleted;
@ -132,6 +134,7 @@ namespace WebsitePanel.Providers.OS {
private System.Threading.SendOrPostCallback DeleteDSNOperationCompleted;
/// <remarks/>
public OperatingSystem() {
this.Url = "http://localhost/Server/OperatingSystem.asmx";
@ -143,6 +146,8 @@ namespace WebsitePanel.Providers.OS {
/// <remarks/>
public event FileExistsCompletedEventHandler FileExistsCompleted;
public event SetQuotaLimitOnFolderCompletedEventHandler SetQuotaLimitOnFolderCompleted;
/// <remarks/>
public event DirectoryExistsCompletedEventHandler DirectoryExistsCompleted;
@ -332,6 +337,56 @@ namespace WebsitePanel.Providers.OS {
}
}
/// <remarks/>
[System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/SetQuotaLimitOnFolder", RequestNamespace = "http://smbsaas/websitepanel/server/", ResponseNamespace = "http://smbsaas/websitepanel/server/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public bool SetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword)
{
object[] results = this.Invoke("SetQuotaLimitOnFolder", new object[] {
cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword});
return ((bool)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginSetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("SetQuotaLimitOnFolder", new object[] {
cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword}, callback, asyncState);
}
/// <remarks/>
public bool EndSetQuotaLimitOnFolder(System.IAsyncResult asyncResult)
{
object[] results = this.EndInvoke(asyncResult);
return ((bool)(results[0]));
}
/// <remarks/>
public void SetQuotaLimitOnFolderAsync(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword)
{
this.SetQuotaLimitOnFolderAsync(cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword, null);
}
/// <remarks/>
public void SetQuotaLimitOnFolderAsync(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword, object userState)
{
if ((this.FileExistsOperationCompleted == null))
{
this.FileExistsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnFileExistsOperationCompleted);
}
this.InvokeAsync("SetQuotaLimitOnFolder", new object[] {
cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword}, this.SetQuotaLimitOnFolderOperationCompleted, userState);
}
private void OnSetQuotaLimitOnFolderOperationCompleted(object arg)
{
if ((this.SetQuotaLimitOnFolderCompleted != null))
{
System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
this.SetQuotaLimitOnFolderCompleted(this, new SetQuotaLimitOnFolderCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
}
}
/// <remarks/>
[System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/DirectoryExists", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
@ -1900,6 +1955,36 @@ namespace WebsitePanel.Providers.OS {
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
public delegate void SetQuotaLimitOnFolderCompletedEventHandler(object sender, SetQuotaLimitOnFolderCompletedEventArgs e);
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class SetQuotaLimitOnFolderCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
private object[] results;
internal SetQuotaLimitOnFolderCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{
this.results = results;
}
/// <remarks/>
public bool Result
{
get
{
this.RaiseExceptionIfNecessary();
return ((bool)(this.results[0]));
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
public delegate void DirectoryExistsCompletedEventHandler(object sender, DirectoryExistsCompletedEventArgs e);

View file

@ -37,6 +37,7 @@ using System.Collections.Generic;
using System.Reflection;
using Ionic.Zip;
using WebsitePanel.Providers.OS;
using System.Management;
namespace WebsitePanel.Providers.Utils
{
@ -844,6 +845,121 @@ namespace WebsitePanel.Providers.Utils
conn, null);
cat = null;
}
public static void DeleteDirectoryRecursive(DirectoryInfo treeRoot)
{
if (treeRoot.Exists)
{
DirectoryInfo[] dirs = treeRoot.GetDirectories();
while (dirs.Length > 0)
{
foreach (DirectoryInfo dir in dirs)
DeleteDirectoryRecursive(dir);
dirs = treeRoot.GetDirectories();
}
// DELETE THE FILES UNDER THE CURRENT ROOT
string[] files = Directory.GetFiles(treeRoot.FullName);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
Directory.Delete(treeRoot.FullName, true);
}
}
public static void SetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword)
{
try
{
string[] splits = folderPath.Split('\\');
if (splits.Length > 0)
{
// Creating the BAT file
FileStream fs = File.Create(cmdFilePath);
if (fs != null)
{
fs.Close();
fs.Dispose();
}
StreamWriter swr = new StreamWriter(cmdFilePath);
if (swr != null)
{
swr.WriteLine(@"cd c:\windows\system32");
string[] shareDrive = { };
string sharePath = String.Empty;
if (splits.Length > 4)
{
// Check the share name if it's not an empty string
if (splits[3].Length > 0)
shareDrive = splits[3].Split('_');
// Form the share physicalPath
if (shareDrive.Length == 2)
sharePath = shareDrive[1] + @":\" + splits[3];
if (splits.Length == 7 && !quotaLimit.Equals(String.Empty))
{
splits[6] = "wwwroot";
switch (mode)
{
// Set
case 0: swr.WriteLine(@"dirquota quota add /path:" + sharePath + @"\" + splits[4] + @"\" + splits[5] + @"\" + splits[6] + @" /limit:" + quotaLimit + @" /remote:" + splits[2]);
break;
// Modify
case 1: swr.WriteLine(@"dirquota quota modify /path:" + sharePath + @"\" + splits[4] + @"\" + splits[5] + @"\" + splits[6] + @" /limit:" + quotaLimit + @" /remote:" + splits[2]);
break;
}
}
}
swr.Flush();
swr.Close();
swr.Dispose();
}
ConnectionOptions connOptions = new ConnectionOptions();
if (wmiUserName.Length > 0)
{
connOptions.Username = wmiUserName;
connOptions.Password = wmiPassword;
}
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
ManagementScope manScope =
new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", virtualFileClusterName), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = cmdFilePath;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
}
}
catch
{ }
}
#region Advanced Delete
/// <summary>
/// Deletes the specified file.

View file

@ -533,6 +533,23 @@ namespace WebsitePanel.Server
throw;
}
}
[WebMethod, SoapHeader("settings")]
public void SetQuotaLimitOnFolder(string cmdFilePath, string virtualFileClusterName, string folderPath, string quotaLimit, int mode, string wmiUserName, string wmiPassword)
{
try
{
Log.WriteStart("'{0}' SetQuotaLimitOnFolder", ProviderSettings.ProviderName);
OsProvider.SetQuotaLimitOnFolder(cmdFilePath, virtualFileClusterName, folderPath, quotaLimit, mode, wmiUserName, wmiPassword);
Log.WriteEnd("'{0}' SetQuotaLimitOnFolder", ProviderSettings.ProviderName);
}
catch (Exception ex)
{
Log.WriteError(String.Format("'{0}' SetQuotaLimitOnFolder", ProviderSettings.ProviderName), ex);
throw;
}
}
#endregion
#region Synchronizing

View file

@ -44,7 +44,7 @@
<!-- Perform security check -->
<enabled value="true"/>
<!-- Server password -->
<password value="W6ph5Mm5Pz8GgiULbPgzG37mj9g="/>
<password value="Ib0S3Bg/dA7nbye3jrOcitlyp1c="/>
</security>
</websitepanel.server>
<system.web>

View file

@ -20,6 +20,10 @@
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -231,6 +235,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Properties\PublishProfiles\QuotaTestHaya.pubxml" />
<None Include="WsePolicyCache.Config" />
</ItemGroup>
<PropertyGroup>

View file

@ -241,6 +241,7 @@
<Content Include="App_Themes\Default\Common.skin" />
<Content Include="App_Themes\Default\DataBoundControls.skin" />
<Content Include="App_Themes\Default\Icons.skin" />
<None Include="Properties\PublishProfiles\NewPortalFork.pubxml" />
</ItemGroup>
<ItemGroup>
<Content Include="App_Containers\Default\TopPane.ascx" />