From: Michael Schroeder Date: Tue, 25 Aug 2015 15:21:17 +0000 (+0200) Subject: Update tclsolv, still work in progress X-Git-Tag: 0.6.12~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e8a17f4ace013f179f9b3c37da8d1c9070e0c07;p=thirdparty%2Flibsolv.git Update tclsolv, still work in progress * use arrays instead of dics for the repos, so we can use the $foo(bar) syntax which makes the code a bit more readable * implement susetags reading and cache writing --- diff --git a/examples/tclsolv b/examples/tclsolv index 21ed816b..4c6b4a5b 100755 --- a/examples/tclsolv +++ b/examples/tclsolv @@ -13,27 +13,29 @@ proc fileno {file} { error "file not open" } -proc repo_calc_cookie_file {selfname filename} { - upvar $selfname self +### generic repo handling (cache reading/writing) + +proc repo_calc_cookie_file {selfName filename} { + upvar $selfName self set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256] - $chksum add 1.1 + $chksum add "1.1" $chksum add_stat $filename return [$chksum raw] } -proc repo_calc_cookie_fp {selfname fp} { - upvar $selfname self +proc repo_calc_cookie_fp {selfName fp} { + upvar $selfName self set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256] $chksum add 1.1 $chksum add_fp $fp return [$chksum raw] } -proc repo_calc_cookie_ext {selfname f cookie} { - upvar $selfname self +proc repo_calc_cookie_ext {selfName f cookie} { + upvar $selfName self set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256] $chksum add 1.1 - $chksum add cookie + $chksum add $cookie $chksum add_fstat [$f fileno] set extcookie [$chksum raw] if {[string index $extcookie 0] eq "\000"} { @@ -42,9 +44,9 @@ proc repo_calc_cookie_ext {selfname f cookie} { return $extcookie } -proc repo_cachepath {selfname {ext "-"}} { - upvar $selfname self - regsub {^\.} [dict get $self name] _ path +proc repo_cachepath {selfName {ext "-"}} { + upvar $selfName self + regsub {^\.} $self(name) _ path if {$ext ne "-"} { set path "${path}_$ext.solvx" } else { @@ -54,48 +56,51 @@ proc repo_cachepath {selfname {ext "-"}} { return "/var/cache/solv/$path" } -proc repo_generic_load {selfname pool} { - upvar $selfname self - set handle [ $pool add_repo [ dict get $self name ] ] - dict set self handle $handle - $handle configure -appdata $self -priority [expr 99 - [dict get $self priority]] - set dorefresh [dict get $self autorefresh] - set metadata_expire [dict get $self metadata_expire] +proc repo_generic_load {selfName pool} { + upvar $selfName self + set handle [ $pool add_repo $self(name) ] + set self(handle) $handle + $handle configure -priority [expr 99 - $self(priority)] + upvar self "::repo_appdata_$handle" + set dorefresh $self(autorefresh) + set metadata_expire $self(metadata_expire) catch { if {$metadata_expire == -1 || [clock seconds] - [file mtime [repo_cachepath self]] < $metadata_expire} { set dorefresh 0 } } - dict set self cookie {} + set self(cookie) {} if { !$dorefresh && [repo_usecachedrepo self] } { - puts "repo [dict get $self name]: cached" + puts "repo $self(name): cached" return 1 } return 0 } -proc repo_free_handle {selfname} { - upvar $selfname self - set handle [ dict get $self handle ] - dict remove $self handle +proc repo_free_handle {selfName} { + upvar $selfName self + set handle $self(handle) + set ::repo_appdata_gone 1 + upvar ::repo_appdata_gone "::repo_appdata_$handle" + unset "::repo_appdata_$handle" + unset self(handle) $handle free 1 } -proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} { - upvar $selfname self - return 0 +proc repo_usecachedrepo {selfName {ext "-"} {mark 0}} { + upvar $selfName self set repopath [repo_cachepath self] set code [catch { set f [open $repopath "rb"] seek $f -32 end set fcookie [read $f 32] - set cookie [dict get $self [expr { $ext eq "-" ? {cookie} : {extcookie}}]] + set cookie [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}] if {$cookie ne {} && $cookie ne $fcookie} { close $f return 0 } set fextcookie {} - if {$ext eq "-" && [dict get $self type] ne "system"} { + if {$ext eq "-" && $self(type) ne "system"} { seek $f -64 end set fextcookie [read $f 32] } @@ -109,14 +114,14 @@ proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} { set flags [expr $flags | $solv::Repo_REPO_LOCALPOOL] } } - if {! [[dict get $self handle] add_solv $ff $flags]} { + if {! [$self(handle) add_solv $ff $flags]} { $ff close return 0 } $ff close - if {[dict get $self type] ne "system" && $ext eq "-"} { - dict set self cookie $fcookie - dict set self extcookie $fextcookie + if {$self(type) ne "system" && $ext eq "-"} { + set self(cookie) $fcookie + set self(extcookie) $fextcookie } if {$mark} { catch { @@ -128,17 +133,37 @@ proc repo_usecachedrepo {selfname {ext "-"} {mark 0}} { return [expr {$code == 2 ? $res : 0}] } -proc repo_writecachedrepo {selfname {ext "-"}} { - upvar $selfname self - if [dict exists $self incomplete] { +proc repo_writecachedrepo {selfName {ext "-"} {info "NULL"}} { + upvar $selfName self + if [info exists self(incomplete)] { return } + file mkdir "/var/cache/solv" + ::fileutil::tempdir "/var/cache/solv" + set tempfilename [::fileutil::tempfile ".newsolv-"] + ::fileutil::tempdirReset + set f [solv::xfopen $tempfilename "w+"] + file attributes $tempfilename -permissions 0444 + if {$info eq {NULL}} { + $self(handle) write $f + } else { + $info write $f + } + $f flush + if {$self(type) ne "system" && $ext eq "-"} { + if {![info exists self(extcookie)]} { + set self(extcookie) [repo_calc_cookie_ext self $f $self(cookie)] + } + $f write $self(extcookie) + } + $f write [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}] + $f close + file rename -force -- $tempfilename [repo_cachepath self $ext] } -proc repo_download {selfname file uncompress chksum {markincomplete 0}} { - upvar $selfname self - set url [dict get $self baseurl] - regsub {/$} $url {} url +proc repo_download {selfName file uncompress chksum {markincomplete 0}} { + upvar $selfName self + regsub {/$} $self(baseurl) {} url set url "$url/$file" set tempfilename [::fileutil::tempfile] set f [open $tempfilename rb+] @@ -151,7 +176,7 @@ proc repo_download {selfname file uncompress chksum {markincomplete 0}} { puts "$file: download error" } close $f - return 0 + return {NULL} } seek $f 0 start if {$chksum ne "" && $chksum ne "NULL"} { @@ -159,39 +184,36 @@ proc repo_download {selfname file uncompress chksum {markincomplete 0}} { if {$fchksum eq "" || $fchksum eq "NULL"} { puts "$file: unknown checksum type" if {$markincomplete} { - dict set self incomplete 1 + set self(incomplete) 1 } close $f - return 0 + return {NULL} } $fchksum add_fd [fileno $f] if {[$fchksum hex] ne [$chksum hex]} { puts "$file: checksum mismatch" if {$markincomplete} { - dict set self incomplete 1 + set self(incomplete) 1 } close $f - return 0 + return {NULL} } } set ff [solv::xfopen_fd [expr {$uncompress ? $file : ""}] [fileno $f]] close $f - if {$ff eq "NULL"} { - return 0 - } return $ff } -### +### system -proc repo_system_load {selfname pool} { - upvar $selfname self - set handle [ $pool add_repo [ dict get $self name ] ] - dict set self handle $handle - $handle configure -appdata $self +proc repo_system_load {selfName pool} { + upvar $selfName self + set handle [ $pool add_repo $self(name) ] + set self(handle) $handle + upvar self "::repo_appdata_$handle" $pool configure -installed $handle puts -nonewline "rpm database: " - dict set self cookie [repo_calc_cookie_file self "/var/lib/rpm/Packages"] + set self(cookie) [repo_calc_cookie_file self "/var/lib/rpm/Packages"] if [repo_usecachedrepo self] { puts "cached" return 1 @@ -202,12 +224,11 @@ proc repo_system_load {selfname pool} { repo_writecachedrepo self } -### +### repomd -proc repo_repomd_find {selfname what} { - upvar $selfname self - set handle [dict get $self handle] - set di [$handle Dataiterator_meta $solv::REPOSITORY_REPOMD_TYPE $what $solv::Dataiterator_SEARCH_STRING] +proc repo_repomd_find {selfName what} { + upvar $selfName self + set di [$self(handle) Dataiterator_meta $solv::REPOSITORY_REPOMD_TYPE $what $solv::Dataiterator_SEARCH_STRING] $di prepend_keyname $solv::REPOSITORY_REPOMD solv::iter d $di { set dp [$d parentpos] @@ -222,42 +243,42 @@ proc repo_repomd_find {selfname what} { return {} } -proc repo_repomd_load {selfname pool} { - upvar $selfname self +proc repo_repomd_load {selfName pool} { + upvar $selfName self if [repo_generic_load self $pool] { return 1 } - puts -nonewline "rpmmd repo '[dict get $self name]': " + puts -nonewline "rpmmd repo '$self(name)': " set f [repo_download self {repodata/repomd.xml} 0 {}] - if {$f == 0} { + if {$f eq {NULL}} { puts "no repomd.xml file, skipped" repo_free_handle self return 0 } - dict set self cookie [repo_calc_cookie_fp self $f] + set self(cookie) [repo_calc_cookie_fp self $f] if [repo_usecachedrepo self] { puts "cached" return 1 } - set handle [dict get $self handle] - $handle add_repomdxml $f 0 + set handle $self(handle) + $handle add_repomdxml $f puts "fetching" set primary [repo_repomd_find self primary] - if {$primary ne ""} { + if {$primary ne {}} { set f [repo_download self [lindex $primary 0] 1 [lindex $primary 1] 1] - if {$f != 0} { - $handle add_rpmmd $f "NULL" 0 + if {$f ne {NULL}} { + $handle add_rpmmd $f {NULL} $f close } - if [dict exists $self incomplete] { + if [info exists self(incomplete)] { return 0 } } set updateinfo [repo_repomd_find self primary] - if {$updateinfo ne ""} { + if {$updateinfo ne {}} { set f [repo_download self [lindex $updateinfo 0] 1 [lindex $updateinfo 1] 1] - if {$f != 0} { - $handle add_updateinfoxml $f 0 + if {$f ne {NULL}} { + $handle add_updateinfoxml $f $f close } } @@ -265,48 +286,105 @@ proc repo_repomd_load {selfname pool} { return 1 } -### +### susetags -proc repo_susetags_load {selfname pool} { - upvar $selfname self +proc repo_susetags_find {selfName what} { + upvar $selfName self + set di [$self(handle) Dataiterator_meta $solv::SUSETAGS_FILE_NAME $what $solv::Dataiterator_SEARCH_STRING] + $di prepend_keyname $solv::SUSETAGS_FILE + solv::iter d $di { + set dp [$d parentpos] + set checksum [$dp lookup_checksum $solv::SUSETAGS_FILE_CHECKSUM] + return [list $what $checksum] + } + return {} +} + +proc repo_susetags_load {selfName pool} { + upvar $selfName self if [repo_generic_load self $pool] { return 1 } - puts -nonewline "susetags repo '[dict get $self name]': " - puts "skipped" - return 0 + puts -nonewline "susetags repo '$self(name)': " + set f [repo_download self {content} 0 {}] + if {$f eq {NULL}} { + puts "no content file, skipped" + repo_free_handle self + return 0 + } + set self(cookie) [repo_calc_cookie_fp self $f] + if [repo_usecachedrepo self] { + puts "cached" + return 1 + } + set handle $self(handle) + $handle add_content $f + puts "fetching" + set defvendorid [[$handle cget -meta] lookup_id $solv::SUSETAGS_DEFAULTVENDOR] + set descrdir [[$handle cget -meta] lookup_str $solv::SUSETAGS_DESCRDIR] + if {$descrdir eq {NULL}} { + set descrdir "suse/setup/descr" + } + set packages [repo_susetags_find self "packages.gz"] + if {$packages eq {}} { + set packages [repo_susetags_find self "packages"] + } + if {$packages ne {}} { + set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1] + if {$f ne {NULL}} { + $handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_SUSETAGS_RECORD_SHARES] + $f close + set packages [repo_susetags_find self "packages.en.gz"] + if {$packages eq {}} { + set packages [repo_susetags_find self "packages.en"] + } + if {$packages ne {}} { + set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1] + if {$f ne {NULL}} { + $handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_REPO_REUSE_REPODATA | $solv::Repo_REPO_EXTEND_SOLVABLES ] + $f close + } + } + $handle internalize + } + } + repo_writecachedrepo self + return 1 } -### +### unknown -proc repo_unknown_load {selfname pool} { - upvar $selfname self - puts "unsupported repo '[dict get $self name]': skipped" +proc repo_unknown_load {selfName pool} { + upvar $selfName self + puts "unsupported repo '$self(name)': skipped" return 0 } -### +### poor man's OO -proc repo_load {selfname pool} { - upvar $selfname self - "repo_[dict get $self type]_load" self $pool +proc repo_load {selfName pool} { + upvar $selfName self + "repo_$self(type)_load" self $pool } +### - -set repos {} +set repoNames {} foreach reponame [lsort [glob -nocomplain -directory $reposdir *.repo]] { set ini [::ini::open $reponame r] foreach alias [::ini::sections $ini] { - set repoattr [dict create enabled 0 priority 99 autorefresh 1 type rpm-md metadata_expire 900] - set repoattr [dict replace $repoattr {*}[::ini::get $ini $alias]] - dict set repoattr name $alias - switch -exact -- [dict get $repoattr type] { - rpm-md { dict set repoattr type repomd } - yast2 { dict set repoattr type susetags } - default { dict set repoattr type unknown } + set num [llength $repoNames] + array set "repos$num" {} + upvar 0 "repos$num" repoattr + array set repoattr {enabled 0 priority 99 autorefresh 1 type rpm-md metadata_expire 900} + array set repoattr [::ini::get $ini $alias] + set repoattr(name) $alias + switch -exact -- $repoattr(type) { + rpm-md { set repoattr(type) repomd } + yast2 { set repoattr(type) susetags } + default { set repoattr(type) unknown } } - lappend repos $repoattr + lappend repoNames "repos$num" } ::ini::close $ini } @@ -314,11 +392,12 @@ foreach reponame [lsort [glob -nocomplain -directory $reposdir *.repo]] { set pool [solv::new_Pool] $pool setarch -set sysrepo [dict create name {@System} type system] +array set sysrepo [list name {@System} type system] repo_load sysrepo $pool -foreach repo $repos { - if [dict get $repo enabled] { +foreach repoName $repoNames { + upvar 0 $repoName repo + if {$repo(enabled)} { repo_load repo $pool } }