Support RPM upgrades on fleetd packages (#19494)

#18534

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [X] Manual QA for all new/changed functionality
  - For Orbit and Fleet Desktop changes:
- [X] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [x] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
This commit is contained in:
Lucas Manuel Rodriguez
2024-06-10 16:49:45 -03:00
committed by GitHub
parent 5f65ea831c
commit 7eb3628fe6
2 changed files with 55 additions and 2 deletions
+1
View File
@@ -0,0 +1 @@
* Added support for upgrades to fleetd RPMs packages.
+54 -2
View File
@@ -15,6 +15,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/secure"
"github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files"
"github.com/goreleaser/nfpm/v2/rpm"
"github.com/rs/zerolog/log"
)
@@ -85,6 +86,8 @@ func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
// Write files
_, isRPM := pkger.(*rpm.RPM)
if err := writeSystemdUnit(opt, rootDir); err != nil {
return "", fmt.Errorf("write systemd unit: %w", err)
}
@@ -110,9 +113,16 @@ func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
return "", fmt.Errorf("write preremove script: %w", err)
}
postRemovePath := filepath.Join(tmpDir, "postremove.sh")
if err := writePostRemove(opt, postRemovePath); err != nil {
if err := writePostRemove(postRemovePath); err != nil {
return "", fmt.Errorf("write postremove script: %w", err)
}
var postTransPath string
if isRPM {
postTransPath = filepath.Join(tmpDir, "posttrans.sh")
if err := writeRPMPostTrans(opt, postTransPath); err != nil {
return "", fmt.Errorf("write RPM posttrans script: %w", err)
}
}
if opt.FleetCertificate != "" {
if err := writeFleetServerCertificate(opt, orbitRoot); err != nil {
@@ -194,6 +204,11 @@ func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
log.Debug().Interface("file", c).Msg("added file")
}
rpmInfo := nfpm.RPM{}
if _, ok := pkger.(*rpm.RPM); ok {
rpmInfo.Scripts.PostTrans = postTransPath
}
// Build package
info := &nfpm.Info{
Name: "fleet-osquery",
@@ -211,6 +226,7 @@ func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
PreRemove: preRemovePath,
PostRemove: postRemovePath,
},
RPM: rpmInfo,
},
}
filename := pkger.ConventionalFileName(info)
@@ -367,7 +383,7 @@ pkill fleet-desktop || true
return nil
}
func writePostRemove(opt Options, path string) error {
func writePostRemove(path string) error {
if err := os.WriteFile(path, []byte(`#!/bin/sh
# For RPM during uninstall, $1 is 0
@@ -381,3 +397,39 @@ fi
return nil
}
// postTransTemplate contains the template for RPM posttrans scriptlet (used when upgrading).
// See https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/.
//
// We cannot rely on "$1" because it's always "0" for RPM < 4.12
// (see https://github.com/rpm-software-management/rpm/commit/ab069ec876639d46d12dd76dad54fd8fb762e43d)
// thus we check if orbit service is enabled, and if not we enable it (because posttrans
// will run both on "install" and "upgrade").
var postTransTemplate = template.Must(template.New("posttrans").Parse(`#!/bin/sh
# Exit on error
set -e
if ! systemctl is-enabled orbit >/dev/null 2>&1; then
# If we have a systemd, daemon-reload away now
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload >/dev/null 2>&1
{{ if .StartService -}}
systemctl restart orbit.service 2>&1
systemctl enable orbit.service 2>&1
{{- end}}
fi
fi
`))
// writeRPMPostTrans sets the posttrans scriptlets necessary to support RPM upgrades.
func writeRPMPostTrans(opt Options, path string) error {
var contents bytes.Buffer
if err := postTransTemplate.Execute(&contents, opt); err != nil {
return fmt.Errorf("execute template: %w", err)
}
if err := os.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil {
return fmt.Errorf("write file: %w", err)
}
return nil
}