Skip to content

Commit

Permalink
add the (optional) ability for the userenv to specify an update policy
Browse files Browse the repository at this point in the history
- if the userenv specifies "missing" (or nothing) for this property
  then no changes to the generated config information is made

- if the userenv specifies "digest" for this property then the origin
  image's digest is included in the origin image config data --
  allowing the caller(s) (ie. rickshaw) to make use of this
  information when determining if a new image should be built
  • Loading branch information
k-rister committed Aug 7, 2024
1 parent 0b2a141 commit ba97041
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 32 deletions.
10 changes: 9 additions & 1 deletion schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
"2020.04.30",
"2022.07.25",
"2023.02.16",
"2024.03.22"
"2024.03.22",
"2024.08.07"
]
}
},
Expand Down Expand Up @@ -110,6 +111,13 @@
"tag": {
"type": "string",
"minLength": 1
},
"update-policy": {
"type": "string",
"enum": [
"missing",
"digest"
]
}
},
"required": [
Expand Down
85 changes: 54 additions & 31 deletions workshop.pl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ sub get_exit_code {
'package_remove' => 93,
'group_remove' => 94,
'architecture_query_failed' => 95,
'unsupported_platform_architecture' => 96
'unsupported_platform_architecture' => 96,
'skopeo_inspect_failed' => 97
);

if (exists($reasons{$exit_reason})) {
Expand Down Expand Up @@ -581,6 +582,13 @@ sub delete_proto {
}
}

if (! exists $userenv_json->{'userenv'}{'origin'}{'update-policy'}) {
# if the loaded json does not include an update policy then
# default to "missing" which results in the same behavior we have
# always had
$userenv_json->{'userenv'}{'origin'}{'update-policy'} = "missing";
}

if (exists $userenv_json->{'userenv'}{'properties'}{'platform'}) {
# the userenv has platform information that indicates what type of
# system architecture(s) it supports so validate that what we are
Expand Down Expand Up @@ -882,10 +890,36 @@ sub delete_proto {
}

if ($args{'dump-config'} eq 'true') {
logger('info', "Config dump:\n");

my %config_dump = ();

if ($userenv_json->{'userenv'}{'origin'}{'update-policy'} eq 'digest') {
# get the userenv digest to include in the config dump -- this
# can be used by callers that are analyzing the dumped config
# to know whether or not the origin image has changed
my $image_id = $userenv_json->{'userenv'}{'origin'}{'image'} . ":" . $userenv_json->{'userenv'}{'origin'}{'tag'};
my $skopeo_url;
if (($image_id =~ /^dir:/) || ($image_id =~ /^docker:\/\//)) {
$skopeo_url = $image_id;
} else {
$skopeo_url = "docker://" . $image_id;
}
logger('info', "Querying for origin image digest...\n", 1);
($command, $command_output, $rc) = run_command("skopeo inspect --no-tags " . $skopeo_url);
if ($rc == 0) {
logger('info', "succeeded\n", 2);
command_logger('verbose', $command, $rc, $command_output);

$command_output = filter_output($command_output);
my $skopeo_json = decode_json($command_output);
$userenv_json->{'userenv'}{'origin'}{'digest'} = $skopeo_json{'digest'};
} else {
logger('info', "failed"\n, 2);
command_logger('error', $command, $rc, $command_output);
logger('error', "Failed to query " . $skopeo_url);
exit(get_exit_code('skopeo_inspect_failed'));
}
}

# consolidate information to be dumped
$config_dump{'userenv'} = $userenv_json;
$config_dump{'requirements'} = $active_requirements{'array'};
Expand All @@ -899,6 +933,7 @@ sub delete_proto {
delete $config_dump{'requirements'}[$i]{'sha256'};
}

logger('info', "Config dump:\n");
logger('info', Data::Dumper->Dump([\%config_dump], [qw(*config_dump)]));

exit()
Expand All @@ -922,46 +957,34 @@ sub delete_proto {
my $origin_image_id;

# acquire the userenv from the origin
logger('info', "Looking for container base image...\n");
($command, $command_output, $rc) = run_command("buildah images --json " . delete_proto($userenv_json->{'userenv'}{'origin'}{'image'}) . ":$userenv_json->{'userenv'}{'origin'}{'tag'}");
logger('info', "Attempting to download the latest version of $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}...\n", 1);
($command, $command_output, $rc) = run_command("buildah pull --quiet --policy=newer --tls-verify=$args{'reg-tls-verify'} $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}");
if ($rc == 0) {
logger('info', "Found $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'} locally\n", 1);
logger('info', "succeeded\n", 2);
command_logger('verbose', $command, $rc, $command_output);

$command_output = filter_output($command_output);
$userenv_json->{'userenv'}{'origin'}{'local_details'} = decode_json($command_output);
chomp($command_output);
$origin_image_id = $command_output;

$origin_image_id = $userenv_json->{'userenv'}{'origin'}{'local_details'}[0]{'id'};
} else {
command_logger('verbose', $command, $rc, $command_output);
logger('info', "Could not find $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}, attempting to download...\n", 1);
($command, $command_output, $rc) = run_command("buildah pull --quiet --tls-verify=$args{'reg-tls-verify'} $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}");
logger('info', "Querying for information about the image...\n", 1);
($command, $command_output, $rc) = run_command("buildah images --json " . $origin_image_id);
if ($rc == 0) {
logger('info', "succeeded\n", 2);
command_logger('verbose', $command, $rc, $command_output);

$command_output = filter_output($command_output);
chomp($command_output);
$origin_image_id = $command_output;

logger('info', "Querying for information about the image...\n", 1);
($command, $command_output, $rc) = run_command("buildah images --json " . $origin_image_id);
if ($rc == 0) {
logger('info', "succeeded\n", 2);
command_logger('verbose', $command, $rc, $command_output);
$command_output = filter_output($command_output);
$userenv_json->{'userenv'}{'origin'}{'local_details'} = decode_json($command_output);
} else {
logger('info', "failed\n", 2);
command_logger('error', $command, $rc, $command_output);
logger('error', "Failed to download/query $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'} ($origin_image_id)!\n");
exit(get_exit_code('image_query'));
}
$userenv_json->{'userenv'}{'origin'}{'local_details'} = decode_json($command_output);
} else {
logger('info', "failed\n", 2);
command_logger('error', $command, $rc, $command_output);
logger('error', "Failed to download $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}!\n");
exit(get_exit_code('image_origin_pull'));
logger('error', "Failed to query $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'} ($origin_image_id)!\n");
exit(get_exit_code('image_query'));
}
} else {
logger('info', "failed\n", 2);
command_logger('error', $command, $rc, $command_output);
logger('error', "Failed to download $userenv_json->{'userenv'}{'origin'}{'image'}:$userenv_json->{'userenv'}{'origin'}{'tag'}!\n");
exit(get_exit_code('image_origin_pull'));
}

logger('debug', "Userenv JSON:\n");
Expand Down

0 comments on commit ba97041

Please sign in to comment.