2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 04:36:36 +00:00

98_update.pm: support multiple repositories (Forum #45121)

git-svn-id: https://svn.fhem.de/fhem/trunk@10234 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-12-23 11:11:18 +00:00
parent 9dcf65e438
commit 6fca9d4cf4
2 changed files with 160 additions and 34 deletions

View File

@ -1,12 +1,13 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
- change: 71_YAMAHA_NP: More secure FM frequency input
- feature: 98_update.pm: support multiple repositories (Forum #45121)
- change: 71_YAMAHA_NP: More secure FM frequency input
- feature: FHEMWEB/Event Monitor: optional FHEM Log monitor.
- feature: 50_Telegrambot: multiple contacts for send etc/removed depreacted
messageTo,sendImageTo,sendPhotoTo/allowunknowncontacts
- bugfix: 70_PushNotifier: remove messages fron FHEM-logfile
- bugfix: 70_PushNotifier: remove messages fron FHEM-logfile
- feature: 49_SSCam: function "snap" for taking snapshots added,
- bugfix: 49_SSCam: fixed a bug that functions may impact each other
- bugfix: 49_SSCam: fixed a bug that functions may impact each other
- feature: 31_MilightDevice: Add restoreAtStart attribute so group devices
(slot 'A') do not restore state by default at startup
- bugfix: 30_MilightBridge/31_MilightDevice: Fix startup restore. Fix crash

View File

@ -15,6 +15,8 @@ sub upd_mkDir($$$);
sub upd_rmTree($);
sub upd_writeFile($$$$);
sub upd_mv($$);
sub upd_metainit($);
sub upd_metacmd($@);
my $updateInBackground;
my $updRet;
@ -41,9 +43,20 @@ CommandUpdate($$)
{
my ($cl,$param) = @_;
my @args = split(/ +/,$param);
my $err = upd_metainit(0);
return $err if($err);
if($args[0] &&
($args[0] eq "list" ||
$args[0] eq "add" ||
$args[0] eq "delete" ||
$args[0] eq "reset")) {
return upd_metacmd($cl, @args);
}
my $arg = (defined($args[0]) ? $args[0] : "all");
my $src = (defined($args[1]) ? $args[1] :
"http://fhem.de/fhemupdate/controls_fhem.txt");
my $src = (defined($args[1]) ? $args[1] : "");
my $ret = eval { "Hello" =~ m/$arg/ };
return "first argument must be a valid regexp, all, force or check"
@ -59,7 +72,7 @@ CommandUpdate($$)
return "Executing the update the background.";
} else {
doUpdate($src, $arg);
doUpdateLoop($src, $arg);
HttpUtils_Close(\%upd_connecthash);
my $ret = $updRet; $updRet = "";
return $ret;
@ -67,6 +80,71 @@ CommandUpdate($$)
}
}
sub
upd_metainit($)
{
my $force = shift;
my $mpath = $attr{global}{modpath}."/FHEM/controls.txt";
if($force || ! -f $mpath || -s $mpath == 0) {
if(!open(FH, ">$mpath")) {
my $msg = "Can't open $mpath: $!";
Log 1, $msg;
return $msg;
}
print FH "http://fhem.de/fhemupdate/controls_fhem.txt\n";
close(FH);
}
return undef;
}
sub
upd_metacmd($@)
{
my ($cl, @args) = @_;
my $mpath = $attr{global}{modpath}."/FHEM/controls.txt";
if($args[0] eq "list") {
open(FH, $mpath) || return "Can't open $mpath: $!";
my $ret = join("", <FH>);
close(FH);
return $ret;
}
if($args[0] eq "add") {
return "Usage: update add http://.../controls_.*.txt"
if(int(@args) != 2 || $args[1] !~ m,^http.*/(controls_.*.txt)$,);
my $fname = $1;
open(FH, $mpath) || return "Can't open $mpath: $!";
my (%fulls, %parts);
map { chomp($_); $fulls{$_}=1; my $x=$_; $x =~ s,^.*/,,; $parts{$x}=$_; } <FH>;
close(FH);
return "$args[1] is already in the list" if($fulls{$args[1]});
return "$fname is already present in $parts{$fname}" if($parts{$fname});
open(FH, ">>$mpath") || return "Can't write $mpath: $!";
print FH $args[1],"\n";
close(FH);
return undef;
}
if($args[0] eq "delete") {
return "Usage: update delete http://.../controls_.*.txt"
if(int(@args) != 2 || $args[1] !~ m,^http.*/(controls_.*.txt)$,);
open(FH, $mpath) || return "Can't open $mpath: $!";
my @list = grep { $_ ne $args[1]."\n"; } <FH>;
close(FH);
open(FH, ">$mpath") || return "Can't write $mpath: $!";
print FH join("", @list);
close(FH);
return undef;
}
if($args[0] eq "reset") {
return upd_metainit(1);
}
}
sub
uLog($$)
{
@ -102,15 +180,44 @@ doUpdateInBackground($)
no warnings 'redefine'; # The main process is not affected
*Log = \&update_Log2Event;
sleep(2); # Give time for ActivateInform / FHEMWEB / JavaScript
doUpdate($h->{src}, $h->{arg});
doUpdateLoop($h->{src}, $h->{arg});
HttpUtils_Close(\%upd_connecthash);
}
sub
doUpdate($$)
doUpdateLoop($$)
{
my ($src, $arg) = @_;
doUpdate(1,1, $src, $arg) if($src =~ m/^http.*/);
my $mpath = $attr{global}{modpath}."/FHEM/controls.txt";
if(!open(LFH, "$mpath")) {
my $msg = "Can't open $mpath: $!";
uLog 1, $msg;
return $msg;
}
my ($max,$curr) = (0,0);
while(my $srcLine = <LFH>) {
chomp($srcLine);
continue if($src && $srcLine !~ m/controls_{$src}/);
$max++;
}
uLog 1, "No source file named controls_$src found" if($src && !$max);
seek(LFH,0,0);
while(my $srcLine = <LFH>) {
chomp($srcLine);
continue if($src && $srcLine !~ m/controls_{$src}/);
doUpdate(++$curr, $max, $srcLine, $arg);
}
close(LFH);
}
sub
doUpdate($$$$)
{
my ($curr, $max, $src, $arg) = @_;
my ($basePath, $ctrlFileName);
if($src !~ m,^(.*)/([^/]*)$,) {
uLog 1, "Cannot parse $src, probably not a valid http control file";
@ -118,8 +225,10 @@ doUpdate($$)
}
$basePath = $1;
$ctrlFileName = $2;
$ctrlFileName =~ m/controls_(.*).txt/;
my $srcName = $1;
if(AttrVal("global", "backup_before_update", 0) && $arg ne "check") {
if(AttrVal("global", "backup_before_update", 0) && $arg ne "check" && $curr==1) {
my $cmdret = AnalyzeCommand(undef, "backup");
if ($cmdret !~ m/backup done.*/) {
uLog 1, "Something went wrong during backup: $cmdret";
@ -128,10 +237,15 @@ doUpdate($$)
}
}
if($max != 1) {
uLog 1, "";
uLog 1, $srcName;
}
my $remCtrlFile = upd_getUrl($src);
return if(!$remCtrlFile);
my @remList = split(/\R/, $remCtrlFile);
uLog 4, "Got remote controlfile with ".int(@remList)." entries.";
uLog 4, "Got remote $ctrlFileName with ".int(@remList)." entries.";
###########################
# read in & digest the local control file
@ -143,7 +257,7 @@ doUpdate($$)
open(FD, "$root/FHEM/$ctrlFileName")) {
@locList = map { $_ =~ s/[\r\n]//; $_ } <FD>;
close(FD);
uLog 4, "Got local controlfile with ".int(@locList)." entries.";
uLog 4, "Got local $ctrlFileName with ".int(@locList)." entries.";
}
my %lh;
foreach my $l (@locList) {
@ -234,8 +348,7 @@ doUpdate($$)
return if(!$remFile); # Error already reported
if(length($remFile) ne $r[2]) {
uLog 1,
"Got ".length($remFile)." bytes for $fName, not $r[2] as expected,";
uLog 1, "Got ".length($remFile)." bytes for $fName, expected $r[2]";
if($attr{global}{verbose} == 5) {
upd_writeFile($root, $restoreDir, "$fName.corrupt", $remFile);
uLog 1, "saving it to $fName.corrupt .";
@ -268,7 +381,7 @@ doUpdate($$)
return "" if(!$nChanged);
if($canJoin && $needJoin) {
if($canJoin && $needJoin && $curr == $max) {
chdir($root);
uLog(1, "Calling $^X $cj, this may take a while");
my $ret = `$^X $cj`;
@ -278,17 +391,19 @@ doUpdate($$)
}
uLog(1, "");
uLog 1,
'update finished, "shutdown restart" is needed to activate the changes.';
my $ss = AttrVal("global","sendStatistics",undef);
if(!defined($ss)) {
uLog(1, "");
uLog(1, "Please consider using the global attribute sendStatistics");
} elsif(defined($ss) && lc($ss) eq "onupdate") {
uLog(1, "");
my $ret = AnalyzeCommandChain(undef, "fheminfo send");
$ret =~ s/.*server response:/server response:/ms;
uLog(1, "fheminfo $ret");
if($curr == $max) {
uLog 1,
'update finished, "shutdown restart" is needed to activate the changes.';
my $ss = AttrVal("global","sendStatistics",undef);
if(!defined($ss)) {
uLog(1, "");
uLog(1, "Please consider using the global attribute sendStatistics");
} elsif(defined($ss) && lc($ss) eq "onupdate") {
uLog(1, "");
my $ret = AnalyzeCommandChain(undef, "fheminfo send");
$ret =~ s/.*server response:/server response:/ms;
uLog(1, "fheminfo $ret");
}
}
}
@ -498,13 +613,17 @@ upd_initRestoreDirs($)
<ul>
<code>update [&lt;fileName&gt;|all|check|force]
[http://.../controlfile]</code>
<br>or<br>
<code>update [add source|delete source|list|reset]</code>
<br>
<br>
Update the FHEM installation. Technically this means update will download
http://fhem.de/fhemupdate/controls_fhem.txt first, compare it to the local
version in FHEM/controls_fhem.txt, and will download each file where the
attributes (timestamp and filelength) are different.
the controlfile(s) first, compare it to the local version of the file in the
moddir/FHEM directory, and download each file where the attributes (timestamp
and filelength) are different.
<br>
With the commands add/delete/list/reset you can manage the list of
controlfiles, e.g. for thirdparty packages.
Notes:
<ul>
<li>The contrib directory will not be updated.</li>
@ -591,13 +710,19 @@ upd_initRestoreDirs($)
<ul>
<code>update [&lt;fileName&gt;|all|check|force]
[http://.../controlfile]</code>
<br>oder<br>
<code>update [add source|delete source|list|reset]</code>
<br>
<br>
Erneuert die FHEM Installation. D.h. es wird zuerst die Datei
http://fhem.de/fhemupdate/controls_fhem.txt heruntergeladen, mit der lokalen
Version dieser Datei (FHEM/controls_fhem.txt) verglichen. Danach werden
alle Programmdateien heruntergeladen, deren Gr&ouml;&szlig;e oder Zeitstempel
sich unterscheidet.
Erneuert die FHEM Installation. D.h. es wird (werden) zuerst die
Kontroll-Datei(en) heruntergeladen, und mit der lokalen Version dieser Datei
in moddir/FHEM verglichen. Danach werden alle in der Kontroll-Datei
spezifizierten Dateien heruntergeladen, deren Gr&ouml;&szlig;e oder
Zeitstempel sich unterscheidet.
<br>
Mit den Befehlen add/delete/list/reset kann man die Liste der Kontrolldateien
pflegen.
<br>
<br>
Zu beachten:
<ul>