Commit 4a59047a authored by Mike Hibler's avatar Mike Hibler

Add -C (check) and -U (uncompress) options.

The -C option will verify that all images match their sigs before
delta/undelta-ing anything.

The -U option will expand all delta images to full images ensuring
that the name of this command is meaningless.
parent 211e9fb5
......@@ -35,42 +35,60 @@ use File::stat;
# left as full images.
#
# To do this, we use the new-style directory representation of an image.
# As an example:
# As an example, for an image with multiple versions:
#
# FBSD102-64-STD.ndz
# FBSD102-64-STD.ndz.sha1
# FBSD102-64-STD.ndz.sig
# FBSD102-64-STD.ndz:1
# FBSD102-64-STD.ndz:2
# FBSD102-64-STD.ndz:1.sha1
# FBSD102-64-STD.ndz:1.sig
# ...
# FBSD102-64-STD.ndz:11
# FBSD102-64-STD.ndz:12
# FBSD102-64-STD.ndz:12.sha1
# FBSD102-64-STD.ndz:12.sig
#
# becomes:
# We just move them all into a subdirectory, ala:
#
# FBSD102-64-STD/
# 0.ndz
# 1.ddz
# 2.ddz
# FBSD102-64-STD.ndz
# FBSD102-64-STD.ndz.sha1
# FBSD102-64-STD.ndz.sig
# FBSD102-64-STD.ndz:1
# FBSD102-64-STD.ndz:1.sha1
# FBSD102-64-STD.ndz:1.sig
# ...
# 11.ddz
# 12.ndz
# FBSD102-64-STD.ndz:12
# FBSD102-64-STD.ndz:12.sha1
# FBSD102-64-STD.ndz:12.sig
#
# where there will also be a signature file for each version (always
# representing the full version of the image, even if the version is
# just a delta) and a SHA1 hash file for each.
# The naming convention is awkward and redundant but required the least
# violence to convert to.
#
# Delta files with have a .ddz suffix instead of .ndz and will have their
# own .sig and .sha1 files as well (though the .sig is identical to the
# full image sigfile).
#
sub usage()
{
print("Usage: imagecompress [-dnK] <imageid> ...\n".
"For a complete image history, convert all intermediate versions\n".
"(i.e., all but first and last) into delta images.\n".
"Options:\n".
" -d Turn on debug mode\n".
" -n Just show what would be done\n".
" -K Keep existing other versions of images as well\n");
" -C Check hashes/signatures before doing anything\n".
" WARNING: this can take a really long time!\n".
" -K Keep existing other versions of images as well\n".
" -U Uncompress; create full images from all deltas instead.\n");
exit(-1);
}
my $optlist = "dnK";
my $optlist = "dnCKU";
my $debug = 0;
my $impotent = 0;
my $checkem = 0;
my $keepother = 0;
my $uncompress = 0;
my @images = ();
my @rmfull = ();
my @rmdelta = ();
......@@ -125,9 +143,15 @@ if (defined($options{"d"})) {
if (defined($options{"n"})) {
$impotent = 1;
}
if (defined($options{"C"})) {
$checkem = 1;
}
if (defined($options{"K"})) {
$keepother = 1;
}
if (defined($options{"U"})) {
$uncompress = 1;
}
if (@ARGV < 1) {
usage();
}
......@@ -259,6 +283,50 @@ sub doimage($)
return 1;
}
#
# Be super paranoid and check hashes and signatures too.
#
if ($checkem) {
if ($path) {
my $nhash = `$SHA1 $path`;
if ($? == 0 && $nhash =~ /^SHA1.*= ([\da-fA-F]+)$/) {
$nhash = lc($1);
if ($nhash ne $imobj->hash()) {
print STDERR "$iname: file hash != DB hash for version $vers!\n";
print STDERR " use 'sudo imagevalidate -uU -V hash $fqname' to correct\n";
return 1;
}
} else {
print STDERR "$iname: $SHA1 failed!?\n";
return 1;
}
if (system("$IMAGEHASH -SX $path")) {
print STDERR "$iname: signature does not check for version $vers!\n";
print STDERR " use 'sudo imagevalidate -uU -V sig $fqname' to correct\n";
return 1;
}
}
if ($dpath) {
my $nhash = `$SHA1 $dpath`;
if ($? == 0 && $nhash =~ /^SHA1.*= ([\da-fA-F]+)$/) {
$nhash = lc($1);
if ($nhash ne $imobj->deltahash()) {
print STDERR "$iname: delta file hash != DB deltahash for version $vers!\n";
print STDERR " use 'sudo imagevalidate -uU -V hash $fqname' to correct\n";
return 1;
}
} else {
print STDERR "$iname: $SHA1 failed!?\n";
return 1;
}
# XXX cannot check signature for delta image
}
}
if ($debug) {
print STDERR "$iname: found full version $vers: $path...\n"
if ($path);
......@@ -297,18 +365,32 @@ sub doimage($)
#
# Intermediate version: want a delta, generate it from full image.
# Also get rid of full version if desired.
# For -U, we want a full image, regenerate it from delta image.
# Also get rid of full (delta) version if desired.
#
if ($vers != $curvers) {
if ($path && !$dpath) {
if (createdelta($iname, $imobj, 1)) {
print STDERR "$iname: could not create delta for version $vers\n";
} else {
$dpath = $imobj->DeltaImageFile();
if ($uncompress) {
if ($dpath && !$path) {
if (createfull($iname, $imobj, 1)) {
print STDERR "$iname: could not create full for version $vers\n";
} else {
$path = $imobj->FullImageFile();
}
}
if ($dpath && $path && !$keepother) {
push(@rmdelta, $imobj);
}
} else {
if ($path && !$dpath) {
if (createdelta($iname, $imobj, 1)) {
print STDERR "$iname: could not create delta for version $vers\n";
} else {
$dpath = $imobj->DeltaImageFile();
}
}
if ($path && $dpath && !$keepother) {
push(@rmfull, $imobj);
}
}
if ($path && $dpath && !$keepother) {
push(@rmfull, $imobj);
}
next;
}
......@@ -511,11 +593,10 @@ sub removefull($$)
if ($debug);
if ($impotent) {
print "Would update DB hash/size/isdelta for full image $file ...\n";
print "Would update DB hash/size for full image $file ...\n";
} else {
if ($image->SetHash(undef) ||
$image->SetSize(0) ||
$image->SetDelta(1)) {
$image->SetSize(0)) {
print STDERR "$iname: could not clear database state\n";
return 1;
}
......@@ -629,11 +710,10 @@ sub removedelta($$)
if ($debug);
if ($impotent) {
print "Would update DB hash/size/isdelta for delta image $file ...\n";
print "Would update DB hash/size for delta image $file ...\n";
} else {
if ($image->SetDeltaHash(undef) ||
$image->SetDeltaSize(0) ||
$image->SetDelta(0)) {
$image->SetDeltaSize(0)) {
print STDERR "$iname: could not clear database state\n";
return 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment