diff --git a/bin/manager.bat b/bin/manager.bat index 713a006..7993f46 100644 --- a/bin/manager.bat +++ b/bin/manager.bat @@ -59,7 +59,8 @@ if /I "%1"=="--port" ( echo Usage: .\manager [--port port] [ --storage /path/to/storage.json] echo [ --reset ] # make current host the manager echo [ --cluster "server1,server2"] # add extra workers on setup - shift + shift + exit ) else (exit) goto parseArgs diff --git a/bin/storage-cli.js b/bin/storage-cli.js index 7e44a99..3c152ce 100755 --- a/bin/storage-cli.js +++ b/bin/storage-cli.js @@ -208,6 +208,8 @@ var storage = new StandaloneStorage(config.Storage, function (err) { // setup new manager server var setup = require('../conf/setup.json'); + let minimal = (process.env['CRONICLE_setup'] === 'minimal') + // make sure this is only run once // changing exit code to 0, so it won't break docker entry point storage.get('global/users', async function (err) { @@ -230,18 +232,29 @@ var storage = new StandaloneStorage(config.Storage, function (err) { var func = params.shift(); params.push(callback); + let obj = {} + // massage a few params if (typeof (params[1]) == 'object') { - var obj = params[1]; + obj = params[1]; if (obj.created) obj.created = Tools.timeNow(true); if (obj.modified) obj.modified = Tools.timeNow(true); if (obj.regexp && (obj.regexp == '_HOSTNAME_')) obj.regexp = '^(' + Tools.escapeRegExp(hostname) + ')$'; if (obj.hostname && (obj.hostname == '_HOSTNAME_')) obj.hostname = hostname; if (obj.ip && (obj.ip == '_IP_')) obj.ip = ip; + //if (obj.optional) { verbose("skipping " + params[0]); return callback(); } + } + + + if(minimal && obj.optional) { + // skip optional objects + callback() + } + else { + // call storage directly + storage[func].apply(storage, params); } - // call storage directly - storage[func].apply(storage, params); }, function (err) { if (err) throw err; diff --git a/bundle b/bundle index 5c7fe09..e0cba68 100755 --- a/bundle +++ b/bundle @@ -345,7 +345,7 @@ else fi if [ "$oracle" = 1 ]; then - sqlDrivers+=("oracledb") + sqlDrivers+=("oracledb@6.5.0") else sqlArgs+=("--external:oracledb") fi diff --git a/bundle.ps1 b/bundle.ps1 index aefe54e..b832c34 100644 --- a/bundle.ps1 +++ b/bundle.ps1 @@ -359,7 +359,7 @@ if($SQL) { $Oracle = $MSSQL = $Mysql = $Pgsql = $true } $Mysql ? $sqlDrivers.Add("mysql2"): $sqlArgs.Add("--external:mysql2") | Out-Null $Pgsql ? $sqlDrivers.AddRange(@("pg", "pg-query-stream")) : $sqlArgs.AddRange(@("--external:pg", "--external:pg-query-stream")) | Out-Null -$Oracle ? $sqlDrivers.Add("oracledb") : $sqlArgs.Add("--external:oracledb") | Out-Null +$Oracle ? $sqlDrivers.Add("oracledb@6.5.0") : $sqlArgs.Add("--external:oracledb") | Out-Null $MSSQL ? $sqlDrivers.Add("tedious") : $sqlArgs.Add("--external:tedious") | Out-Null $Sqlite ? $sqlDrivers.Add("sqlite3") : $sqlArgs.Add("--external:sqlite3") | Out-Null diff --git a/engines/SQLExamples/DDL.sql b/engines/SQLExamples/DDL.sql index dbd9d1d..59f6836 100644 --- a/engines/SQLExamples/DDL.sql +++ b/engines/SQLExamples/DDL.sql @@ -31,7 +31,7 @@ CREATE TABLE cronicle ( ) ------- oracle -CREATE TABLE cronicle5 ( +CREATE TABLE cronicle ( K varchar(256) PRIMARY KEY, V blob, created timestamp DEFAULT CURRENT_TIMESTAMP, diff --git a/htdocs/js/pages/Schedule.class.js b/htdocs/js/pages/Schedule.class.js index f9c589a..38823c0 100644 --- a/htdocs/js/pages/Schedule.class.js +++ b/htdocs/js/pages/Schedule.class.js @@ -908,9 +908,16 @@ Class.subclass(Page.Base, "Page.Schedule", { let niceTiming = summarize_event_timing(item.timing, item.timezone, (inactiveTitle || isGrid) ? null : item.ticks) + let gridTiming = niceTiming.length > 20 ? summarize_event_timing_short(item.timing) : niceTiming + let gridTimingTitle = niceTiming; + if (inactiveTitle) { + gridTiming = `${gridTiming}` + gridTimingTitle = `${inactiveTitle}
${niceTiming}` niceTiming = `${niceTiming}` - if (item.ticks) niceTiming += ` + ` + if (item.ticks) niceTiming += ` + ` + + } let now = Date.now() / 1000 @@ -921,7 +928,7 @@ Class.subclass(Page.Base, "Page.Schedule", { self.getNiceCategory(cat, col_width), self.getNicePlugin(plugin, col_width), self.getNiceGroup(group, item.target, col_width), - niceTiming + (isGrid ? '' : chainInfo), + niceTiming + chainInfo, '' + status_html + '', get_text_from_seconds(now - item.modified, true, true), //modified actions.join(' | ') @@ -978,18 +985,16 @@ Class.subclass(Page.Base, "Page.Schedule", { } // group_by - let timingTitle = niceTiming; - let timing = niceTiming.length > 20 ? summarize_event_timing_short(item.timing) : tds[5] - - + // timing title in grid view + if(item.ticks) { - timingTitle += `

Extra ticks: ${item.ticks}` - timing += "+" + gridTimingTitle += `

Extra ticks: ${item.ticks}` + gridTiming += "+" } if(app.chained_jobs[item.id]) { - timingTitle += ('

' + app.chained_jobs[item.id]) - timing += "<"; + gridTimingTitle += ('

' + app.chained_jobs[item.id]) + gridTiming += "<"; } let lastStatus = 'event-none' @@ -1016,7 +1021,7 @@ Class.subclass(Page.Base, "Page.Schedule", {
${actions.join(' | ')}
- ${timing} + ${gridTiming}
diff --git a/package-lock.json b/package-lock.json index b646820..2ee5b34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cronicle-edge", - "version": "1.9.0", + "version": "1.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cronicle-edge", - "version": "1.9.0", + "version": "1.9.2", "license": "MIT", "dependencies": { "@iarna/toml": "^2.2.5", diff --git a/package.json b/package.json index 325933d..91d77a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cronicle-edge", - "version": "1.9.2", + "version": "1.9.3", "description": "A simple, distributed task scheduler and runner with a web based UI.", "author": "Joseph Huckaby ", "homepage": "https://github.com/jhuckaby/Cronicle", diff --git a/sample_conf/setup.json b/sample_conf/setup.json index e90d530..591f8ac 100644 --- a/sample_conf/setup.json +++ b/sample_conf/setup.json @@ -135,7 +135,8 @@ "created": 1434125333, "params": [ { "id":"prefix", "type":"text", "size":20, "title":"Env Prefix", "value": "JOB_" } - ] + ], + "optional": true } ], [ "listPush", "global/plugins", { @@ -280,37 +281,43 @@ "id": "base_app_url", "title": "base_app_url", "key": "http://localhost:3012", - "description": "overrides app url displayed in notifications" + "description": "overrides app url displayed in notifications", + "optional": true }], [ "listPush", "global/conf_keys", { "id": "ad_domain", "title": "ad_domain", "key": "corp.cronicle.com", - "description": "default AD domain for external auth. You can also prepend domain to the username (e.g. user@domain.com)" + "description": "default AD domain for external auth. You can also prepend domain to the username (e.g. user@domain.com)", + "optional": true }], [ "listPush", "global/conf_keys", { "id": "smtp_hostname", "title": "smtp_hostname", "key": "mailrelay.cronicle.com", - "description": "SMTP server (port 25 is used default)" + "description": "SMTP server (port 25 is used default)", + "optional": true }], [ "listPush", "global/conf_keys", { "id": "email_from", "title": "email_from", "key": "admin@cronicle.com", - "description": "Notification sender" + "description": "Notification sender", + "optional": true }], [ "listPush", "global/conf_keys", { "id": "admin_web_hook", "title": "admin_web_hook", "key": "", - "description": "Webhook for activity log notifications. Uses slack markdown.\nTip: use cronicle run api to handle notification with custom event" + "description": "Webhook for activity log notifications. Uses slack markdown.\nTip: use cronicle run api to handle notification with custom event", + "optional": true }], [ "listPush", "global/conf_keys", { "id": "custom_live_log_socket_url", "title": "custom_live_log_socket_url", "key": "http://localhost:3012", - "description": "!this requires browser page refresh\noverrides the host for live log connection. On multinode cluster this can be assigned to each node, e.g. \ncustom_live_log_socket_url.manager\ncustom_live_log_socket_url.worker1\nCan specify custom port too. This is useful if using reverse proxy or docker/swarm" + "description": "!this requires browser page refresh\noverrides the host for live log connection. On multinode cluster this can be assigned to each node, e.g. \ncustom_live_log_socket_url.manager\ncustom_live_log_socket_url.worker1\nCan specify custom port too. This is useful if using reverse proxy or docker/swarm", + "optional": true }] ,[ "listPush", "global/conf_keys", { @@ -388,21 +395,24 @@ "id": "oninfo_web_hook", "title": "oninfo_web_hook", "key": "", - "description": "Special webhook - will fire on info message, e.g. server startup/restart/error. Those messages appear on activity log" + "description": "Special webhook - will fire on info message, e.g. server startup/restart/error. Those messages appear on activity log", + "optional": true }] ,[ "listPush", "global/conf_keys", { "id": "universal_web_hook", "title": "universal_web_hook", "key": "", - "description": "Special webhook - will fire on each job start/completion" + "description": "Special webhook - will fire on each job start/completion", + "optional": true }] ,[ "listPush", "global/conf_keys", { "id": "onupdate_web_hook", "title": "onupdate_web_hook", "key": "", - "description": "Special webhook - will fire on metadata update (e.g. on event update)" + "description": "Special webhook - will fire on metadata update (e.g. on event update)", + "optional": true }] ,[ "listPush", "global/conf_keys", { @@ -410,7 +420,8 @@ "title": "ui.live_log_ws", "type": "bool", "key": false, - "description": "Turns on classic websocket api for live log" + "description": "Turns on classic websocket api for live log", + "optional": true }] ,[ "listPush", "global/conf_keys", {