From 9cf197c9ac5226e9ebe142acee231fcef5b8f801 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Mon, 1 Dec 2008 13:47:35 +0000 Subject: Rewrote cron to make it do something. git-svn-id: svn://svn.alpinelinux.org/acf/alpine-baselayout/trunk@1613 ab2d0c66-481e-0410-8bed-d214d4d58bed --- Makefile | 1 + alpine-baselayout.roles | 8 +-- cron-controller.lua | 32 ++++++++--- cron-createjob-html.lsp | 1 + cron-editjob-html.lsp | 1 + cron-expert-html.lsp | 1 + cron-listjobs-html.lsp | 37 +++++++++++++ cron-model.lua | 141 ++++++++++++++++++++++++++++++++++++++++-------- cron-startstop-html.lsp | 1 + cron-status-html.lsp | 1 + cron.menu | 4 ++ 11 files changed, 195 insertions(+), 33 deletions(-) create mode 120000 cron-createjob-html.lsp create mode 120000 cron-editjob-html.lsp create mode 120000 cron-expert-html.lsp create mode 100644 cron-listjobs-html.lsp create mode 120000 cron-startstop-html.lsp create mode 120000 cron-status-html.lsp create mode 100644 cron.menu diff --git a/Makefile b/Makefile index 28a6bf1..02dd0aa 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ APP_DIST=\ rc* \ password* \ modules* \ + cron* \ EXTRA_DIST=README Makefile config.mk diff --git a/alpine-baselayout.roles b/alpine-baselayout.roles index e03c65f..7c54f1c 100644 --- a/alpine-baselayout.roles +++ b/alpine-baselayout.roles @@ -1,5 +1,5 @@ GUEST=health:system,hostname:read -USER=health:storage,health:proc,health:network,health:modules,health:networkstats,interfaces:status,interfaces:read,interfaces:restart,logfiles:status,logfiles:view,logfiles:download,logfiles:tail,modules:status,skins:update,skins:read,syslog:status,syslog:loginfo,syslog:startstop,rc:status -EDITOR=hostname:edit,interfaces:delete,interfaces:create,interfaces:update,interfaces:ifup,interfaces:ifdown,logfiles:delete,syslog:config,rc:edit -EXPERT=syslog:expert,interfaces:editintfile,modules:edit,modules:reload -ADMIN=health:system,hostname:read,health:storage,health:proc,health:network,health:modules,health:networkstats,interfaces:status,interfaces:read,interfaces:restart,logfiles:status,logfiles:view,logfiles:download,logfiles:tail,modules:status,skins:update,skins:read,syslog:status,syslog:loginfo,syslog:startstop,rc:status,hostname:edit,interfaces:delete,interfaces:create,interfaces:update,interfaces:ifup,interfaces:ifdown,logfiles:delete,syslog:config,rc:edit,syslog:expert,interfaces:editintfile,modules:edit,modules:reload,password:edit +USER=cron:status,cron:startstop,health:storage,health:proc,health:network,health:modules,health:networkstats,interfaces:status,interfaces:read,interfaces:restart,logfiles:status,logfiles:view,logfiles:download,logfiles:tail,modules:status,skins:update,skins:read,syslog:status,syslog:loginfo,syslog:startstop,rc:status +EDITOR=cron:listjobs,hostname:edit,interfaces:delete,interfaces:create,interfaces:update,interfaces:ifup,interfaces:ifdown,logfiles:delete,syslog:config,rc:edit +EXPERT=cron:editjob,cron:deletejob,cron:createjob,cron:expert,syslog:expert,interfaces:editintfile,modules:edit,modules:reload +ADMIN=cron:status,cron:startstop,cron:listjobs,cron:editjob,cron:deletejob,cron:createjob,cron:expert,health:system,hostname:read,health:storage,health:proc,health:network,health:modules,health:networkstats,interfaces:status,interfaces:read,interfaces:restart,logfiles:status,logfiles:view,logfiles:download,logfiles:tail,modules:status,skins:update,skins:read,syslog:status,syslog:loginfo,syslog:startstop,rc:status,hostname:edit,interfaces:delete,interfaces:create,interfaces:update,interfaces:ifup,interfaces:ifdown,logfiles:delete,syslog:config,rc:edit,syslog:expert,interfaces:editintfile,modules:edit,modules:reload,password:edit diff --git a/cron-controller.lua b/cron-controller.lua index 43a76d3..ae8abee 100644 --- a/cron-controller.lua +++ b/cron-controller.lua @@ -1,16 +1,34 @@ -- the cron controller - module (..., package.seeall) --- Public methods +require("controllerfunctions") + +default_action = "status" + +function status(self) + return self.model.getstatus() +end + +function startstop(self) + return controllerfunctions.handle_startstop(self, self.model.startstop_service, self.model.getstatus, self.clientdata) +end -default_action = "read" +function listjobs(self) + return self.model.listjobs() +end -read = function (self) - return ({ crontab = self.model:get()} ) +function editjob(self) + return controllerfunctions.handle_form(self, function() return self.model.read_job(self.clientdata.name) end, self.model.update_job, self.clientdata, "Save", "Edit Job", "Job Saved") end +function deletejob(self) + return self:redirect_to_referrer(self.model.delete_job(self.clientdata.name)) +end + +function createjob(self) + return controllerfunctions.handle_form(self, self.model.create_new_job, self.model.create_job, self.clientdata, "Create", "Create New Job", "New Job Created") +end -update = function (self) - return ( {status = self.model:set() }) +function expert(self) + return controllerfunctions.handle_form(self, self.model.read_configfile, self.model.update_configfile, self.clientdata, "Save", "Edit Config File", "Configuration Set") end diff --git a/cron-createjob-html.lsp b/cron-createjob-html.lsp new file mode 120000 index 0000000..4b6b762 --- /dev/null +++ b/cron-createjob-html.lsp @@ -0,0 +1 @@ +../form-html.lsp \ No newline at end of file diff --git a/cron-editjob-html.lsp b/cron-editjob-html.lsp new file mode 120000 index 0000000..15b1930 --- /dev/null +++ b/cron-editjob-html.lsp @@ -0,0 +1 @@ +../filedetails-html.lsp \ No newline at end of file diff --git a/cron-expert-html.lsp b/cron-expert-html.lsp new file mode 120000 index 0000000..207f324 --- /dev/null +++ b/cron-expert-html.lsp @@ -0,0 +1 @@ +../expert-html.lsp \ No newline at end of file diff --git a/cron-listjobs-html.lsp b/cron-listjobs-html.lsp new file mode 100644 index 0000000..6f21673 --- /dev/null +++ b/cron-listjobs-html.lsp @@ -0,0 +1,37 @@ +<% local view, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<% displaycommandresults({"editjob", "deletejob"}, session) %> +<% displaycommandresults({"createjob"}, session, true) %> + +<% if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("status") +end %> + +

Cron Jobs

+<% for i,tabl in ipairs(view.value) do %> +

<%= tabl.period %>

+ <% if #tabl.jobs == 0 then %> +No jobs + <% else %> + + + + + + <% for i,job in ipairs(tabl.jobs) do %> + + + + + <% end %> +
ActionJob
+ <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/editjob?name="..job.."&redir="..page_info.orig_action, label="Edit "} %> + <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/deletejob?name="..job, label="Delete "} %> + <%= string.gsub(job, "^.*/", "") %>
+ <% end %> +<% end %> + +<% if viewlibrary and viewlibrary.dispatch_component and session.permissions.cron.createjob then + viewlibrary.dispatch_component("createjob") +end %> diff --git a/cron-model.lua b/cron-model.lua index 1f39296..65d4393 100644 --- a/cron-model.lua +++ b/cron-model.lua @@ -1,29 +1,126 @@ module (..., package.seeall) -require "format" -require "fs" - -get = function (self) - f = io.open("/etc/crontabs/root") - crontab = f:read("*a") - - f:close() - return (cfe{value=crontab, name="crontab",type="longtext"}) -end - -set = function(self, cron) - checksum1 = fs.md5sum_file("/etc/crontabs/root") - newcron = format.dostounix(cron) - file.write_file("/etc/crontabs/root", newcron) - checksum2 = fs.md5sum_file("/etc/crontabs/root") - if checksum1 == checksum2 then - status = "Crontab file unchanged." - else - status = "Crontab file changed successfully" + +require("modelfunctions") +require("format") +require("fs") +require("validator") + +local configfile = "/etc/crontabs/root" +local processname = "crond" +local packagename = "busybox" +local servicename = "cron" +local baseurl = "/etc/periodic/" + +local periods +-- ################################################################################ +-- LOCAL FUNCTIONS + +local function list_periods() + if not periods then + periods = {} + local file = fs.read_file(configfile) or "" + for dir in string.gmatch(file, "/etc/periodic/(%S+)") do + periods[#periods+1] = dir + end +--[[ local reverseperiods = {} + for i,per in ipairs(periods) do reverseperiods[per] = i end + for dir in posix.files(baseurl) do + if fs.is_dir(baseurl .. dir) and (dir ~= ".") and (dir ~= "..") and not reverseperiods[dir] then + periods[#periods+1] = dir + end + end--]] end - - return(cfe{value=status, name="status"}) + return periods end +local function validate_filename(name) + local success = false + for i,per in ipairs(list_periods()) do + if validator.is_valid_filename(name, baseurl..per) then + success = true + break + end + end + return success +end +-- ################################################################################ +-- PUBLIC FUNCTIONS + +function startstop_service(action) + return modelfunctions.startstop_service(servicename, action) +end +function getstatus() + return modelfunctions.getstatus(processname, packagename, "Cron Status", servicename) +end + +function listjobs() + local jobs = {} + for i,period in ipairs(list_periods()) do + local temp = {period=period, jobs={}} + for file in fs.find("[^.]+", baseurl..period) do + table.insert(temp.jobs, file) + end + jobs[#jobs+1] = temp + end + return cfe({ type="structure", value=jobs, label="Cron Jobs" }) +end + +function read_job(filename) + return modelfunctions.getfiledetails(filename, validate_filename) +end + +function update_job(filedetails) + return modelfunctions.setfiledetails(filedetails, validate_filename) +end +function delete_job(filename) + local retval = cfe({ label="Delete Job Result", errtxt="Invalid file" }) + if validate_filename(filename) then + os.remove(filename) + retval.value = "Job File Deleted" + retval.errtxt = nil + end + return retval +end + +function create_new_job() + local newjob = {} + newjob.name = cfe({ label="Name" }) + newjob.period = cfe({ type="select", label="Period", option=list_periods() }) + return cfe({ type="group", value=newjob, label="Create New Job" }) +end + +function create_job(newjob) + local success = modelfunctions.validateselect(newjob.value.period) + + if newjob.value.name.value == "" then + newjob.value.name.errtxt = "Missing File Name" + success = false + elseif string.find(newjob.value.name.value, "[^%w_-]") then + newjob.value.name.errtxt = "Invalid File Name" + success = false + elseif posix.stat(baseurl..newjob.value.period.value.."/"..newjob.value.name.value) then + newjob.value.name.errtxt = "File already exists" + success = false + end + + if success then + fs.create_file(baseurl..newjob.value.period.value.."/"..newjob.value.name.value) + else + newjob.errtxt = "Failed to create new job" + end + + return newjob +end + +function read_configfile() + -- FIXME validate + return modelfunctions.getfiledetails(configfile) +end + +function update_configfile(filedetails) + -- FIXME validate + return modelfunctions.setfiledetails(filedetails, {configfile}) +end diff --git a/cron-startstop-html.lsp b/cron-startstop-html.lsp new file mode 120000 index 0000000..0ea2627 --- /dev/null +++ b/cron-startstop-html.lsp @@ -0,0 +1 @@ +../startstop-html.lsp \ No newline at end of file diff --git a/cron-status-html.lsp b/cron-status-html.lsp new file mode 120000 index 0000000..b2f8480 --- /dev/null +++ b/cron-status-html.lsp @@ -0,0 +1 @@ +../status-html.lsp \ No newline at end of file diff --git a/cron.menu b/cron.menu new file mode 100644 index 0000000..61430d8 --- /dev/null +++ b/cron.menu @@ -0,0 +1,4 @@ +#CAT GROUP/DESC TAB ACTION +System 21Cron Status status +System 21Cron Jobs listjobs +System 21Cron Expert expert -- cgit v1.2.3