forked from hummypkg/webif
243 lines
5.6 KiB
Plaintext
Executable File
243 lines
5.6 KiB
Plaintext
Executable File
#!/mod/bin/jimsh
|
|
|
|
source /mod/webif/lib/setup
|
|
require system.class settings.class ts.class rsv.class browse.class \
|
|
queue.class \
|
|
lock plugin safe_delete pretty_size
|
|
|
|
source /mod/webif/lib/auto/util.jim
|
|
|
|
set ::auto::settings [settings]
|
|
set ::auto::loglevel [$::auto::settings autolog]
|
|
|
|
set ::auto::force 0
|
|
|
|
while {[llength $argv]} {
|
|
switch -- [lindex $argv 0] {
|
|
-d {
|
|
incr ::auto::loglevel
|
|
set ::auto::logfd stdout
|
|
}
|
|
-f {
|
|
set ::auto::force 1
|
|
}
|
|
-logprefix {
|
|
set argv [lrange $argv 1 end]
|
|
if {[llength $argv]} {
|
|
set ::auto::logprefix [lindex $argv 0]
|
|
}
|
|
}
|
|
default {
|
|
# Pass to rest of script.
|
|
break
|
|
}
|
|
}
|
|
set argv [lrange $argv 1 end]
|
|
}
|
|
|
|
# Acquire lock
|
|
if {$::auto::logfd ne "unset"} {
|
|
puts $::auto::logfd "Acquiring lock..."
|
|
}
|
|
if {![acquire_lock webif_autodeq]} {
|
|
if {$::auto::loglevel > 1} {
|
|
system plog auto "Could not acquire lock."
|
|
}
|
|
puts "Could not acquire exclusive lock, terminating."
|
|
exit
|
|
}
|
|
|
|
::auto::loginit
|
|
|
|
######################################################################
|
|
# Determine if it's time to run
|
|
|
|
if {[system uptime] < 180} {
|
|
::auto::log "Aborting, system has just booted." 2
|
|
exit
|
|
}
|
|
|
|
::auto::dsc
|
|
::auto::oktorun
|
|
|
|
#########################################################################
|
|
# Initialisation
|
|
|
|
set scanstart [clock milliseconds]
|
|
::auto::log "Auto de-queue starting" 2
|
|
|
|
::auto::tmpdir "webif_autoq"
|
|
|
|
if {[system pkginst undelete]} {
|
|
set ::auto::dustbin "[system dustbin]"
|
|
} else {
|
|
set ::auto::dustbin ""
|
|
}
|
|
|
|
set ::auto::root [system mediaroot]
|
|
file stat "$::auto::root/" rootstat
|
|
set ::auto::rootdev $rootstat(dev)
|
|
|
|
#########################################################################
|
|
# Utility functions
|
|
|
|
######################################################################
|
|
# Plugin registration
|
|
|
|
set ::auto::plugins {}
|
|
|
|
proc ::auto::register {plugin {priority 500}} {
|
|
variable plugins
|
|
|
|
set fn "::${plugin}::dequeue"
|
|
set plugins($plugin) $priority
|
|
log "Registered $plugin with priority $priority" 2
|
|
}
|
|
|
|
######################################################################
|
|
# Load plugins
|
|
|
|
# Bundled
|
|
eval_plugins queue 1 "" /mod/webif/lib/auto/plugin
|
|
|
|
# Third party
|
|
|
|
eval_plugins queue 1
|
|
|
|
######################################################################
|
|
# Process the queue
|
|
|
|
queue startup [$::auto::settings autokeep]
|
|
|
|
proc ::auto::dumpq {qq} {
|
|
foreach q $qq {
|
|
set pri 0
|
|
if {[$q get action] in $::auto::plugins} {
|
|
set pri $::auto::plugins([$q get action])
|
|
}
|
|
log [format " C: %4d %5d %8s - %s" \
|
|
[$q get id] $pri [$q get action] [$q get file]] 2
|
|
}
|
|
}
|
|
|
|
proc ::auto::runplugin {plugin fn args} {
|
|
set rfn "::${plugin}::${fn}"
|
|
if {![exists -proc $rfn]} { return -1 }
|
|
if {[catch {set ret [uplevel 1 $rfn $args]} msg]} {
|
|
log "$rfn: $msg" 0
|
|
lassign [info stacktrace] p f l
|
|
log " $f:$l @ $p" 0
|
|
return -1
|
|
}
|
|
return $ret
|
|
}
|
|
|
|
proc ::auto::runplugins {fn args} {
|
|
foreach plugin [lsort -decreasing -command [lambda {a b} {
|
|
if {$a ni $::auto::plugins} { return 0 }
|
|
if {$b ni $::auto::plugins} { return 0 }
|
|
return $($::auto::plugins($a) - $::auto::plugins($b))
|
|
}] [dict keys $::auto::plugins]] {
|
|
set rfn "::${plugin}::${fn}"
|
|
if {![exists -proc $rfn]} continue
|
|
if {[catch {uplevel 1 $rfn {*}$args} msg]} {
|
|
log "$rfn: $msg" 0
|
|
lassign [info stacktrace] p f l
|
|
log " $f:$l @ $p" 0
|
|
}
|
|
}
|
|
}
|
|
|
|
# Helper function to sort a list of queue items by plugin priority
|
|
proc ::auto::pending {} {
|
|
return [lsort -decreasing -command [lambda {a b} {
|
|
set aa [$a get action]
|
|
set ba [$b get action]
|
|
if {$aa ni $::auto::plugins} { return 0 }
|
|
if {$ba ni $::auto::plugins} { return 0 }
|
|
set ap $::auto::plugins($aa)
|
|
set bp $::auto::plugins($ba)
|
|
if {$ap != $bp} { return $($ap - $bp) }
|
|
return $([$b get id] - [$a get id])
|
|
}] [queue pending]]
|
|
}
|
|
|
|
set ::auto::processed 0
|
|
for {set qq [::auto::pending]} {[llength $qq]} {set qq [::auto::pending]} {
|
|
::auto::dumpq $qq
|
|
|
|
incr ::auto::processed
|
|
|
|
# Try to run the first item in the queue.
|
|
set q [lindex $qq 0]
|
|
set plugin [$q get action]
|
|
set file [$q get file]
|
|
|
|
::auto::log "De-queuing [$q get id] - [$q get action] - $file" 0
|
|
|
|
if {[string match {file://*} $file]} {
|
|
set arg [string range $file 7 end]
|
|
if {![file exists $arg]} {
|
|
::auto::log "file does not exist." 0
|
|
$q update "FAILED" "File does not exist" 1
|
|
continue
|
|
}
|
|
} elseif {[string first :// $file] != -1} {
|
|
set arg $file
|
|
} else {
|
|
if {[catch {set arg [ts fetch $file]}] || $arg eq "0"} {
|
|
::auto::log "ts load failed." 0
|
|
$q update "FAILED" "Could not load .ts file" 1
|
|
continue
|
|
}
|
|
}
|
|
|
|
::auto::dsc
|
|
::auto::oktorun
|
|
|
|
$q update RUNNING "Started at [::auto::date]"
|
|
|
|
set ologprefix $::auto::logprefix
|
|
set ::auto::logprefix "$plugin:$::auto::logprefix"
|
|
|
|
set st [clock milliseconds]
|
|
lassign [::auto::runplugin $plugin dequeue $q $arg] code msg next
|
|
set ::auto::logprefix $ologprefix
|
|
set elapsed [::auto::elapsed $st]
|
|
|
|
if {[string index $next 0] eq "+"} { incr next [clock seconds] }
|
|
|
|
::auto::log " $code - $msg - $next" 0
|
|
switch -- $code {
|
|
"-1" {
|
|
::auto::log " Plugin failure" 0
|
|
$q update "FAILED" "Plugin failure" 1
|
|
}
|
|
"OK" {
|
|
$q update "COMPLETE" $msg 1 $elapsed
|
|
::auto::runplugins dequeued $plugin $q $arg
|
|
}
|
|
"DEFER" {
|
|
if {$next ne ""} { $q set start $next }
|
|
$q update "DEFER" $msg 1 $elapsed
|
|
}
|
|
"FAILED" { $q update "FAILED" $msg 1 $elapsed }
|
|
default {
|
|
$q update "FAILED" "Unknown response '$code'"
|
|
}
|
|
}
|
|
}
|
|
|
|
######################################################################
|
|
# Cleanup
|
|
|
|
release_lock webif_autodeq
|
|
|
|
if {$::auto::processed || $::auto::loglevel > 1} {
|
|
set q "s"
|
|
if {$::auto::processed == 1} { set q "" }
|
|
::auto::log "Auto de-queue processed $::auto::processed item$q in [\
|
|
::auto::elapsed $scanstart] seconds."
|
|
}
|
|
|