This repository has been archived by the owner on May 22, 2023. It is now read-only.
forked from d11wtq/gentoo-packer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
latest_state3.pl
156 lines (131 loc) · 4.46 KB
/
latest_state3.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env perl
# ABSTRACT: Inject latest stage3 data into .json
use strict;
use warnings;
use 5.010;
sub main {
my $base = "http://distfiles.gentoo.org/releases/amd64/autobuilds";
my $image_name = "install-amd64-minimal";
my $datestamp = get_datestamp(
url => "${base}/latest-iso.txt",
image_name => $image_name,
);
*STDERR->print("* Got datestamp = $datestamp\n");
my $sha512 = get_hash(
url => "${base}/${datestamp}/${image_name}-${datestamp}.iso.DIGESTS",
filename => "${image_name}-${datestamp}.iso",
label => "SHA512 HASH"
);
*STDERR->print("* Got digest = $sha512\n");
my $json = read_json('virtualbox.json');
$json->{variables}->{stage3} = $datestamp;
for my $builder ( @{ $json->{builders} } ) {
next unless $builder->{vm_name} eq 'Gentoo';
$builder->{iso_checksum} = $sha512;
$builder->{iso_checksum_type} = "sha512";
}
write_json( 'virtualbox.json', $json );
return 0;
}
exit main();
# get_datestamp(
# url => url to fetch datestamps from
# image_name => basename for image to match, eg: install-amd64-minimal
# );
#
# Emits a number if a number is found in the URL matching :number/:image_name-:number.iso
sub get_datestamp {
my ($config) = {@_};
my $url = $config->{url};
my $image_name = $config->{image_name};
for my $line ( lines( get_url($url) ) ) {
next if $line =~ /\A#/;
next unless $line =~ /\A(\d+)\/${image_name}-\d+.iso\s/;
return "$1";
}
die "Did not find /${image_name} in ${url}";
}
# get_hash (
# label => The comment line indicating what kind of hash it is, eg:"SHA512 HASH"
# filename => The filename you want the hash for, eg: ":image_name-:datestamp.iso"
# url => The URL to fetch digest data from.
# hash_characters => The number of characters the hash will be ( 128 )
# hash_dictionary => The characters a hash will be expressed in ( lower hex )
# )
sub get_hash {
my ($config) = {@_};
my $want_label = $config->{label};
my $want_filename = $config->{filename};
my $url = $config->{url};
my $hash_characters = $config->{hash_characters} || 128;
my $hash_dictionary = $config->{hash_dictionary} || '0-9a-f';
my $hash_expr = '[' . $hash_dictionary . ']{' . $hash_characters . '}';
my $seen_comment;
my (@lines) = lines( get_url($url) );
while (@lines) {
my ( $label, $content ) = splice @lines, 0, 2, ();
next if $label !~ /\A#\s\Q${want_label}\E/;
next unless $content =~ /\A(${hash_expr})\s+\Q${want_filename}\E\z/;
return "$1";
}
die "Did not find ${want_label} for ${want_filename} in ${url}";
}
use JSON::PP;
# json()->
#
# Returns a JSON::PP object configured for keeping the existing indentation of virtualbox.json
sub json {
return state $encoder = do {
JSON::PP->new->indent(1)->space_after(1)->canonical(1)
->indent_length(2)->utf8(1);
};
}
# read_json('filename.json')
# returns filename.json as a hash tree.
sub read_json {
my ($path) = @_;
return json()->decode( slurp($path) );
}
# write_json('filename.json', $hash_tree )
# writes hash tree to filename.json
sub write_json {
my ( $path, $data ) = @_;
return spew( $path, json()->encode($data) );
}
# slurp( $filename )
# reads $filename as a single string.
sub slurp {
my ($fn) = @_;
open my $fh, '<:raw:unix', $fn or die "Can't open $fn for reading: $! $?";
my $content = do { local $/; scalar <$fh> };
close $fh or warn "Problem closing $fn, $! $?";
return $content;
}
# spew( filename, $content );
# write content out to $filename
sub spew {
my ( $fn, $content ) = @_;
open my $fh, '>:raw:unix', $fn or die "Can't open $fn for writing: $! $?";
print {$fh} $content or warn "Problem writing to $fn! $! $?";
close $fh or warn "Problem closing $fn!, $! $?";
return;
}
use HTTP::Tiny;
# get_url( $url )
# return $url's content, or die.
sub get_url {
my ($url) = @_;
state $agent = do {
HTTP::Tiny->new();
};
*STDERR->print("* Fetching $url\n");
my $result = $agent->get($url);
return $result->{content} if $result->{success};
die "Could not fetch $url, status: "
. $result->{status}
. " reason: "
. $result->{reason};
}
# my @lines = lines( $content )
# returns content split into lines with trailing \n's stripped.
sub lines { split /\n/, $_[0] }