diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | apk-available-html.lsp | 34 | ||||
-rw-r--r-- | apk-controller.lua | 24 | ||||
-rw-r--r-- | apk-details-html.lsp | 30 | ||||
-rw-r--r--[l---------] | apk-expert-html.lsp | 23 | ||||
-rw-r--r-- | apk-loaded-html.lsp (renamed from apk-html.lsp) | 41 | ||||
-rw-r--r-- | apk-model.lua | 219 | ||||
-rw-r--r-- | apk.roles | 6 |
8 files changed, 333 insertions, 46 deletions
@@ -1,6 +1,6 @@ APP_NAME=apk-tools PACKAGE=acf-$(APP_NAME) -VERSION=0.2.0 +VERSION=0.3.0 APP_DIST=\ apk* \ diff --git a/apk-available-html.lsp b/apk-available-html.lsp new file mode 100644 index 0000000..808a513 --- /dev/null +++ b/apk-available-html.lsp @@ -0,0 +1,34 @@ +<% local form, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<% displaycommandresults({"upgrade", "install"}, session) %> + +<H1><%= form.label %></H1> +<DL> +<TABLE> + <TR style="background:#eee;font-weight:bold;"> + <% if session.permissions.apk.install or session.permissions.apk.upgrade then %> + <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD> + <% end %> + <TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD> + <TD style="white-space:nowrap;" WIDTH="90%" class="header">Version</TD> + </TR> + +<% for i,packagetable in pairs(form.value) do %> + <TR> + <% if session.permissions.apk.install or session.permissions.apk.upgrade then %> + <TD style="padding-right:20px;white-space:nowrap;"> + <% if session.permissions.apk.install and not packagetable.upgrade then %> + <%= html.link{value = "install?package=" .. packagetable.name, label="Install "} %> + <% end %> + <% if session.permissions.apk.upgrade and packagetable.upgrade then %> + <%= html.link{value = "upgrade?package=" .. packagetable.name, label="Upgrade "} %> + <% end %> + </TD> + <% end %> + <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD> + <TD><%= html.html_escape(packagetable.version) %></TD> + </TR> +<% end %> +</TABLE> +</DL> diff --git a/apk-controller.lua b/apk-controller.lua index 8ceace3..e3dcf75 100644 --- a/apk-controller.lua +++ b/apk-controller.lua @@ -5,16 +5,16 @@ module (..., package.seeall) default_action = "loaded" -read = function(self) - return self.model.get_packages() -end - loaded = function(self) - return cfe({ type="group", value={loaded=self.model.get_loaded_packages()} }) + return self.model.get_loaded_packages() end available = function(self) - return cfe({ type="group", value={available=self.model.get_available_packages()} }) + return self.model.get_available_packages() +end + +details = function(self) + return self.model.get_package_details(self.clientdata.package) end delete = function(self) @@ -25,6 +25,18 @@ install = function(self) return self:redirect_to_referrer(self.model.install_package(self.clientdata.package or "", self.sessiondata)) end +upgrade = function(self) + return self:redirect_to_referrer(self.model.upgrade_package(self.clientdata.package or "", self.sessiondata)) +end + expert = function(self) return controllerfunctions.handle_form(self, self.model.get_configfile, self.model.update_configfile, self.clientdata, "Save", "Edit Configuration", "Configuration Saved") end + +updateall = function(self) + return self:redirect_to_referrer(self.model.update_all()) +end + +upgradeall = function(self) + return self:redirect_to_referrer(self.model.upgrade_all()) +end diff --git a/apk-details-html.lsp b/apk-details-html.lsp new file mode 100644 index 0000000..af1cf6b --- /dev/null +++ b/apk-details-html.lsp @@ -0,0 +1,30 @@ +<% local data, viewlibrary, page_info, session = ... +require("viewfunctions") +%> + +<% displaycommandresults({"install", "upgrade"}, session) %> + +<H1><%= data.label %></H1> +<DL> +<% +displayitem(data.value.package) +displayitem(data.value.installed) +displayitem(data.value.version) +displayitem(data.value.comment) +displayitem(data.value.webpage) +displayitem(data.value.size) +displayitem(data.value.upgrade) +%> +</DL> + +<% if session.permissions[page_info.controller].install and data.value.installed.value == "" then %> +<DL><DT>Install</DT> +<DD><form action="install" method="POST"> +<input class="hidden" type="hidden" name="package" value=<%= data.value.package.value %>> +<input class="submit" type="submit" value="Install"></form></DD></DL> +<% elseif session.permissions[page_info.controller].upgrade and data.value.upgrade.value ~= "" then %> +<DL><DT>Upgrade</DT> +<DD><form action="upgrade" method="POST"> +<input class="hidden" type="hidden" name="package" value=<%= data.value.package.value %>> +<input class="submit" type="submit" value="Upgrade"></form></DD></DL> +<% end %> diff --git a/apk-expert-html.lsp b/apk-expert-html.lsp index 15b1930..a991447 120000..100644 --- a/apk-expert-html.lsp +++ b/apk-expert-html.lsp @@ -1 +1,22 @@ -../filedetails-html.lsp
\ No newline at end of file +<% local form, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<% displaycommandresults({"updateall", "upgradeall"}, session) %> + +<% +local pattern = string.gsub(page_info.prefix..page_info.controller, "[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1") +local func = haserl.loadfile(page_info.viewfile:gsub(pattern..".*$", "/") .. "filedetails-html.lsp") +func(form, viewlibrary, page_info, session) +%> + +<% if session.permissions[page_info.controller].updateall or session.permissions[page_info.controller].upgradeall then %> +<H2>Update / Upgrade</H2> +<% end %> +<% if session.permissions[page_info.controller].updateall then %> + <DL><DT>Update Index</DT> + <DD><form action="updateall" method="POST"><input class="submit" type="submit" value="Update"></form></DD></DL> +<% end %> +<% if session.permissions[page_info.controller].upgradeall then %> + <DL><DT>Upgrade All</DT> + <DD><form action="upgradeall" method="POST"><input class="submit" type="submit" value="Upgrade"></form></DD></DL> +<% end %> diff --git a/apk-html.lsp b/apk-loaded-html.lsp index afc62bd..2aae111 100644 --- a/apk-html.lsp +++ b/apk-loaded-html.lsp @@ -1,67 +1,62 @@ <% local form, viewlibrary, page_info, session = ... %> <% require("viewfunctions") %> -<% ---[[ DEBUG INFORMATION -io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") -io.write(html.cfe_unpack(form)) -io.write("</span>") ---]] -%> -<% displaycommandresults({"delete", "install"}, session) %> +<% displaycommandresults({"delete", "install", "upgrade"}, session) %> -<% if form.value.loaded then %> -<H1>Loaded Packages</H1> +<H1><%= html.html_escape(form.label) %></H1> +<H2><%= html.html_escape(form.value.toplevel.label) %></H2> <DL> <TABLE> <TR style="background:#eee;font-weight:bold;"> - <% if session.permissions.apk.delete then %> - <TD style="padding-right:20px;white-space:nowrap;" class="header">Delete</TD> + <% if session.permissions.apk.delete or session.permissions.apk.upgrade then %> + <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD> <% end %> <TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD> <TD style="padding-right:20px;white-space:nowrap;" class="header">Version</TD> <TD style="white-space:nowrap;" class="header">Description</TD> </TR> -<% for i,packagetable in pairs(form.value.loaded.value) do %> +<% for i,packagetable in pairs(form.value.toplevel.value) do %> <TR> <% if session.permissions.apk.delete then %> <TD style="padding-right:20px;white-space:nowrap;"> - <%= html.link{value = "delete?package=" .. packagetable.name, label="Delete"} %> + <%= html.link{value = "delete?package=" .. packagetable.name, label="Delete "} %> + <% if session.permissions.apk.upgrade and packagetable.upgrade then %> + <%= html.link{value = "upgrade?package=" .. packagetable.name, label="Upgrade "} %> + <% end %> </TD> <% end %> - <TD><%= html.html_escape(packagetable.name) %></TD> + <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD> <TD><%= html.html_escape(packagetable.version) %></TD> <TD><%= html.html_escape(packagetable.description) %></TD> </TR> <% end %> </TABLE> </DL> -<% end %> -<% if form.value.available then %> -<H1>Available Packages</H1> +<H2><%= html.html_escape(form.value.dependant.label) %></H2> <DL> <TABLE> <TR style="background:#eee;font-weight:bold;"> <% if session.permissions.apk.install then %> - <TD style="padding-right:20px;white-space:nowrap;" class="header">Install</TD> + <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD> <% end %> <TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD> - <TD style="white-space:nowrap;" WIDTH="90%" class="header">Version</TD> + <TD style="padding-right:20px;white-space:nowrap;" class="header">Version</TD> + <TD style="white-space:nowrap;" class="header">Description</TD> </TR> -<% for i,packagetable in pairs(form.value.available.value) do %> +<% for i,packagetable in pairs(form.value.dependant.value) do %> <TR> <% if session.permissions.apk.install then %> <TD style="padding-right:20px;white-space:nowrap;"> <%= html.link{value = "install?package=" .. packagetable.name, label="Install"} %> </TD> <% end %> - <TD><%= html.html_escape(packagetable.name) %></TD> + <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD> <TD><%= html.html_escape(packagetable.version) %></TD> + <TD><%= html.html_escape(packagetable.description) %></TD> </TR> <% end %> </TABLE> </DL> -<% end %> diff --git a/apk-model.lua b/apk-model.lua index 66a9a30..e23ecc2 100644 --- a/apk-model.lua +++ b/apk-model.lua @@ -4,26 +4,170 @@ require("apk") require("modelfunctions") local configfile = "/etc/apk/repositories" +local worldfile = "/var/lib/apk/world" -get_all_packages = function() - -- read in all of the packages - return cfe({ type="list", value=apk.get_all(), label="All Packages"}) +local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin " + +local repo = nil +local install_cache = false +local toplevel + +-- ################################################################################ +-- LOCAL FUNCTIONS + +local function gettoplevel() + if not toplevel then + toplevel = {} + local top = format.string_to_table(fs.read_file(worldfile) or "", "%s+") + for i,name in ipairs(top) do + toplevel[name] = i + end + end + return toplevel +end + +local run_apk_cmd = function(cmd) + local c = path.."apk "..cmd.." 2>&1" + local f = io.popen(c) + local cmdresult = f:read("*a") + f:close() + return cmdresult +end + +local reload_installed = function() + if repo then + -- clear out installed info + for name,value in pairs(repo) do + if value then + value.installed = nil + value.comment = nil + end + end + -- read in which are installed + local f = io.popen(path.."apk info -vv 2>/dev/null") + for line in f:lines() do + local name, ver, comment = string.match(line, "(%S+)%-(%d+%S*)%s+%-%s+(.*)") + if not repo[name] then + repo[name] = {} + end + repo[name].installed = ver + repo[name].comment = comment + end + f:close() + install_cache = true + end + return repo end +local repository = function() + if not repo then + -- read in all of the packages + local f = io.popen(path.."apk search 2>/dev/null") + repo = {} + install_cache = false + for line in f:lines() do + local name, ver = string.match(line, "(.*)%-(%d+.*)") + if name then + repo[name] = {} + repo[name].version = ver + end + end + f:close() + end + if not install_cache then + reload_installed() + end + return repo +end + +-- Find all the packages that depend on this package (using recursion) +-- package is the name of the package +-- tab saves dependants for already processed packages +-- saved marks when package included in output +-- output is the output +function find_dependants(package) + repo = repo or repository() + if not repo[package] then + return {} + end + if not repo[package].dependants then + repo[package].dependants = {} + local cmd = path .. "apk info -R "..package + local f = io.popen(cmd) + for line in f:lines() do + if not line:find("depends on:") and not line:find("^%s*$") then + table.insert(repo[package].dependants, line) + for i,dep in ipairs(find_dependants(line, saved, output)) do + table.insert(repo[package].dependants, dep) + end + end + end + end + return repo[package].dependants +end + +local function upgrade_available(package) + local retval = false + repo = repo or repository() + if repo[package] and repo[package].version > repo[package].installed then + retval = true + else -- check the dependants + for i,dep in ipairs(find_dependants(package)) do + if repo[dep] and repo[dep].version > repo[dep].installed then + retval = true + break + end + end + end + return retval +end + +-- ################################################################################ +-- PUBLIC FUNCTIONS + get_loaded_packages = function() + repo = repository() + toplevel = gettoplevel() + -- read in the loaded packages - return cfe({ type="list", value=apk.get_loaded(), label="Loaded Packages"}) + local top = cfe({ type="list", value={}, label="Top Level Packages"}) + local depend = cfe({ type="list", value={}, label="Dependant Packages"}) + for name,value in pairs(repo) do + if value.installed then + local temp = {} + temp.name = name + temp.version = value.installed + temp.description = value.comment + if toplevel[name] then + temp.upgrade = upgrade_available(name) + top.value[#top.value+1] = temp + else + depend.value[#depend.value+1] = temp + end + end + end + table.sort(top.value, function(a,b) return (a.name < b.name) end) + table.sort(depend.value, function(a,b) return (a.name < b.name) end) + return cfe({ type="group", value={toplevel=top, dependant=depend}, label="Loaded Packages" }) end get_available_packages = function() - -- available are all except loaded - return cfe({ type="list", value=apk.get_available(), label="Available Packages" }) -end - -get_packages = function() - local loaded = get_loaded_packages() - local available = get_available_packages() - return cfe({ type="group", value={loaded=loaded, available=available} }) + repo = repository() + -- available are all except same version installed + local available = cfe({ type="list", value={}, label="Available Packages" }) + for name,value in pairs(repo) do + if value.version ~= value.installed then + local temp = {} + temp.name = name + temp.version = value.version + if value.installed and value.version > value.installed then + temp.upgrade = true + end + available.value[#available.value + 1] = temp + end + end + table.sort(available.value, function(a,b) return (a.name < b.name) end) + return available end delete_package = function(package, sessiondata) @@ -46,6 +190,18 @@ install_package = function(package,sessiondata) return cfe({ value=cmdresult, label="Result of Install" }) end +upgrade_package = function(package) + return cfe({ value=run_apk_cmd("add -u "..package), label="Result of Package Upgrade" }) +end + +update_all = function() + return cfe({ value=run_apk_cmd("update"), label="Result of Update" }) +end + +upgrade_all = function() + return cfe({ value=run_apk_cmd("upgrade"), label="Result of Upgrade" }) +end + get_configfile = function() return modelfunctions.getfiledetails(configfile) end @@ -53,3 +209,42 @@ end update_configfile = function(newconfig) return modelfunctions.setfiledetails(newconfig, {configfile}) end + +get_package_details = function(package) + repo = repo or repository() + local details = {} + details.package = cfe({ value=package, label="Package" }) + details.version = cfe({ label="Available Version" }) + details.installed = cfe({ label="Installed Version" }) + details.comment = cfe({ label="Description" }) + details.webpage = cfe({ label="Web Page" }) + details.size = cfe({ label="Size" }) + details.upgrade = cfe({ label="Upgrade Details" }) + if not repo[package] then + details.package.errtxt = "Invalid package" + else + details.version.value = repo[package].version + if repo[package].installed then + --details.installed.value = string.match(cmdresult[1], "%S*") + details.installed.value = repo[package].installed + details.comment.value = repo[package].comment + local cmdresult = format.string_to_table(run_apk_cmd("info -ws "..package), "\n") + details.webpage.value = cmdresult[2] or "" + details.size.value = cmdresult[5] or "" + local dependants = find_dependants(package) + table.insert(dependants, 1, package) + local revdeps = {} + details.upgrade.value = {} + for i,val in ipairs(dependants) do + if not revdeps[val] then + revdeps[val] = true + if repo[val].version > repo[val].installed then + table.insert(details.upgrade.value, val.." "..repo[val].installed.." -> "..repo[val].version) + end + end + end + details.upgrade.value = table.concat(details.upgrade.value, "\n") + end + end + return cfe({ type="group", value=details, label="Package Details" }) +end @@ -1,3 +1,3 @@ -USER=apk:loaded,apk:available -EXPERT=apk:expert,apk:delete,apk:install -ADMIN=apk:loaded,apk:available,apk:expert,apk:delete,apk:install,apk:read +USER=apk:loaded,apk:available,apk:details +EXPERT=apk:expert,apk:delete,apk:install,apk:upgrade,apk:updateall,apk:upgradeall +ADMIN=apk:loaded,apk:available,apk:details,apk:expert,apk:delete,apk:install,apk:upgrade,apk:updateall,apk:upgradeall |