Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update all - check for upgradable packages #644

Merged
merged 20 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ef4d021
dpkg check for upgradable
ashnamehrotra May 22, 2024
9ef1ea4
apk check for upgradable
ashnamehrotra May 22, 2024
960a843
rpm distroless check for upgradable - change yum info to yum list ava…
ashnamehrotra May 22, 2024
47ec06e
dnf and yum non distro
ashnamehrotra May 29, 2024
0f8cc47
non-distro microdnf check via dnf
ashnamehrotra May 30, 2024
099afc3
Merge branch 'main' of github.com:project-copacetic/copacetic into ch…
ashnamehrotra May 30, 2024
9ef953d
apk fix
ashnamehrotra Jun 3, 2024
0f7717e
Merge branch 'main' of github.com:project-copacetic/copacetic into ch…
ashnamehrotra Jun 3, 2024
5872e8e
lint fix
ashnamehrotra Jun 3, 2024
084534c
saving changes to mount tooling for upgrade checks - rpm non-distro
ashnamehrotra Jun 12, 2024
35da7f7
Merge branch 'main' of github.com:project-copacetic/copacetic into ch…
ashnamehrotra Jun 12, 2024
ad5b85f
test with writing a file approach
ashnamehrotra Jun 20, 2024
93552e2
fix path
ashnamehrotra Jun 21, 2024
5a67c60
remove debugging
ashnamehrotra Jun 21, 2024
a43508b
lint fixes
ashnamehrotra Jun 21, 2024
f550adc
revert to using package managers if present and remove debug output f…
ashnamehrotra Jun 25, 2024
2e94f13
lint fix
ashnamehrotra Jun 25, 2024
2add0b3
Merge branch 'main' of github.com:project-copacetic/copacetic into ch…
ashnamehrotra Jun 25, 2024
60649af
Merge branch 'main' of github.com:project-copacetic/copacetic into ch…
ashnamehrotra Jun 26, 2024
13db0e4
Merge branch 'main' into check-for-update
sozercan Jul 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/pkgmgr/apk.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@
// TODO: Add support for custom APK config
apkUpdated := am.config.ImageState.Run(llb.Shlex("apk update"), llb.WithProxy(utils.GetProxy()), llb.IgnoreCache).Root()

// If updating all packages, check for upgrades before proceeding with patch
if updates == nil {
checkUpgradable := `sh -c "apk list 2>/dev/null | grep -q "upgradable" || exit 1"`
sozercan marked this conversation as resolved.
Show resolved Hide resolved
sozercan marked this conversation as resolved.
Show resolved Hide resolved
apkUpdated = apkUpdated.Run(llb.Shlex(checkUpgradable)).Root()

Check warning on line 171 in pkg/pkgmgr/apk.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/apk.go#L169-L171

Added lines #L169 - L171 were not covered by tests
}

var apkInstalled llb.State
var resultManifestBytes []byte
var err error
Expand Down
8 changes: 8 additions & 0 deletions pkg/pkgmgr/dpkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@
llb.IgnoreCache,
).Root()

checkUpgradable := `sh -c "apt list --upgradable 2>/dev/null | grep -q "upgradable" || exit 1"`
aptUpdated = aptUpdated.Run(llb.Shlex(checkUpgradable)).Root()

Check warning on line 319 in pkg/pkgmgr/dpkg.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/dpkg.go#L318-L319

Added lines #L318 - L319 were not covered by tests

// Install all requested update packages without specifying the version. This works around:
// - Reports being slightly out of date, where a newer security revision has displaced the one specified leading to not found errors.
// - Reports not specifying version epochs correct (e.g. bsdutils=2.36.1-8+deb11u1 instead of with epoch as 1:2.36.1-8+dev11u1)
Expand Down Expand Up @@ -396,6 +399,11 @@
fi
done <<< "$(echo "$json_str" | tr -d '{}\n' | tr ',' '\n')"

if [ -z "$update_packages" ]; then
echo "No packages to update"
exit 1
fi

Check warning on line 405 in pkg/pkgmgr/dpkg.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/dpkg.go#L402-L405

Added lines #L402 - L405 were not covered by tests

mkdir /var/cache/apt/archives
cd /var/cache/apt/archives
echo "$update_packages" > packages.txt
Expand Down
2 changes: 1 addition & 1 deletion pkg/pkgmgr/pkgmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func GetPackageManager(osType string, osVersion string, config *buildkit.Config,
case "debian", "ubuntu":
return &dpkgManager{config: config, workingFolder: workingFolder, osVersion: osVersion}, nil
case "cbl-mariner", "centos", "redhat", "rocky", "amazon":
return &rpmManager{config: config, workingFolder: workingFolder}, nil
return &rpmManager{config: config, workingFolder: workingFolder, osVersion: osVersion}, nil
default:
return nil, fmt.Errorf("unsupported osType %s specified", osType)
}
Expand Down
41 changes: 38 additions & 3 deletions pkg/pkgmgr/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
rpmTools rpmToolPaths
isDistroless bool
packageInfo map[string]string
osVersion string
}

type rpmDBType uint
Expand Down Expand Up @@ -400,12 +401,27 @@
var installCmd string
switch {
case rm.rpmTools["dnf"] != "":
checkUpdateTemplate := `sh -c "%[1]s check-update; if [ $? -ne 0 ]; then echo >> /updates.txt; fi"`
sozercan marked this conversation as resolved.
Show resolved Hide resolved
if !rm.checkForUpgrades(ctx, rm.rpmTools["dnf"], checkUpdateTemplate) {
return nil, nil, fmt.Errorf("no patchable packages found")

Check warning on line 406 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L404-L406

Added lines #L404 - L406 were not covered by tests
}

const dnfInstallTemplate = `sh -c '%[1]s upgrade %[2]s -y && %[1]s clean all'`
installCmd = fmt.Sprintf(dnfInstallTemplate, rm.rpmTools["dnf"], pkgs)
case rm.rpmTools["yum"] != "":
checkUpdateTemplate := `sh -c 'if [ "$(%[1]s -q check-update | wc -l)" -ne 0 ]; then echo >> /updates.txt; fi'`
sozercan marked this conversation as resolved.
Show resolved Hide resolved
if !rm.checkForUpgrades(ctx, rm.rpmTools["yum"], checkUpdateTemplate) {
return nil, nil, fmt.Errorf("no patchable packages found")

Check warning on line 414 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L412-L414

Added lines #L412 - L414 were not covered by tests
}

const yumInstallTemplate = `sh -c '%[1]s upgrade %[2]s -y && %[1]s clean all'`
installCmd = fmt.Sprintf(yumInstallTemplate, rm.rpmTools["yum"], pkgs)
case rm.rpmTools["microdnf"] != "":
checkUpdateTemplate := `sh -c "%[1]s install dnf -y; dnf check-update -y; if [ $? -ne 0 ]; then echo >> /updates.txt; fi;"`
sozercan marked this conversation as resolved.
Show resolved Hide resolved
if !rm.checkForUpgrades(ctx, rm.rpmTools["microdnf"], checkUpdateTemplate) {
return nil, nil, fmt.Errorf("no patchable packages found")

Check warning on line 422 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L420-L422

Added lines #L420 - L422 were not covered by tests
}

const microdnfInstallTemplate = `sh -c '%[1]s update %[2]s && %[1]s clean all'`
installCmd = fmt.Sprintf(microdnfInstallTemplate, rm.rpmTools["microdnf"], pkgs)
default:
Expand All @@ -416,12 +432,12 @@

// Write results.manifest to host for post-patch validation
var resultBytes []byte
var err error
if updates != nil {
const rpmResultsTemplate = `sh -c 'rpm -qa --queryformat "%s" %s > "%s"'`
outputResultsCmd := fmt.Sprintf(rpmResultsTemplate, resultQueryFormat, pkgs, resultManifest)
resultsWritten := installed.Dir(resultsPath).Run(llb.Shlex(outputResultsCmd)).AddMount(resultsPath, llb.Scratch())

var err error

Check warning on line 440 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L440

Added line #L440 was not covered by tests
resultBytes, err = buildkit.ExtractFileFromState(ctx, rm.config.Client, &resultsWritten, resultManifest)
if err != nil {
return nil, nil, err
Expand All @@ -434,6 +450,20 @@
return &patchMerge, resultBytes, nil
}

func (rm *rpmManager) checkForUpgrades(ctx context.Context, toolPath, checkUpdateTemplate string) bool {
checkUpdate := fmt.Sprintf(checkUpdateTemplate, toolPath)
stateWithCheck := rm.config.ImageState.Run(llb.Shlex(checkUpdate)).Root()

Check warning on line 455 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L453-L455

Added lines #L453 - L455 were not covered by tests

_, err := buildkit.ExtractFileFromState(ctx, rm.config.Client, &stateWithCheck, "/updates.txt")

Check warning on line 457 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L457

Added line #L457 was not covered by tests

// if error in extracting file, that means updates.txt does not exist and there are no updates.
if err != nil {

Check failure on line 460 in pkg/pkgmgr/rpm.go

View workflow job for this annotation

GitHub Actions / lint

S1008: should use 'return err == nil' instead of 'if err != nil { return false }; return true' (gosimple)
return false

Check warning on line 461 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L460-L461

Added lines #L460 - L461 were not covered by tests
}

return true

Check warning on line 464 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L464

Added line #L464 was not covered by tests
}

func (rm *rpmManager) unpackAndMergeUpdates(ctx context.Context, updates unversioned.UpdatePackages, toolImage string) (*llb.State, []byte, error) {
// Spin up a build tooling container to fetch and unpack packages to create patch layer.
// Pull family:version -> need to create version to base image map
Expand All @@ -449,7 +479,7 @@
if updates == nil {
jsonPackageData, err := json.Marshal(rm.packageInfo)
if err != nil {
return nil, nil, fmt.Errorf("unable to marshal dm.packageInfo %w", err)
return nil, nil, fmt.Errorf("unable to marshal rm.packageInfo %w", err)

Check warning on line 482 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L482

Added line #L482 was not covered by tests
}

busyboxCopied = busyboxCopied.Run(
Expand All @@ -463,13 +493,18 @@
pkg_name=$(echo "$package" | sed 's/^"\(.*\)"$/\1/')

pkg_version=$(echo "$version" | sed 's/^"\(.*\)"$/\1/')
latest_version=$(yum info $pkg_name 2>/dev/null | grep "Version" | sed -n '$s/Version *: //p')
latest_version=$(yum list available $pkg_name 2>/dev/null | grep $pkg_name | tail -n 1 | tr -s ' ' | cut -d ' ' -f 2 | sed 's/\.cm2//')

Check warning on line 496 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L496

Added line #L496 was not covered by tests

if [ "$latest_version" != "$pkg_version" ]; then
update_packages="$update_packages $pkg_name"
fi
done <<< "$(echo "$json_str" | tr -d '{}\n' | tr ',' '\n')"

if [ -z "$update_packages" ]; then
echo "No packages to update"
exit 1
fi

Check warning on line 506 in pkg/pkgmgr/rpm.go

View check run for this annotation

Codecov / codecov/patch

pkg/pkgmgr/rpm.go#L503-L506

Added lines #L503 - L506 were not covered by tests

echo "$update_packages" > packages.txt
`,
})).Root()
Expand Down
Loading