OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.43k stars 2.4k forks source link

Consider Command Line support for OrchardCore #1742

Open rserj opened 6 years ago

rserj commented 6 years ago

I see some Command Line support in Orchard Core, but it was removed because of Performance concerns. https://github.com/OrchardCMS/OrchardCore/commit/2e8a495c75e30647b05b78f8907528b0ae42b961

I tried to return deleted code but it seems it is obsolete cause I'm getting an error

Cannot resolve scoped service 'OrchardCore.Environment.Commands.ICommandManager' from root provider.

registering DefaultCommandManager as Transient instance solved the issue but when I tried "help commands" command it failed with another Exception.

So I just thought, if we can host Orchard Core as Console App like it was made for Nancy. I think It will be useful for Admins, they can install Orchard Core via command line and run some Administrative commands too. I thought about running Orchard Core as Console App i.e without running WebHost, but I afraid it is not possible cause our shell/tenant is tied to Web, Asp.Net (like IHostingEnvironment)

Any thoughts/ideas on this?

sebastienros commented 6 years ago

We definitely need command line commands to work. I don't know how to fix it right now, and I assume @Jetski5822 will be the most knowledgeable on it.

The question I have though is if we should make it work directly from the same process, or on a separate process. Could we have something like an API that a specific app would communicate with (provided we have correct authentication story)? This way we could also administer remote instances.

I was also thinking about being able to access these commands from scripts, say we could then send a JS script to the server, using these commands (this is what Redis allows with Lua).

Ideas?

rserj commented 6 years ago

The question I have though is if we should make it work directly from the same process, or on a separate process.

I think we should support both cases

rserj commented 6 years ago

Just for notes

I thought about running Orchard Core as Console App i.e without running WebHost, but I afraid it is not possible cause our shell/tenant is tied to Web, Asp.Net (like IHostingEnvironment)

In .net core 2.1 they are changing this part, for de-couple the HTTP pipeline building from the Host API. So, IHostingEnvironmentd won't longer contain properties related to Web such as WebRootPath, WebRootFileProvider. Plus WebHostBuilder will be deprecated and replaced by Generic Host builder, this is a good chance thinking about decoupling Shells and other stuff from Web for Command Line support. Please see: https://github.com/aspnet/Hosting/issues/1163 cc: @jtkech

jtkech commented 6 years ago

@rserj thanks for the infos, i didn't have any time to take a look, i will do soon.

hmm, when i worked on hosted services i read things around this but i understood that we will have the choice to be in a host context or in a webhost context where we will keep what we already have.

While migrating to 2.1 with @sebastienros we could see that IHostingEnvironment still have the web properties. But there is also this one when in a host context.

I never used OC command line ;)

neolution-ch2 commented 5 years ago

Now with Orchard running on 2.2, you are probably planning to support this again... I see the RC milestone attached, but is there a chance we'll see it earlier, in a beta?

We would like to create a console app to enable users to deploy pre-configured Orchard apps via command line.

sebastienros commented 5 years ago

With @jrestall we talked about it by the past, and we prefer a way were the CLI is talking http with the tenants (including the default one for host-level actions). He made a working prototype based on nodejs as existing tools exist to make it easy, but I preferred to wait so we can have a dotnet CLI instead. With dotnet tools, and single-exe apps coming in 3.0 it would also be great.

This means that all actions would require corresponding APIs, which is also beneficial for many other scenarios. We just need to agree on how these APIs should look like, ideally in a way that the tool can dynamically list these operations and invoke them (self-described apis) by for instance using swagger. This could also be all graphql based as it has the same kind of metadata and it creates a single endpoint that is already secured.

jrestall commented 5 years ago

Here's the prototype code I did https://github.com/jrestall/orchardcore-cli

It can be installed using 'dotnet tool install --global orchardcore-cli' so it works already as a dotnet CLI. However since the CLI is just a thin passthrough to nodejs it does require you have nodejs installed on the machine which is a downside.

I think it's actually nice since it supports dotnet tools, npm or yarn :)

We were waiting on https://github.com/graphql-dotnet/graphql-dotnet/pull/592 in order to try remove the dependency on nodejs but that pull request has now died. I do however think the overall approach of using graphql mutations and discovering and building the CLI dynamically from the metadata is a really nice approach so hopefully we can continue in that direction.

rserj commented 5 years ago

@neolution-ch talked about installing orchard via command line, like we have in O1.

I think we should define use cases

1) Installing O2 via command line. In such case, we might think about introducing the ability for modules to handle command args from dotnet run orchard.web command

2) Using CLI on behalf of admin user, where Admin should logIn and generate AccessToken, then configure CLI to use one, so he can use CLI under his user. Like AWS CLI

3) Use CLI as client based app, without user context (do we need this?)

2 and 3 cases require Orchard core to be installed and GraphQL and OpenIdict modules must be enabled

rserj commented 5 years ago

Another crazy/good idea to make orchard to be hosted as a console app itself, and make a CLI from it. In such case, we can reuse existed code-base with modular framework to organize CLI command handlers more granular in different modules. But we might need to get rid of from web specific dependencies in the Shell.

jrestall commented 5 years ago

It looks like it might be possible to do a purely dotnet CLI using the new hotchocolate graphql library, which is looking impressive and could very soon be a challenger to graphql-dotnet. It has extensive stitching support. https://github.com/ChilliCream/hotchocolate/tree/master/src/Stitching

We might be able to use the SchemaInfo and parsing to get at the metadata. Then use the RemoteQueryBuilder to call the remote schema. See DelegateToRemoteSchemaMiddleware.cs.

@michaelstaib

michaelstaib commented 5 years ago

If you need help with setting something like this up, we are willing to help.

neolution-ch2 commented 5 years ago

@rserj We like your crazy/good idea. It's exactly what we have tried first.

... well without a full-blown CLI. We only wanted to do some configuration with a console app. But it's hard to get rid of the HTTP dependencies of OrchardCore, if not even impossible at the moment.

sebastienros commented 5 years ago

@rserj @neolution-ch

to make orchard to be hosted as a console app itself

That's the worst idea ever ;) We did that in O1 and I actually mentioned it during last tuesday's meeting. The issue with that is that it would load all tenants, which can be super slow, and consume too much memory. Also it need to run on the same instance. Never again ! Unless you change my mind. Even @Jetski5822 who created the command line in OC agreed with the use if REST/GraphQL instead.

rserj commented 5 years ago

@sebastienros I talked about making a CLI out of Orchard Core engine. Not like we have in O1. It will be a different Console app based on orchard modularity framework (we won't spin a web server or anything like this), which will use GraphQL and OpenId to connect to Orchard Core web site.

sebastienros commented 5 years ago

@rserj I don't understand. Why would it be modular? It's a single engine that can connect to a remove service to list all the actions it can do, after authenticating to it. It can use multiple projects, but what is modular in it? What can be enabled/disabled?

rserj commented 5 years ago

@sebastienros I understood the idea, you want a simple client which will use API metadata endpoint to list all available actions to perform (like POST Man or sort of). I thought about CLI with modules each module will be responsible for a particular set of commands like contentItems ls roles ls. I agree that having a simple console client will be more beneficiary for us in terms of implementation and support.

sebastienros commented 5 years ago

Ok makes sense now. That's something I looked into, but then the version of the CLI will need to match the version of the site, which is fine, but the cli will need to be built with the same solution as the websites, which is harder. In terms of perf, each module with commands would have a schema, that would have a version, and the cli could just check these versions and have a local cache per remote.

Even with http driven command lines each module would be responsible for providing specific commands like you described.

Also that would force each module to provide REST apis of graphql endpoint, which can be used with the command line tools or pure http requests.

neolution-ch2 commented 5 years ago

I think we should define use cases

1) Installing O2 via command line. In such case, we might think about introducing the ability for modules to handle command args from dotnet run orchard.web command

2) Using CLI on behalf of admin user, where Admin should logIn and generate AccessToken, then configure CLI to use one, so he can use CLI under his user. Like AWS CLI

3) Use CLI as client based app, without user context (do we need this?)

2 and 3 cases require Orchard core to be installed and GraphQL and OpenIdict modules must be enabled

That would work for us. If O2 would implement functionality for this use cases, I think we could implement our deployment scenario by first installing O2 via command line and then importing a recipe via CLI. 👍

Piedone commented 4 years ago

I'd consider creating a PowerShell Core host for Orchard: thus you could run PS scripts in the context of an Orchard app (a bit like having an on-the-fly PS Orchard module). Since PS can natively call anything in .NET it could use the internal APIs directly without any explicit support.

Piedone commented 4 years ago

Or utilizing .NET Interactive and just writing C#...