[CFConfig] Best practices for switching between CF engines

Like I bet a lot of other folks, it’s super valuable to be able to switch back and forth between different CFML engines running the same code. On a basic level that’s working well, but I wonder how others doing this are handling server config changes.

Is there a simple way to have CFConfig capture any config changes into .CFConfig.json when the server shuts down? Or when there are changes?

Thanks.

There is. In CommandBox run:

config set modules.commandbox-cfconfig.exportOnStop=true

https://cfconfig.ortusbooks.com/using-the-cli/server-interceptors/server-stop.html

Excellent, will investigate.

Does that apply to all servers, existing and future? Or is it per server?

That’s all servers. I’m not sure if there’s a way to enable it on an individual server basis. There probably is, since Brad always thinks of things like that. :slight_smile:

That’s all servers. I’m not sure if there’s a way to enable it on an individual server basis. There probably is, since Brad always thinks of things like that. :slight_smile:

All servers works for me personally as of now, we’ll see what the more dev-ops guys think if they decide to play with CommandBox, which IMO they really should.

Just my $0.00002…

  • The more of those avenues that run these kinds of lifecycle hooks the better. (Especially the ‘kicked out the power cord’ one, I’d find that one very useful :wink: )

  • I’ve accidentally quit CommandBox on multiple occasions through some unintended action. If there was a way to configure CommandBox to confirm first, that’d be cool.

  • It’s possible the unintended actions were hitting ^C to cancel a cmd I started to type and thought the better of, and it ended up quitting CommandBox instead. If you could make it not do that, that’d be cool too.

  • The reason that’s pretty awkward is that I’ve ended up with a server running that I couldn’t figure out how to kill, had to restart the box. Another CB instance I started didn’t see it. Is there a magic trick for that case? Or could quitting CommandBox with servers running ask if you’d like to kill any running servers too?

Thanks again for all this. Very cool and useful stuff, well thought out.

My biggest reluctance before (further) evangelizing CommandBox around here is the little differences I posted about between CB and standalone runtime behavior. It’s super helpful (to put it mildly) if the issues we do and don’t see locally mirror what happens in the wild pretty well. I can work around the few differences I’ve hit so far, but that’s what I’ve seen in a few days, hard to know what the road ahead will bring.

Dave

I’m not sure if it’s possible for a console app to intercept when someone clicks the “x” very easily. I could prompt when you hit Ctrl+C but that’s not typical of a CLI. Generally Ctrl+C in a CLI means kill it with fire, then ask questions.

The only time I’ve seen a server that the “stop” command won’t stop is if you start two servers with the SAME NAME in the same directory. There is a prompt in place however that asks you if you really really want to do it, so it shouldn’t happen on accident. What’s likely happening is you started a server with a name, but you’re not using the same name to stop it. Running “server list --local” will help show you all the servers you’ve started in that directory. That said, even if the “stop” command doesn’t work, there should still be a tray icon you can click on and choose “stop” which works regardless.

Hmmm, in at least some contexts, ctrl-X just cancels the current cmd you were typing, doesn’t quit anything. But no doubt I’m not as widely versed in the ways of the cmd line as present company. Maybe an option to confirm before quitting cmd box? OTOH, not necessary if it’s actually true that a newly started instance should be able to see and control servers started by another box instance that’s no longer running. Not sure what happened in my case, server was clearly accessible in a browser, stop --all didn’t stop it.

Anyway, back to exportOnStop, on reflection, I actually would like to set that for a single server, or more specifically, to override the global setting you can set today. For instance, a test server might get settings you specifically don’t want to persist. There are other ways to approach that of course, but still.

FWIW, I've found having a per-project .CommandBox home to be really nice
for exactly this reason-- "leftover" or ad-hoc config changes are the
bane of repeatability, so this allows me to keep my project servers
separate and easily wipe-able.

Having './releng clean build' totally clear out everything and
reconfigure from scratch means I treat my servers like the disposable
build artifacts that they are (/me pictures one of them looking at him
now, all doe-eyed, as the derezzer looms... run, program, run!), and
configure any changes to environment in the appropriate environment config.

I'm loving using a DSL for configuring CFML projects in Gradle, I'm
thinking we need something like box.dsl or some-such that instead of
being a static config file is a script that is run so that's all you
need to configure everything, similar to what I'm rocking for
build.gradle, which is super flexible and dangerous-- just like CF. =)

-Denny

There definitely clearly are use cases for both behaviors – from scratch-every-time and like-I-left-it. Test boxes and dev environments are perfect cases of each.

A few days ago, I’d gotten a lot of what I needed running but still didn’t have my head fully around the implications, and I installed a web app that created datasources and mappings, and set some Lucee configs, all good. Then I just stopped the server. Oops, all gone, back to what’s in .cfconfig.json on server restart. Not that big a deal, I know the app and could recreate them (though I did learn about one Lucee setting it changed that I wasn’t aware of…). Bottom line is that if I’m using Commandbox and CFConfig to manage my dev environments, which I will be unless I hit show-stoppers, those configs I want kept, like it was a standalone server.

But like Den said, ghost echoes are the bane of test repeatability, so those servers should revert to a known state every time.

So Brad, allowing per-server override is a win-win in my book.

I’m not as widely versed in the ways of the cmd line as present company. Maybe an option to confirm before quitting cmd box?

That’s not how CLI work. I’ve never seen one that asked you if you really meant it when you hit Ctrl+C.

a newly started instance should be able to see and control servers started by another box instance that’s no longer running.

Yes, that should totally work. That said, I’ve had some issues on my Windows machine where the CLI process gets tied to the server process but I have a ticket in for Denny to look at in Runwar How’s that going Denny?? :slight_smile:

stop --all didn’t stop it.

It sounds like you started more than one server in the same directory with the same name. If it happens again, dump out the stop port of the current server:

server info property=stopSocket

and then use netstat on your OS to see if that port is bound to the server process in question.

I actually would like to set that for a single server,

Sounds like a good addition. Can you add a ticket?
https://ortussolutions.atlassian.net/projects/CFCONFIG/issues
Pull requests are also welcome!

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

I'm not as widely versed in the ways of the cmd line as present

company. Maybe an option to confirm before quitting cmd box?

That's not how CLI work. I've never seen one that asked you if you
really meant it when you hit Ctrl+C.

I think some use ctrl+D... this actually just came up for the WildFly
CLI, I'm kind of liking their direction, what do you think?

https://developer.jboss.org/wiki/CLI-RevisitCtrl-CAndCtrl-DHandling

a newly started instance should be able to see and control servers

started by another box instance that's no longer running.

Yes, that should totally work. That said, I've had some issues on my
Windows machine where the CLI process gets tied to the server process
but I have a ticket in for Denny to look at in Runwar How's that going
Denny?? :slight_smile:

Been looking into it. Just don't use Windows much myself these days so
you know how it goes. :-/ (The main reason I'd run it before was for
SQL Server, but now I'm using a docker image for the linux version which
works well and keeps everything under build control.)

I'm thinking I'll probably take a look at how Gradle does stuff, they
keep a process running for a while after you run anything so it's warmed
up for the next call, which is something we've been looking at doing for
a while, at the least there will be some good ideas there I reckon.

(That's a bit separate from the server stuff per se but same ballpark.)

:Den

I think some use ctrl+D… this actually just came up for the WildFly
CLI, I’m kind of liking their direction, what do you think?

Hmm, that’s interesting. I can’t control what happens when the user hits “X” on the window, since that’s part of the cmd process, but I do get to decide what happens when they hit Ctrl+C from the interactive shell. JLine raises an exception that I catch to handle it. I don’t know that JLine does any handling of Ctrl+D though. I guess I could see a use case where when you’re in the interactive shell, and running a command, where Ctrl+C could just send you back to the CommandBox shell. If you’re running one-off commands from your OS shell, I think you would expect Ctrl+C to just kill everything Box was doing. Generally Ctrl+C is only caught if CommandBox is waiting on user input. For instance, if you hit Ctrl+C while waiting for user input in CommandBox, I already cancel the current command and put you back at the interactive shell, which is basically what we’re talking about. However, If you type Ctrl+C while a command is doing something, then it’s generally ignored until I give control back over to JLine to “read” the next line. At least, that’s the case on Windows. On Bash, Ctrl+C might be more aggressively enforced from the OS/bash.

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

"Is there a simple way to have CFConfig capture any config changes into

.CFConfig.json when the server shuts down? Or when there are changes?"<<

This sounds like a perfect excuse to write an awesome CommandBox
Interceptor! The process is covered well in the docs. There are several
commandbox modules that use the technique. Look how they utilize
moduleConfig.cfc to gain a little inspiration. It's really slick!
Interceptors are the bees knees.

--Joel

You might have missed the prior E-mail on this, but that functionality is already implemented here:

https://cfconfig.ortusbooks.com/using-the-cli/server-interceptors/server-stop.html

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

I’m probably missing something obvious, but I’m having trouble with admin passwords when switching a CommandBox server between ACF and Lucee.

What’s the best-practice way to set the admin pw in a way that’s portable across multiple engines? I would have thought it would be with cfconfig set adminPassword=whatever, then export to .cfconfig.json, but it doesn’t seem to stick across ACF2016 and Lucee 4.5.

Anything obvious I’m doing wrong, or that I should check?

I am having issues with AdminPassword as well Dave. It is something I need to test further. It works sometimes but not others but haven’t found the pattern yet

Dave, this should work find so long as you’re storing the password in your json file as plaintext and in the “adminPassword” property. However, if you’re exporting a hashed version of the password into one of the Lucee or Adobe specific properties then it won’t work because CFConfig can’t unhash a password to transfer it.

You mentioned cfconfig set and then cfconfig export, but it actually depends on which engine you set it into and whether you started that engine prior to exporting it! (Adobe engines set initially in their config file as plain text, but get auto-hashed the first time the engine starts up, unlike Lucee, which gets hashed immediately upon being set)

Check that you’ve got a plain text password in your JSON file under “adminPassword” and let me know if that still doesn’t work.

Thanks!

~Brad

Thanks Brad, worked perfectly! Awesome tool!

So I’m thinking best practice from scratch would be…

  • Create .cfconfig.json manually with only a plain text password
  • Launch your preferred engine
  • Save any mapping, datasource and other configs you want from the engine’s UI
  • Export settings to .cfconfig.json, to save those mappings etc

Is that right?