refactor(nix-monitor): rewrite most of the service code to make it a little bit more readable
This commit is contained in:
@@ -33,8 +33,9 @@ function displayWidget(glyph: string, text: string, color: string?)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Hooks
|
||||||
function update()
|
function update()
|
||||||
if getState("isRunning") then
|
if getState("isRemoteCheckRunning") then
|
||||||
displayWidget(barCfg("checking_glyph"), tr("bar.checking"), barCfg("checking_color"))
|
displayWidget(barCfg("checking_glyph"), tr("bar.checking"), barCfg("checking_color"))
|
||||||
else
|
else
|
||||||
if getState("isUpdateAvailable") then
|
if getState("isUpdateAvailable") then
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
noctalia.setUpdateInterval(1000)
|
noctalia.setUpdateInterval(5000)
|
||||||
|
|
||||||
|
-- Helper functions
|
||||||
function tr(key)
|
function tr(key)
|
||||||
return noctalia.tr(key)
|
return noctalia.tr(key)
|
||||||
end
|
end
|
||||||
@@ -20,32 +21,34 @@ function watchState(key, cb)
|
|||||||
noctalia.state.watch(key, cb)
|
noctalia.state.watch(key, cb)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Vars
|
||||||
local branch = cfg("branch")
|
local branch = cfg("branch")
|
||||||
local updateCheckInterval = cfg("check_interval")
|
local updateCheckInterval = cfg("check_interval")
|
||||||
local checkDurationThreshold = cfg("check_duration_threshold")
|
local checkDurationThreshold = cfg("check_duration_threshold")
|
||||||
local systemStatsCheckInterval = cfg("system_stats_check_interval")
|
local systemStatsCheckInterval = cfg("system_stats_check_interval")
|
||||||
local isInit = true
|
|
||||||
local stateDir = "/tmp/nix-monitor"
|
local stateDir = "/tmp/nix-monitor"
|
||||||
local localHashFile = stateDir .. "/localHash"
|
|
||||||
local remoteHashFile = stateDir .. "/remoteHash"
|
local remoteHashFile = stateDir .. "/remoteHash"
|
||||||
local storeSizeFile = stateDir .. "/storeSize"
|
local storeSizeFile = stateDir .. "/storeSize"
|
||||||
local closureSizeFile = stateDir .. "/closureSize"
|
local closureSizeFile = stateDir .. "/closureSize"
|
||||||
|
local showUpdateNotification = true
|
||||||
|
|
||||||
local localHashCmd = "nixos-version --hash 2> /dev/null | cut -c -7 > " .. localHashFile .. " &"
|
local localHashCmd = "nixos-version --hash 2> /dev/null | cut -c -7"
|
||||||
local remoteHashCmd = "git ls-remote https://github.com/NixOS/nixpkgs " .. branch .. " 2>/dev/null | cut -c 1-7 > " .. remoteHashFile .. " &"
|
local remoteHashCmd = "git ls-remote https://github.com/NixOS/nixpkgs " .. branch .. " 2>/dev/null | cut -c 1-7"
|
||||||
local nixosGenerationsCmd = "nixos-rebuild list-generations | tail -n +2 | wc -l"
|
local nixosGenerationsCmd = "nixos-rebuild list-generations | tail -n +2 | wc -l"
|
||||||
local nixosCurrentGenCmd = "nixos-rebuild list-generations | grep True | awk '{print $1}'"
|
local nixosCurrentGenCmd = "nixos-rebuild list-generations | grep True | awk '{print $1}'"
|
||||||
local hmGenerationsCmd = "home-manager generations | wc -l"
|
local hmGenerationsCmd = "home-manager generations | wc -l"
|
||||||
local hmCurrentGenCmd = "home-manager generations | grep '(current)' | awk '{print $5}'"
|
local hmCurrentGenCmd = "home-manager generations | grep '(current)' | awk '{print $5}'"
|
||||||
local storeSizeCmd = `du -s --block-size=1GiB /nix/store | awk '\{print $1 " GiB"\}' > {storeSizeFile} &`
|
local storeSizeCmd = "du -s --block-size=1GiB /nix/store | awk '\{print $1 \" GiB\"\}'"
|
||||||
local closureSizeCmd = `nix path-info --closure-size --human-readable /run/current-system | awk '\{print $2, $3\}' > {closureSizeFile} &`
|
local closureSizeCmd = "nix path-info --closure-size --human-readable /run/current-system | awk '\{print $2, $3\}'"
|
||||||
|
|
||||||
setState("lastRunTime", os.time())
|
-- State inits
|
||||||
setState("lastCheckTime", os.time())
|
setState("lastLocalCheckTime", os.time())
|
||||||
setState("lastCheckTimeStr", "n/a")
|
setState("lastRemoteCheckRunTime", os.time())
|
||||||
|
setState("lastRemoteCheckTime", os.time())
|
||||||
|
setState("lastRemoteCheckTimeStr", "n/a")
|
||||||
setState("localHash", "n/a")
|
setState("localHash", "n/a")
|
||||||
setState("remoteHash", "n/a")
|
setState("remoteHash", "n/a")
|
||||||
setState("isRunning", false)
|
setState("isRemoteCheckRunning", false)
|
||||||
setState("isUpdateAvailable", false)
|
setState("isUpdateAvailable", false)
|
||||||
setState("lastGenerationsCheckTime", 0)
|
setState("lastGenerationsCheckTime", 0)
|
||||||
setState("lastSystemStatsCheckTime", 0)
|
setState("lastSystemStatsCheckTime", 0)
|
||||||
@@ -58,120 +61,61 @@ setState("storeSize", "•••")
|
|||||||
setState("closureSize", "•••")
|
setState("closureSize", "•••")
|
||||||
|
|
||||||
noctalia.mkdirAll(stateDir)
|
noctalia.mkdirAll(stateDir)
|
||||||
noctalia.writeFile(localHashFile, "")
|
|
||||||
noctalia.writeFile(remoteHashFile, "")
|
noctalia.writeFile(remoteHashFile, "")
|
||||||
|
|
||||||
function update()
|
-- Local check
|
||||||
if isInit or (os.time() - getState("lastCheckTime")) >= 60 * updateCheckInterval then
|
function checkLocalHash()
|
||||||
cancelCheck()
|
noctalia.runAsync(localHashCmd, function(res)
|
||||||
checkUpdate()
|
if res.exitCode == 0 then
|
||||||
end
|
setState("localHash", res.stdout)
|
||||||
|
|
||||||
if getState("isRunning") then
|
|
||||||
if isCheckUpdateSuccessfully() then
|
|
||||||
onHashCheckCompleted()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if getState("isSystemStatsCheckRunning") then
|
|
||||||
checkSystemStatsFile()
|
|
||||||
end
|
|
||||||
|
|
||||||
if getState("isRunning") and (os.time() - getState("lastRunTime")) >= 60 * checkDurationThreshold then
|
|
||||||
cancelCheck()
|
|
||||||
end
|
|
||||||
|
|
||||||
if (os.time() - getState("lastGenerationsCheckTime")) >= 20 then
|
|
||||||
checkGenerations()
|
|
||||||
end
|
|
||||||
|
|
||||||
if (os.time() - getState("lastSystemStatsCheckTime")) >= 60 * systemStatsCheckInterval then
|
|
||||||
checkSystemStats()
|
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function checkUpdate()
|
-- Remote check
|
||||||
if getState("isRunning") then
|
--
|
||||||
|
-- Currently it is writing to a file because when I use the runAsync with
|
||||||
|
-- the callback, it is timed out
|
||||||
|
function checkRemoteHash(delay: number?)
|
||||||
|
local delay = delay or 0
|
||||||
|
|
||||||
|
if getState("isRemoteCheckRunning") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local remoteCmd = remoteHashCmd
|
setState("isRemoteCheckRunning", true)
|
||||||
|
setState("lastRemoteCheckRunTime", os.time())
|
||||||
|
|
||||||
if isInit then
|
|
||||||
remoteCmd = "sleep 10 && " .. remoteCmd
|
|
||||||
isInit = false
|
|
||||||
end
|
|
||||||
|
|
||||||
setState("lastRunTime", os.time())
|
|
||||||
|
|
||||||
if cfg("show_checking_notification") then
|
|
||||||
noctalia.notify(tr("notification.checking_update"))
|
|
||||||
end
|
|
||||||
|
|
||||||
setState("isRunning", true)
|
|
||||||
|
|
||||||
noctalia.writeFile(localHashFile, "")
|
|
||||||
noctalia.writeFile(remoteHashFile, "")
|
noctalia.writeFile(remoteHashFile, "")
|
||||||
|
noctalia.runAsync(`sleep {delay} && {remoteHashCmd} > {remoteHashFile} &`)
|
||||||
noctalia.runAsync(localHashCmd)
|
|
||||||
noctalia.runAsync(remoteCmd)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function isCheckUpdateSuccessfully()
|
-- Check if the remoteHash check command is finished by reading the file
|
||||||
local localHash = noctalia.string.trim(noctalia.readFile(localHashFile))
|
function checkRemoteStatus()
|
||||||
local remoteHash = noctalia.string.trim(noctalia.readFile(remoteHashFile))
|
local remoteHash = noctalia.string.trim(noctalia.readFile(remoteHashFile))
|
||||||
|
|
||||||
if typeof(localHash) == "string" and localHash ~= "" then
|
if type(remoteHash) == "string" and remoteHash ~= "" then
|
||||||
setState("localHash", localHash)
|
setState("isRemoteCheckRunning", false)
|
||||||
end
|
|
||||||
|
|
||||||
if typeof(remoteHash) == "string" and remoteHash ~= "" then
|
|
||||||
setState("remoteHash", remoteHash)
|
setState("remoteHash", remoteHash)
|
||||||
|
onRemoteHashCheckCompleted()
|
||||||
end
|
end
|
||||||
|
|
||||||
local success = typeof(localHash) == "string" and localHash ~= "" and
|
|
||||||
typeof(remoteHash) == "string" and remoteHash ~= ""
|
|
||||||
|
|
||||||
if success then
|
|
||||||
onHashCheckCompleted()
|
|
||||||
end
|
|
||||||
|
|
||||||
return success
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function onHashCheckCompleted()
|
function onRemoteHashCheckCompleted()
|
||||||
if getState("localHash") ~= getState("remoteHash") then
|
|
||||||
setState("isUpdateAvailable", true)
|
|
||||||
if cfg("show_update_notification") then
|
|
||||||
noctalia.notify(tr("notification.update_is_available"))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if cfg("show_checking_notification") then
|
if cfg("show_checking_notification") then
|
||||||
noctalia.notify(tr("notification.update_check_completed"))
|
noctalia.notify(tr("notification.update_check_completed"))
|
||||||
end
|
end
|
||||||
|
|
||||||
setState("lastCheckTime", os.time())
|
setState("lastRemoteCheckTime", os.time())
|
||||||
noctalia.runAsync("date '+%Y-%m-%d %H:%M'", function(date) setState("lastCheckTimeStr", date.stdout) end)
|
noctalia.runAsync("date '+%Y-%m-%d %H:%M'", function(date) setState("lastRemoteCheckTimeStr", date.stdout) end)
|
||||||
|
|
||||||
setState("isRunning", false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function cancelCheck()
|
function cancelRemoteCheck()
|
||||||
setState("isRunning", false)
|
setState("isRemoteCheckRunning", false)
|
||||||
noctalia.runAsync(`kill $(ps -ef | grep "git ls-remote https://github.com/NixOS/nixpkgs" | grep -v grep | awk '\{print $2\}')`)
|
noctalia.runAsync(`kill $(ps -ef | grep "git ls-remote https://github.com/NixOS/nixpkgs" | grep -v grep | awk '\{print $2\}')`)
|
||||||
end
|
end
|
||||||
|
|
||||||
watchState("command", function(command)
|
-- Generation check
|
||||||
if command == "check" then
|
|
||||||
checkUpdate()
|
|
||||||
end
|
|
||||||
|
|
||||||
if command == "cancel" then
|
|
||||||
cancelCheck()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
function checkGenerations()
|
function checkGenerations()
|
||||||
setState("lastGenerationsCheckTime", os.time())
|
setState("lastGenerationsCheckTime", os.time())
|
||||||
|
|
||||||
@@ -194,6 +138,7 @@ function checkGenerations()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- System stats check
|
||||||
function checkSystemStats()
|
function checkSystemStats()
|
||||||
if getState("isSystemStatsCheckRunning") then
|
if getState("isSystemStatsCheckRunning") then
|
||||||
return
|
return
|
||||||
@@ -202,8 +147,8 @@ function checkSystemStats()
|
|||||||
setState("isSystemStatsCheckRunning", true)
|
setState("isSystemStatsCheckRunning", true)
|
||||||
setState("lastSystemStatsCheckTime", os.time())
|
setState("lastSystemStatsCheckTime", os.time())
|
||||||
|
|
||||||
noctalia.runAsync(storeSizeCmd)
|
noctalia.runAsync(`{storeSizeCmd} > {storeSizeFile} &`)
|
||||||
noctalia.runAsync(closureSizeCmd)
|
noctalia.runAsync(`{closureSizeCmd} > {closureSizeFile} &`)
|
||||||
end
|
end
|
||||||
|
|
||||||
function checkSystemStatsFile()
|
function checkSystemStatsFile()
|
||||||
@@ -226,6 +171,79 @@ function checkSystemStatsFile()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Init
|
||||||
|
checkLocalHash()
|
||||||
|
checkRemoteHash(10)
|
||||||
|
|
||||||
|
-- Command watcher
|
||||||
|
watchState("command", function(command)
|
||||||
|
if command == "check" then
|
||||||
|
checkLocalHash()
|
||||||
|
cancelRemoteCheck()
|
||||||
|
checkRemoteHash()
|
||||||
|
checkGenerations()
|
||||||
|
checkSystemStats()
|
||||||
|
end
|
||||||
|
|
||||||
|
if command == "cancel" then
|
||||||
|
cancelRemoteCheck()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Hooks
|
||||||
|
--
|
||||||
|
|
||||||
|
function update()
|
||||||
|
-- Check local hash every 10 seconds
|
||||||
|
if (os.time() - getState("lastLocalCheckTime") >= 10) then
|
||||||
|
checkLocalHash()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remote check
|
||||||
|
if (os.time() - getState("lastRemoteCheckTime")) >= 60 * updateCheckInterval then
|
||||||
|
checkRemoteHash()
|
||||||
|
end
|
||||||
|
|
||||||
|
if getState("isRemoteCheckRunning") then
|
||||||
|
checkRemoteStatus()
|
||||||
|
|
||||||
|
-- Remote check timeout
|
||||||
|
if (os.time() - getState("lastRemoteCheckRunTime")) >= 60 * checkDurationThreshold then
|
||||||
|
cancelRemoteCheck()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if getState("localHash") ~= getState("remoteHash") and
|
||||||
|
getState("localHash") ~= "n/a" and getState("remoteHash") ~= "n/a"
|
||||||
|
then
|
||||||
|
setState("isUpdateAvailable", true)
|
||||||
|
|
||||||
|
if cfg("show_update_notification") and showUpdateNotification then
|
||||||
|
noctalia.notify(tr("notification.update_is_available"))
|
||||||
|
showUpdateNotification = false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
setState("isUpdateAvailable", false)
|
||||||
|
showUpdateNotification = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Generations check
|
||||||
|
if (os.time() - getState("lastGenerationsCheckTime")) >= 20 then
|
||||||
|
checkGenerations()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- System stats check
|
||||||
|
if (os.time() - getState("lastSystemStatsCheckTime")) >= 60 * systemStatsCheckInterval then
|
||||||
|
checkSystemStats()
|
||||||
|
end
|
||||||
|
|
||||||
|
if getState("isSystemStatsCheckRunning") then
|
||||||
|
checkSystemStatsFile()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function onExit(signal)
|
function onExit(signal)
|
||||||
cancelCheck()
|
cancelRemoteCheck()
|
||||||
end
|
end
|
||||||
|
|||||||
+14
-5
@@ -1,3 +1,5 @@
|
|||||||
|
-- Helper functions
|
||||||
|
|
||||||
function tr(key)
|
function tr(key)
|
||||||
return noctalia.tr(key)
|
return noctalia.tr(key)
|
||||||
end
|
end
|
||||||
@@ -48,7 +50,7 @@ local function labelBox(subtext, text, glyph)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function statLabel(text, glyph: string?)
|
local function statLabel(text, glyph: string?)
|
||||||
local items = {}
|
local items = {}
|
||||||
if glyph ~= nil then
|
if glyph ~= nil then
|
||||||
table.insert(items, ui.glyph({
|
table.insert(items, ui.glyph({
|
||||||
@@ -72,7 +74,7 @@ end
|
|||||||
local function render()
|
local function render()
|
||||||
local firstBtn = btnCheck
|
local firstBtn = btnCheck
|
||||||
|
|
||||||
if getState("isRunning") then
|
if getState("isRemoteCheckRunning") then
|
||||||
firstBtn = ui.button({
|
firstBtn = ui.button({
|
||||||
text = tr("panel.cancel"),
|
text = tr("panel.cancel"),
|
||||||
glyph = "cancel",
|
glyph = "cancel",
|
||||||
@@ -100,7 +102,7 @@ local function render()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local lastCheckTimeStr = getState("lastCheckTimeStr")
|
local lastCheckTimeStr = getState("lastRemoteCheckTimeStr")
|
||||||
local generationItems = {
|
local generationItems = {
|
||||||
statLabel(`SYS: {getState("nixosGenerations")}`, "device-desktop"),
|
statLabel(`SYS: {getState("nixosGenerations")}`, "device-desktop"),
|
||||||
statLabel(`{tr("panel.current")}: {getState("nixosCurrentGen")}`, "device-desktop-check")
|
statLabel(`{tr("panel.current")}: {getState("nixosCurrentGen")}`, "device-desktop-check")
|
||||||
@@ -200,15 +202,22 @@ local function render()
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
watchState("isRunning", render)
|
-- State watcher
|
||||||
watchState("lastCheckTimeStr", render)
|
watchState("isRemoteCheckRunning", render)
|
||||||
|
watchState("lastRemoteCheckTimeStr", render)
|
||||||
watchState("localHash", render)
|
watchState("localHash", render)
|
||||||
watchState("remoteHash", render)
|
watchState("remoteHash", render)
|
||||||
|
|
||||||
|
-- Hooks
|
||||||
function onOpen(_ctx)
|
function onOpen(_ctx)
|
||||||
render()
|
render()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function update()
|
||||||
|
render()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Click handler
|
||||||
function onCheckClicked()
|
function onCheckClicked()
|
||||||
setState("command", "check")
|
setState("command", "check")
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user