mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 11:44:58 +08:00
Implemented Initializing status.
This commit is contained in:
@@ -91,6 +91,7 @@
|
||||
<Compile Include="Providers\Builders\ContentStep.cs" />
|
||||
<Compile Include="Providers\Builders\RecipeMetadataStep.cs" />
|
||||
<Compile Include="Providers\Builders\SettingsStep.cs" />
|
||||
<Compile Include="Providers\Executors\ActivateShellStep.cs" />
|
||||
<Compile Include="Providers\Executors\ActivateSweepGeneratorStep.cs" />
|
||||
<Compile Include="Providers\Executors\CommandStep.cs" />
|
||||
<Compile Include="Providers\Executors\RemoveContentStep.cs" />
|
||||
|
@@ -0,0 +1,23 @@
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Recipes.Models;
|
||||
using Orchard.Recipes.Services;
|
||||
|
||||
namespace Orchard.Recipes.Providers.Executors {
|
||||
public class ActivateShellStep : RecipeExecutionStep {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IShellSettingsManager _shellSettingsManager;
|
||||
|
||||
public ActivateShellStep(ShellSettings shellSettings, IShellSettingsManager shellSettingsManager, RecipeExecutionLogger logger)
|
||||
: base(logger) {
|
||||
_shellSettings = shellSettings;
|
||||
_shellSettingsManager = shellSettingsManager;
|
||||
}
|
||||
|
||||
public override string Name { get { return "ActivateShell"; } }
|
||||
|
||||
public override void Execute(RecipeExecutionContext context) {
|
||||
_shellSettings.State = TenantState.Running;
|
||||
_shellSettingsManager.SaveSettings(_shellSettings);
|
||||
}
|
||||
}
|
||||
}
|
@@ -74,7 +74,13 @@ namespace Orchard.Recipes.Services {
|
||||
if (!String.IsNullOrWhiteSpace(recipeName))
|
||||
query = from record in query where record.RecipeName == recipeName select record;
|
||||
|
||||
var stepResultRecord = query.Single();
|
||||
var stepResultRecord = query.SingleOrDefault();
|
||||
|
||||
if (stepResultRecord == null)
|
||||
// No step result record was created when scheduling the step, so simply ignore.
|
||||
// The only reason where one would not create such a record would be Setup,
|
||||
// when no database exists to store the record but still wants to schedule a recipe step (such as the "StopViewsBackgroundCompilationStep").
|
||||
return;
|
||||
|
||||
stepResultRecord.IsCompleted = true;
|
||||
stepResultRecord.IsSuccessful = isSuccessful;
|
||||
|
@@ -20,10 +20,11 @@ namespace Orchard.Setup.Controllers {
|
||||
private const string DefaultRecipe = "Default";
|
||||
|
||||
public SetupController(
|
||||
INotifier notifier,
|
||||
ISetupService setupService,
|
||||
INotifier notifier,
|
||||
ISetupService setupService,
|
||||
IViewsBackgroundCompilation viewsBackgroundCompilation,
|
||||
ShellSettings shellSettings) {
|
||||
|
||||
_viewsBackgroundCompilation = viewsBackgroundCompilation;
|
||||
_shellSettings = shellSettings;
|
||||
_notifier = notifier;
|
||||
@@ -42,12 +43,16 @@ namespace Orchard.Setup.Controllers {
|
||||
|
||||
public ActionResult Index() {
|
||||
var initialSettings = _setupService.Prime();
|
||||
|
||||
if(initialSettings.State == TenantState.Initializing)
|
||||
return View("Initializing");
|
||||
|
||||
var recipes = _setupService.Recipes().ToList();
|
||||
string recipeDescription = null;
|
||||
if (recipes.Count > 0) {
|
||||
recipeDescription = recipes[0].Description;
|
||||
}
|
||||
|
||||
|
||||
// On the first time installation of Orchard, the user gets to the setup screen, which
|
||||
// will take a while to finish (user inputting data and the setup process itself).
|
||||
// We use this opportunity to start a background task to "pre-compile" all the known
|
||||
@@ -56,10 +61,10 @@ namespace Orchard.Setup.Controllers {
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(initialSettings.Name, ShellSettings.DefaultName)) {
|
||||
_viewsBackgroundCompilation.Start();
|
||||
}
|
||||
|
||||
|
||||
return IndexViewResult(new SetupViewModel {
|
||||
AdminUsername = "admin",
|
||||
DatabaseIsPreconfigured = !string.IsNullOrEmpty(initialSettings.DataProvider),
|
||||
DatabaseIsPreconfigured = !String.IsNullOrEmpty(initialSettings.DataProvider),
|
||||
Recipes = recipes,
|
||||
RecipeDescription = recipeDescription
|
||||
});
|
||||
@@ -76,17 +81,17 @@ namespace Orchard.Setup.Controllers {
|
||||
if (model.DatabaseProvider != SetupDatabaseType.Builtin && string.IsNullOrEmpty(model.DatabaseConnectionString))
|
||||
ModelState.AddModelError("DatabaseConnectionString", T("A connection string is required.").Text);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.ConfirmPassword) && model.AdminPassword != model.ConfirmPassword ) {
|
||||
if (!String.IsNullOrWhiteSpace(model.ConfirmPassword) && model.AdminPassword != model.ConfirmPassword) {
|
||||
ModelState.AddModelError("ConfirmPassword", T("Password confirmation must match.").Text);
|
||||
}
|
||||
|
||||
if (model.DatabaseProvider != SetupDatabaseType.Builtin && !string.IsNullOrWhiteSpace(model.DatabaseTablePrefix)) {
|
||||
model.DatabaseTablePrefix = model.DatabaseTablePrefix.Trim();
|
||||
if(!char.IsLetter(model.DatabaseTablePrefix[0])) {
|
||||
if (!Char.IsLetter(model.DatabaseTablePrefix[0])) {
|
||||
ModelState.AddModelError("DatabaseTablePrefix", T("The table prefix must begin with a letter.").Text);
|
||||
}
|
||||
|
||||
if(model.DatabaseTablePrefix.Any(x => !Char.IsLetterOrDigit(x))) {
|
||||
if (model.DatabaseTablePrefix.Any(x => !Char.IsLetterOrDigit(x))) {
|
||||
ModelState.AddModelError("DatabaseTablePrefix", T("The table prefix must contain letters or digits.").Text);
|
||||
}
|
||||
}
|
||||
@@ -103,16 +108,15 @@ namespace Orchard.Setup.Controllers {
|
||||
foreach (var recipe in recipes.Where(recipe => recipe.Name == model.Recipe)) {
|
||||
model.RecipeDescription = recipe.Description;
|
||||
}
|
||||
model.DatabaseIsPreconfigured = !string.IsNullOrEmpty(_setupService.Prime().DataProvider);
|
||||
|
||||
model.DatabaseIsPreconfigured = !String.IsNullOrEmpty(_setupService.Prime().DataProvider);
|
||||
|
||||
return IndexViewResult(model);
|
||||
}
|
||||
|
||||
try {
|
||||
string providerName = null;
|
||||
|
||||
switch (model.DatabaseProvider)
|
||||
{
|
||||
switch (model.DatabaseProvider) {
|
||||
case SetupDatabaseType.Builtin:
|
||||
providerName = "SqlCe";
|
||||
break;
|
||||
@@ -140,11 +144,11 @@ namespace Orchard.Setup.Controllers {
|
||||
DatabaseProvider = providerName,
|
||||
DatabaseConnectionString = model.DatabaseConnectionString,
|
||||
DatabaseTablePrefix = model.DatabaseTablePrefix,
|
||||
EnabledFeatures = null, // default list
|
||||
EnabledFeatures = null, // Default list
|
||||
Recipe = model.Recipe
|
||||
};
|
||||
|
||||
string executionId = _setupService.Setup(setupContext);
|
||||
var executionId = _setupService.Setup(setupContext);
|
||||
|
||||
// First time installation if finally done. Tell the background views compilation
|
||||
// process to stop, so that it doesn't interfere with the user (asp.net compilation
|
||||
@@ -153,7 +157,8 @@ namespace Orchard.Setup.Controllers {
|
||||
|
||||
// Redirect to the welcome page.
|
||||
return Redirect("~/" + _shellSettings.RequestUrlPrefix);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Error(ex, "Setup failed");
|
||||
_notifier.Error(T("Setup failed: {0}", ex.Message));
|
||||
|
||||
@@ -161,7 +166,7 @@ namespace Orchard.Setup.Controllers {
|
||||
foreach (var recipe in recipes.Where(recipe => recipe.Name == model.Recipe)) {
|
||||
model.RecipeDescription = recipe.Description;
|
||||
}
|
||||
model.DatabaseIsPreconfigured = !string.IsNullOrEmpty(_setupService.Prime().DataProvider);
|
||||
model.DatabaseIsPreconfigured = !String.IsNullOrEmpty(_setupService.Prime().DataProvider);
|
||||
|
||||
return IndexViewResult(model);
|
||||
}
|
||||
|
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard.Setup.Controllers
|
||||
{
|
||||
public enum SetupDatabaseType
|
||||
{
|
||||
Builtin,
|
||||
SqlServer,
|
||||
MySql,
|
||||
PostgreSql,
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -78,7 +79,7 @@
|
||||
<Compile Include="Annotations\StringLengthMin.cs" />
|
||||
<Compile Include="Commands\SetupCommand.cs" />
|
||||
<Compile Include="Controllers\SetupController.cs" />
|
||||
<Compile Include="Controllers\SetupDatabaseType.cs" />
|
||||
<Compile Include="ViewModels\SetupDatabaseType.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Routes.cs" />
|
||||
<Compile Include="Services\ISetupService.cs" />
|
||||
@@ -136,6 +137,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Document.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Setup\Initializing.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@@ -4,8 +4,7 @@ using System.Web.Routing;
|
||||
using Orchard.Mvc.Routes;
|
||||
|
||||
namespace Orchard.Setup {
|
||||
public class Routes : IRouteProvider
|
||||
{
|
||||
public class Routes : IRouteProvider {
|
||||
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
||||
foreach (var routeDescriptor in GetRoutes())
|
||||
routes.Add(routeDescriptor);
|
||||
@@ -13,24 +12,24 @@ namespace Orchard.Setup {
|
||||
|
||||
public IEnumerable<RouteDescriptor> GetRoutes() {
|
||||
return new[] {
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"{controller}/{action}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"},
|
||||
{"controller", "Setup"},
|
||||
{"action", "Index"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"},
|
||||
{"controller", "Setup"},
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
}
|
||||
};
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"{controller}/{action}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"},
|
||||
{"controller", "Setup"},
|
||||
{"action", "Index"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"},
|
||||
{"controller", "Setup"},
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Setup"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web;
|
||||
using System.Xml.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Settings.Models;
|
||||
using Orchard.Data;
|
||||
@@ -16,7 +17,6 @@ using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.State;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Recipes.Models;
|
||||
@@ -26,7 +26,7 @@ using Orchard.Settings;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Setup.Services {
|
||||
public class SetupService : ISetupService {
|
||||
public class SetupService : Component, ISetupService {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IOrchardHost _orchardHost;
|
||||
private readonly IShellSettingsManager _shellSettingsManager;
|
||||
@@ -46,6 +46,7 @@ namespace Orchard.Setup.Services {
|
||||
IProcessingEngine processingEngine,
|
||||
IExtensionManager extensionManager,
|
||||
IRecipeHarvester recipeHarvester) {
|
||||
|
||||
_shellSettings = shellSettings;
|
||||
_orchardHost = orchardHost;
|
||||
_shellSettingsManager = shellSettingsManager;
|
||||
@@ -54,13 +55,8 @@ namespace Orchard.Setup.Services {
|
||||
_processingEngine = processingEngine;
|
||||
_extensionManager = extensionManager;
|
||||
_recipeHarvester = recipeHarvester;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ShellSettings Prime() {
|
||||
return _shellSettings;
|
||||
}
|
||||
@@ -86,36 +82,33 @@ namespace Orchard.Setup.Services {
|
||||
|
||||
// The vanilla Orchard distibution has the following features enabled.
|
||||
string[] hardcoded = {
|
||||
// Framework
|
||||
"Orchard.Framework",
|
||||
// Core
|
||||
"Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation","Scheduling", "Settings", "Shapes", "Title",
|
||||
// Modules
|
||||
"Orchard.Pages", "Orchard.ContentPicker", "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules",
|
||||
"PackagingServices", "Orchard.Packaging", "Gallery", "Orchard.Recipes"
|
||||
};
|
||||
// Framework
|
||||
"Orchard.Framework",
|
||||
// Core
|
||||
"Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation","Scheduling", "Settings", "Shapes", "Title",
|
||||
// Modules
|
||||
"Orchard.Pages", "Orchard.ContentPicker", "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules",
|
||||
"PackagingServices", "Orchard.Packaging", "Gallery", "Orchard.Recipes"
|
||||
};
|
||||
|
||||
context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty<string>()).Distinct().ToList();
|
||||
|
||||
var shellSettings = new ShellSettings(_shellSettings);
|
||||
|
||||
if (string.IsNullOrEmpty(shellSettings.DataProvider)) {
|
||||
if (String.IsNullOrEmpty(shellSettings.DataProvider)) {
|
||||
shellSettings.DataProvider = context.DatabaseProvider;
|
||||
shellSettings.DataConnectionString = context.DatabaseConnectionString;
|
||||
shellSettings.DataTablePrefix = context.DatabaseTablePrefix;
|
||||
}
|
||||
|
||||
#region Encryption Settings
|
||||
|
||||
|
||||
shellSettings.EncryptionAlgorithm = "AES";
|
||||
// randomly generated key
|
||||
|
||||
// Randomly generated key.
|
||||
shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString();
|
||||
|
||||
shellSettings.HashAlgorithm = "HMACSHA256";
|
||||
// randomly generated key
|
||||
shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString();
|
||||
|
||||
#endregion
|
||||
// Randomly generated key.
|
||||
shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString();
|
||||
|
||||
var shellDescriptor = new ShellDescriptor {
|
||||
Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name })
|
||||
@@ -123,12 +116,12 @@ namespace Orchard.Setup.Services {
|
||||
|
||||
var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor);
|
||||
|
||||
// initialize database explicitly, and store shell descriptor
|
||||
// Initialize database explicitly, and store shell descriptor.
|
||||
using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) {
|
||||
|
||||
using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) {
|
||||
|
||||
// check if the database is already created (in case an exception occured in the second phase)
|
||||
// Check if the database is already created (in case an exception occured in the second phase).
|
||||
var schemaBuilder = new SchemaBuilder(environment.Resolve<IDataMigrationInterpreter>());
|
||||
var installationPresent = true;
|
||||
try {
|
||||
@@ -143,7 +136,7 @@ namespace Orchard.Setup.Services {
|
||||
throw new OrchardException(T("A previous Orchard installation was detected in this database with this table prefix."));
|
||||
}
|
||||
|
||||
// Make a workaround to avoid the Transaction issue for PostgreSQL
|
||||
// Workaround to avoid some Transaction issue for PostgreSQL.
|
||||
environment.Resolve<ITransactionManager>().RequireNew();
|
||||
|
||||
schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table
|
||||
@@ -168,15 +161,15 @@ namespace Orchard.Setup.Services {
|
||||
}
|
||||
}
|
||||
|
||||
// in effect "pump messages" see PostMessage circa 1980
|
||||
// In effect "pump messages" see PostMessage circa 1980.
|
||||
while (_processingEngine.AreTasksPending())
|
||||
_processingEngine.ExecuteNextTask();
|
||||
|
||||
// creating a standalone environment.
|
||||
// Creating a standalone environment.
|
||||
// in theory this environment can be used to resolve any normal components by interface, and those
|
||||
// components will exist entirely in isolation - no crossover between the safemode container currently in effect
|
||||
// components will exist entirely in isolation - no crossover between the safemode container currently in effect.
|
||||
|
||||
// must mark state as Running - otherwise standalone enviro is created "for setup"
|
||||
// Set shell state to "Running" so that the proper shell context is created.
|
||||
shellSettings.State = TenantState.Running;
|
||||
using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) {
|
||||
try {
|
||||
@@ -188,24 +181,25 @@ namespace Orchard.Setup.Services {
|
||||
}
|
||||
}
|
||||
|
||||
// Set shell state to "Initializing" so that subsequent HTTP requests are responded to with "Service Unavailable" while Orchard is setting up.
|
||||
shellSettings.State = _shellSettings.State = TenantState.Initializing;
|
||||
_shellSettingsManager.SaveSettings(shellSettings);
|
||||
|
||||
return executionId;
|
||||
}
|
||||
|
||||
private string CreateTenantData(SetupContext context, IWorkContextScope environment) {
|
||||
// create superuser
|
||||
// Create site owner.
|
||||
var membershipService = environment.Resolve<IMembershipService>();
|
||||
var user =
|
||||
membershipService.CreateUser(new CreateUserParams(context.AdminUsername, context.AdminPassword,
|
||||
String.Empty, String.Empty, String.Empty,
|
||||
true));
|
||||
var user = membershipService.CreateUser(
|
||||
new CreateUserParams(context.AdminUsername, context.AdminPassword,
|
||||
String.Empty, String.Empty, String.Empty, true));
|
||||
|
||||
// set superuser as current user for request (it will be set as the owner of all content items)
|
||||
// Set site owner as current user for request (it will be set as the owner of all content items).
|
||||
var authenticationService = environment.Resolve<IAuthenticationService>();
|
||||
authenticationService.SetAuthenticatedUserForRequest(user);
|
||||
|
||||
// set site name and settings
|
||||
// Set site name and settings.
|
||||
var siteService = environment.Resolve<ISiteService>();
|
||||
var siteSettings = siteService.GetSiteSettings().As<SiteSettingsPart>();
|
||||
siteSettings.SiteSalt = Guid.NewGuid().ToString("N");
|
||||
@@ -213,7 +207,7 @@ namespace Orchard.Setup.Services {
|
||||
siteSettings.SuperUser = context.AdminUsername;
|
||||
siteSettings.SiteCulture = "en-US";
|
||||
|
||||
// add default culture
|
||||
// Add default culture.
|
||||
var cultureManager = environment.Resolve<ICultureManager>();
|
||||
cultureManager.AddCulture("en-US");
|
||||
|
||||
@@ -222,10 +216,22 @@ namespace Orchard.Setup.Services {
|
||||
|
||||
if (recipe == null)
|
||||
throw new OrchardException(T("The recipe '{0}' could not be found.", context.Recipe));
|
||||
|
||||
|
||||
var executionId = recipeManager.Execute(recipe);
|
||||
|
||||
// null check: temporary fix for running setup in command line
|
||||
// Once the recipe has finished executing, we need to update the shell state to "Running", so add a recipe step that does exactly that.
|
||||
var recipeStepQueue = environment.Resolve<IRecipeStepQueue>();
|
||||
var recipeStepResultRecordRepository = environment.Resolve<IRepository<RecipeStepResultRecord>>();
|
||||
var activateShellStep = new RecipeStep(Guid.NewGuid().ToString("N"), recipe.Name, "ActivateShell", new XElement("ActivateShell"));
|
||||
recipeStepQueue.Enqueue(executionId, activateShellStep);
|
||||
recipeStepResultRecordRepository.Create(new RecipeStepResultRecord {
|
||||
ExecutionId = executionId,
|
||||
RecipeName = recipe.Name,
|
||||
StepId = activateShellStep.Id,
|
||||
StepName = activateShellStep.Name
|
||||
});
|
||||
|
||||
// Null check: temporary fix for running setup in command line.
|
||||
if (HttpContext.Current != null) {
|
||||
authenticationService.SignIn(user, true);
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Routing;
|
||||
using Autofac;
|
||||
using Orchard.Caching;
|
||||
|
@@ -0,0 +1,10 @@
|
||||
namespace Orchard.Setup.ViewModels
|
||||
{
|
||||
public enum SetupDatabaseType
|
||||
{
|
||||
Builtin,
|
||||
SqlServer,
|
||||
MySql,
|
||||
PostgreSql,
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
@model Orchard.Setup.ViewModels.SetupViewModel
|
||||
@using Orchard.Recipes.Models;
|
||||
@using Orchard.Setup.ViewModels
|
||||
@{
|
||||
Script.Require("jQuery");
|
||||
Script.Require("ShapesBase");
|
||||
@@ -47,19 +48,19 @@ if (!Model.DatabaseIsPreconfigured) {
|
||||
<legend>@T("How would you like to store your data?")</legend>
|
||||
@Html.ValidationMessage("DatabaseOptions", "Unable to setup data storage.")
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, Orchard.Setup.Controllers.SetupDatabaseType.Builtin.ToString(), new { id = "builtin" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.Builtin.ToString(), new { id = "builtin" })
|
||||
<label for="builtin" class="forcheckbox">@T("Use built-in data storage (SQL Server Compact)")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, Orchard.Setup.Controllers.SetupDatabaseType.SqlServer.ToString(), new { id = "sqlserver" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.SqlServer.ToString(), new { id = "sqlserver" })
|
||||
<label for="sqlserver" class="forcheckbox">@T("Use an existing SQL Server, SQL Express database")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, Orchard.Setup.Controllers.SetupDatabaseType.MySql.ToString(), new { id = "mysql" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.MySql.ToString(), new { id = "mysql" })
|
||||
<label for="mysql" class="forcheckbox">@T("Use an existing MySql database")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, Orchard.Setup.Controllers.SetupDatabaseType.PostgreSql.ToString(), new { id = "postgresql" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.PostgreSql.ToString(), new { id = "postgresql" })
|
||||
<label for="postgresql" class="forcheckbox">@T("Use an existing PostgreSQL database")</label>
|
||||
</div>
|
||||
<div data-controllerid="builtin" data-defaultstate="hidden">
|
||||
|
@@ -0,0 +1 @@
|
||||
@T("Orchard is initializing. Please check back in a few minutes.")
|
@@ -9,7 +9,7 @@ namespace Orchard.Environment.Configuration {
|
||||
|
||||
public class ShellSettingsManager : Component, IShellSettingsManager {
|
||||
|
||||
private const string _settingsFileName = "Settings.txt";
|
||||
private const string SettingsFileName = "Settings.txt";
|
||||
private readonly IAppDataFolder _appDataFolder;
|
||||
private readonly IShellSettingsManagerEventHandler _events;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Orchard.Environment.Configuration {
|
||||
throw new ArgumentException("The Name property of the supplied ShellSettings object is null or empty; the settings cannot be saved.", "settings");
|
||||
|
||||
Logger.Information("Saving ShellSettings for tenant '{0}'...", settings.Name);
|
||||
var filePath = Path.Combine(Path.Combine("Sites", settings.Name), _settingsFileName);
|
||||
var filePath = Path.Combine(Path.Combine("Sites", settings.Name), SettingsFileName);
|
||||
_appDataFolder.CreateFile(filePath, ShellSettingsSerializer.ComposeSettings(settings));
|
||||
|
||||
Logger.Information("ShellSettings saved successfully; flagging tenant '{0}' for restart.", settings.Name);
|
||||
@@ -48,7 +48,7 @@ namespace Orchard.Environment.Configuration {
|
||||
var filePaths = _appDataFolder
|
||||
.ListDirectories("Sites")
|
||||
.SelectMany(path => _appDataFolder.ListFiles(path))
|
||||
.Where(path => String.Equals(Path.GetFileName(path), _settingsFileName, StringComparison.OrdinalIgnoreCase));
|
||||
.Where(path => String.Equals(Path.GetFileName(path), SettingsFileName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
foreach (var filePath in filePaths) {
|
||||
yield return ShellSettingsSerializer.ParseSettings(_appDataFolder.ReadFile(filePath));
|
||||
|
@@ -1,6 +1,7 @@
|
||||
namespace Orchard.Environment.Configuration {
|
||||
public enum TenantState {
|
||||
Uninitialized,
|
||||
Initializing,
|
||||
Running,
|
||||
Disabled,
|
||||
Invalid
|
||||
|
@@ -128,12 +128,12 @@ namespace Orchard.Environment {
|
||||
void CreateAndActivateShells() {
|
||||
Logger.Information("Start creation of shells");
|
||||
|
||||
// is there any tenant right now ?
|
||||
// Is there any tenant right now?
|
||||
var allSettings = _shellSettingsManager.LoadSettings()
|
||||
.Where(settings => settings.State == TenantState.Running || settings.State == TenantState.Uninitialized)
|
||||
.Where(settings => settings.State == TenantState.Running || settings.State == TenantState.Uninitialized || settings.State == TenantState.Initializing)
|
||||
.ToArray();
|
||||
|
||||
// load all tenants, and activate their shell
|
||||
// Load all tenants, and activate their shell.
|
||||
if (allSettings.Any()) {
|
||||
Parallel.ForEach(allSettings, settings => {
|
||||
try {
|
||||
@@ -145,7 +145,7 @@ namespace Orchard.Environment {
|
||||
}
|
||||
});
|
||||
}
|
||||
// no settings, run the Setup
|
||||
// No settings, run the Setup.
|
||||
else {
|
||||
var setupContext = CreateSetupContext();
|
||||
ActivateShell(setupContext);
|
||||
@@ -172,24 +172,26 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a transient shell for the default tenant's setup
|
||||
/// Creates a transient shell for the default tenant's setup.
|
||||
/// </summary>
|
||||
private ShellContext CreateSetupContext() {
|
||||
Logger.Debug("Creating shell context for root setup");
|
||||
Logger.Debug("Creating shell context for root setup.");
|
||||
return _shellContextFactory.CreateSetupContext(new ShellSettings { Name = ShellSettings.DefaultName });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shell context based on shell settings
|
||||
/// Creates a shell context based on shell settings.
|
||||
/// </summary>
|
||||
private ShellContext CreateShellContext(ShellSettings settings) {
|
||||
if (settings.State == TenantState.Uninitialized) {
|
||||
Logger.Debug("Creating shell context for tenant {0} setup", settings.Name);
|
||||
return _shellContextFactory.CreateSetupContext(settings);
|
||||
switch (settings.State) {
|
||||
case TenantState.Uninitialized:
|
||||
case TenantState.Initializing:
|
||||
Logger.Debug("Creating shell context for tenant {0} setup.", settings.Name);
|
||||
return _shellContextFactory.CreateSetupContext(settings);
|
||||
default:
|
||||
Logger.Debug("Creating shell context for tenant {0}.", settings.Name);
|
||||
return _shellContextFactory.CreateShellContext(settings);
|
||||
}
|
||||
|
||||
Logger.Debug("Creating shell context for tenant {0}", settings.Name);
|
||||
return _shellContextFactory.CreateShellContext(settings);
|
||||
}
|
||||
|
||||
private void SetupExtensions() {
|
||||
|
@@ -37,6 +37,7 @@ namespace Orchard.Environment {
|
||||
ISweepGenerator sweepGenerator,
|
||||
IEnumerable<IOwinMiddlewareProvider> owinMiddlewareProviders,
|
||||
ShellSettings shellSettings) {
|
||||
|
||||
_eventsFactory = eventsFactory;
|
||||
_routeProviders = routeProviders;
|
||||
_httpRouteProviders = httpRouteProviders;
|
||||
|
@@ -103,7 +103,8 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
Features = new[] {
|
||||
new ShellFeature { Name = "Orchard.Setup" },
|
||||
new ShellFeature { Name = "Shapes" },
|
||||
new ShellFeature { Name = "Orchard.jQuery" },
|
||||
new ShellFeature { Name = "Orchard.Recipes" },
|
||||
new ShellFeature { Name = "Orchard.jQuery" }
|
||||
},
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user