CFConfig Hacking. <@U06V253M4>, I still don't hav...
# lucee
j
CFConfig Hacking. @bdw429s, I still don't have this working locally, but this gets me closer: https://github.com/Ortus-Solutions/cfconfig/pull/61
i can keep tweaking the readme as the missing pieces come into focus.
i might not get time to actually hack on cfconfig but heads up that i'm getting a lot of this kind of thing:
Not sure about this path:
/cfconfig-services
Is that the expected name of the git working copy directory? It naturally is
cfconfig
.
b
Yes, that's the name of the repo and it's prolly the dir the code expects to live in
I put a comment on Github, but I basically haven't used a web server to hack on cfconfig in years
I just link the module to the CommandBox core and hack on it in the CLI
• uninstall any forgebox CLI module from CommandBox • clone
commandbox-cfconfig
and
config-services
repos • run
box install
from the root of the services one (but NOT the commandbox one) •
package link
them both (just run that command from the root) • You can now test import/export commands from the CLI using your checked out repos. Use
reload
(
r
) to pick up changes to the files between tests
This is the easiest way to test changes with an actual server and actual config files right there in the CLI
j
thanks for the alternate approach. i'm going to have to put the lucee 6 upgrade down for a while and move on to some completely unrelated stuff. for now, i've documented the problems i found with scheduled tasks and gateways in lucee 6: https://cfml.slack.com/archives/C06TA0A9W/p1739403522177949?thread_ts=1739315550.543899&amp;cid=C06TA0A9W
b
Urgh, sorry about all that
I don't have a ton of time ATM since we're trying hard to get our BoxLang release candidate out the door
And since we're moving a lot of our Ortus sites to BL, we haven't been as hot on our testing of latest Lucee versions either
I'll have to circle back and figure out the differences in the JSON formats soon
j
no prob, thanks. on the plus side, scheduled tasks and gateways are the only (obvious) problems i spotted in a smoke test.
b
Well, it's prolly a simple matter of massaging the data to the correct format. It can just be rather time consuming to actually figure out what that format is!
👍 1
@bdw429s i was making progress but i keep coming back to a central issue: if cfconfig is meant to offer "write once and run anywhere!" functionality (which i always assumed was one of its selling points but please let me know if that's an incorrect assumption): ...it needs to have a canonical (documented) spec. for instance: • docs/specs need to go beyond just the root level, simple data type flags (which is the extent of the current docs) • need scheduled tasks? here's the syntax: ... • need a scheduled task to be paused? here's the flag for that:
schmaused = "flarp"
without a spec, i'm stuck. i don't think the spec can be adequately gleaned from function signatures (optional argument lists) because that seems to be a bit of a kitchen sink, at the moment. a developer approaching a fresh project should, IMO, be able to write, say, an engine-agnostic scheduled task definition from scratch in
config.json
from docs (as opposed to reverse-engineering from an engine admin output and then relying on whatever engine quirks that the
cfconfig export
yields). defining (or partially reverse-engineering) a spec is a tough thing to do as a contributor. it's a common issue i've had with open source project which have hindered contributions before. (i've had to bail out on contributions to other open source projects for the same reason.) ortus has great documentation, in general, but this particular gap is getting me.
b
I think that's a great idea to have docs like that, but I'm not inclinded to spend the incredible amount of time it would take to make them. And that's mostly because 99.9% of CFConfig users don't care and have never asked for such a thing. The typical user of CFConfig exports the config from a server, stashes the magical JSON file and moves on with their day. The list of supported items is large, changes frequently, and is only partially-implemented by each engine. I've never heard of anyone attempting to type up an entire cfconfig.json file from scratch-- it sounds sort of terrible. I think trying to understand the totality of it may be part of the issue. What specific key are you trying to make work at the moment? Reverse-engineering is basically the name of the game here. If you want to know the "working" way that CFConfig was storing Lucee scheduled tasks prior to Lucee 6, the fastest and simplest approach is simply to toss a scheduled task in the UI of a Lucee 5 server and run
cfconfig show
and you'll instantly see what it looks like. I'd happily accept pulls that try to flesh out more examples-- especially for things like mail servers, datasources, or schedule tasks, but trying to cover every possible variation could require hundreds of pages of examples, which to be honest, no one is going to read. What I did spend more time documenting was the CLI for adding specific complex types such as datasources or scheduled tasks. Each of those docs contain copy/paste examples which should create the necessary JSON for you. Ex: https://cfconfig.ortusbooks.com/using-the-cli/command-overview/manage-scheduled-tasks
Copy code
cfconfig task save myTask <http://www.google.com> Once 4/13/2018 "5:00 PM"
cfconfig task save task=myTask url=<http://www.google.com> interval=Once startDate=4/13/2018 startTime="5:00 PM" to=serverName
cfconfig task save task=myTask url=<http://www.google.com> interval=Once startDate=4/13/2018 startTime="5:00 PM" to=/path/to/server/home
Just point one of those commands to your JSON file and it will write the config there. The CLI help for these commands also lists out all the parameters
Copy code
cfconfig task save ?
It had seemed easier to document the API of the CLI commands than the underlying JSON format, which is generally created for you.
As far as the structure of the JSON files for someone wanting to contribute, it seems pretty straightforward. Each property in the baseconfig represents a possible top-level key in the JSON. And for the "complex" types, the arguments to the
addXXX()
method documents what the nested structs may look like
So, for
addScheduledTask()
we have a method signature of
Copy code
/**
	* Add a single Scheduled Task to the config
	* @task The name of the task
	* @url The full URL to hit
	* @group The group for the task (Adobe only)
	* @chained Is this task chained? (Adobe only)
	* @clustered Is this task clustered? (Adobe only)
	* @crontime Schedule in Cron format (Adobe only)
	* @endDate Date when task will end as 1/1/2000
	* @endTime Time when task will end as 9:57:00 AM
	* @eventhandler Specify a dot-delimited CFC path under webroot, for example a.b.server (without the CFC extension). The CFC should implement CFIDE.scheduler.ITaskEventHandler. (Adobe only)
	* @exclude Comma-separated list of dates or date range for exclusion in the schedule period. (Adobe only)
	* @file Save output of task to this file
	* @httpPort The port for the main task URL
	* @httpProxyPort The port for the proxy server
	* @interval The type of schedule. Once, Weekly, Daily, Monthly, an integer containing the number of seconds between runs
	* @misfire What to do in case of a misfire.  Ignore, FireNow, invokeHander (Adobe only)
	* @oncomplete Comma-separated list of chained tasks to be run after the completion of the current task (task1:group1,task2:group2...) (Adobe only)
	* @onexception Specify what to do if a task results in error. Ignore, Pause, ReFire, InvokeHandler (Adobe only)
	* @overwrite Overwrite the log file? (Adobe only)
	* @password Basic auth password to use when hitting URL
	* @priority An integer that indicates the priority of the task. (Adobe only)
	* @proxyPassword Proxy server password
	* @proxyServer Name of the proxy server to use
	* @proxyUser Proxy server username
	* @saveOutputToFile Save output to a file?
	* @repeat -1 to repeat forever, otherwise integer.
	* @requestTimeOut Number of seconds to timeout the request.  Empty string for none.
	* @resolveurl When saving output of task to file, Resolve internal URLs so that links remain intact.
	* @retrycount The number of reattempts if the task results in an error. (Adobe only)
	* @startDate The date to start executing the task
	* @startTime The date to end excuting the task
	* @status The current status of the task.  Running, Paused
	* @username Basic auth username to use when hitting URL
	* @autoDelete (Lucee only)
	* @hidden Do not show in admin UI (Lucee only)
	* @unique  If set run the task only once at time. Every time a task is started, it will check if still a task from previous round is running, if so no new test is started. (Lucee only)
	*/
	function addScheduledTask(
		required string task,
		string url,
		string group,
		boolean chained,
		boolean clustered,
		string crontime,
		string endDate,
		string endTime,
		string eventhandler,
		string exclude,
		string file,
		string httpPort,
		string httpProxyPort,
		string interval,
		string misfire,
		string oncomplete,
		string onexception,
		string overwrite,
		string password,
		string priority,
		string proxyPassword,
		string proxyServer,
		string proxyUser,
		boolean saveOutputToFile,
		string repeat,
		string requestTimeOut,
		boolean resolveurl,
		string retryCount,
		string startDate,
		string startTime,
		string status,
		string username,
		string autoDelete,
		string hidden,
		string unique
		) {
so any of those params can be a key in a sched task struct, of the type specified, and matching the description specified
Yeah, it's a bit of a kitchen sink, but but that's because there's a LOT of different things which may be stored! (a dozen of which only apply to Adobe, a handful of which only apply to Lucee, and only some of which are actually used on a regular basis.
So based on that, I could presumably start typing up a JSON file from scratch with a basic idea of all the keys I can store for a scheduled task. That's just not a use case I've ever heard of anyone doing tho
j
let me ask a specific question first: what's different about a
cfconfig import
to a plain directory versus what happens when i am in the "box" cli context and do a
cfconfig import
there? i had it generating json that looked good in the first case but after doing the import into the running server, then doing a
cfconfig show
, it was missing scheduled task subkeys that i had been writing.
b
If the
to
param is omitted, the CLI will look for a CommandBox sever defined in the current folder, and point itself as the server home of that server (and detect the engine name and version) If the
to
param points directly to a folder on disk, then the XML/JSON/properties files will be written out for the CF engine/version (whether explicitly provided in the
toFormat
or detect based on the contents of the file system)
`config show`'s
from
and
fromFormat
follow the same rules, just applied to reading instead of writing
If the
to
or
from
is a file path pointing to a JSON file, then the config is read or written as CFConfig's JSON format (no CF engine)
i had it generating json that looked good in the first case but after doing the import into the running server, then doing a
cfconfig show
, it was missing scheduled task subkeys that i had been writing.
Presumably, that key was not being written to Lucee's cfconfig.json in the server home, and wasn't there to read back out, you'd have to import and then look to see what got written.
j
thanks for the info. i may pick back up on this next week. i have an idea for docs but i'll think more about it later. i'm not actually looking for all of the different json examples, but documentation for the keys. the info contained in the addScheduledTask() annotations is close.
tbh, i'm not sure i even noticed the annotations before (🤦 )