2021-03-03 01:19:24 +00:00
|
|
|
package packaging
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2023-04-27 11:44:39 +00:00
|
|
|
"crypto/tls"
|
2023-11-22 19:04:38 +00:00
|
|
|
"errors"
|
2021-11-22 14:13:26 +00:00
|
|
|
"fmt"
|
2021-03-03 01:19:24 +00:00
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"text/template"
|
|
|
|
|
|
2022-05-03 19:46:02 +00:00
|
|
|
"github.com/Masterminds/semver"
|
2021-08-11 14:02:22 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/orbit/pkg/constant"
|
|
|
|
|
"github.com/fleetdm/fleet/v4/orbit/pkg/update"
|
2021-08-24 12:50:03 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/secure"
|
2021-03-03 01:19:24 +00:00
|
|
|
"github.com/goreleaser/nfpm/v2"
|
|
|
|
|
"github.com/goreleaser/nfpm/v2/files"
|
2024-06-10 19:49:45 +00:00
|
|
|
"github.com/goreleaser/nfpm/v2/rpm"
|
2021-03-03 01:19:24 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
|
)
|
|
|
|
|
|
2021-11-15 13:40:58 +00:00
|
|
|
func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
|
2021-03-03 01:19:24 +00:00
|
|
|
// Initialize directories
|
2021-10-27 23:17:41 +00:00
|
|
|
tmpDir, err := initializeTempDir()
|
2021-03-03 01:19:24 +00:00
|
|
|
if err != nil {
|
2021-11-15 13:40:58 +00:00
|
|
|
return "", err
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
2022-05-02 18:18:59 +00:00
|
|
|
rootDir := filepath.Join(tmpDir, "root")
|
|
|
|
|
if err := secure.MkdirAll(rootDir, constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("create root dir: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
2022-05-02 18:18:59 +00:00
|
|
|
orbitRoot := filepath.Join(rootDir, "opt", "orbit")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("create orbit dir: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-17 20:07:59 +00:00
|
|
|
if opt.Architecture != ArchAmd64 && opt.Architecture != ArchArm64 {
|
|
|
|
|
return "", fmt.Errorf("Invalid architecture: %s", opt.Architecture)
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 01:19:24 +00:00
|
|
|
// Initialize autoupdate metadata
|
|
|
|
|
updateOpt := update.DefaultOptions
|
2022-03-15 19:04:12 +00:00
|
|
|
|
2021-03-03 01:19:24 +00:00
|
|
|
updateOpt.RootDirectory = orbitRoot
|
2024-07-17 20:07:59 +00:00
|
|
|
if opt.Architecture == ArchArm64 {
|
|
|
|
|
updateOpt.Targets = update.LinuxArm64Targets
|
|
|
|
|
} else {
|
|
|
|
|
updateOpt.Targets = update.LinuxTargets
|
|
|
|
|
}
|
2023-04-27 11:44:39 +00:00
|
|
|
updateOpt.ServerCertificatePath = opt.UpdateTLSServerCertificate
|
|
|
|
|
|
|
|
|
|
if opt.UpdateTLSClientCertificate != "" {
|
|
|
|
|
updateClientCrt, err := tls.LoadX509KeyPair(opt.UpdateTLSClientCertificate, opt.UpdateTLSClientKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("error loading update client certificate and key: %w", err)
|
|
|
|
|
}
|
|
|
|
|
updateOpt.ClientCertificate = &updateClientCrt
|
|
|
|
|
}
|
2022-03-15 19:04:12 +00:00
|
|
|
|
2022-05-04 14:14:12 +00:00
|
|
|
if opt.Desktop {
|
2024-07-17 20:07:59 +00:00
|
|
|
if opt.Architecture == ArchArm64 {
|
2024-10-28 23:40:19 +00:00
|
|
|
updateOpt.Targets[constant.DesktopTUFTargetName] = update.DesktopLinuxArm64Target
|
2024-07-17 20:07:59 +00:00
|
|
|
} else {
|
2024-10-28 23:40:19 +00:00
|
|
|
updateOpt.Targets[constant.DesktopTUFTargetName] = update.DesktopLinuxTarget
|
2024-07-17 20:07:59 +00:00
|
|
|
}
|
2022-05-04 14:14:12 +00:00
|
|
|
// Override default channel with the provided value.
|
2024-10-28 23:40:19 +00:00
|
|
|
updateOpt.Targets.SetTargetChannel(constant.DesktopTUFTargetName, opt.DesktopChannel)
|
2022-05-04 14:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
2022-03-15 19:04:12 +00:00
|
|
|
// Override default channels with the provided values.
|
2024-10-28 23:40:19 +00:00
|
|
|
updateOpt.Targets.SetTargetChannel(constant.OrbitTUFTargetName, opt.OrbitChannel)
|
|
|
|
|
updateOpt.Targets.SetTargetChannel(constant.OsqueryTUFTargetName, opt.OsquerydChannel)
|
2022-03-15 19:04:12 +00:00
|
|
|
|
2021-03-10 22:42:02 +00:00
|
|
|
updateOpt.ServerURL = opt.UpdateURL
|
2021-03-23 00:38:32 +00:00
|
|
|
if opt.UpdateRoots != "" {
|
|
|
|
|
updateOpt.RootKeys = opt.UpdateRoots
|
|
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
|
2022-01-31 13:41:11 +00:00
|
|
|
updatesData, err := InitializeUpdates(updateOpt)
|
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("initialize updates: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
2022-01-31 13:41:11 +00:00
|
|
|
log.Debug().Stringer("data", updatesData).Msg("updates initialized")
|
|
|
|
|
if opt.Version == "" {
|
|
|
|
|
// We set the package version to orbit's latest version.
|
|
|
|
|
opt.Version = updatesData.OrbitVersion
|
|
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
|
2022-05-03 19:46:02 +00:00
|
|
|
varLibSymlink := false
|
|
|
|
|
if orbitSemVer, err := semver.NewVersion(updatesData.OrbitVersion); err == nil {
|
|
|
|
|
if orbitSemVer.LessThan(semver.MustParse("0.0.11")) {
|
|
|
|
|
varLibSymlink = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// If err != nil we assume non-legacy Orbit.
|
|
|
|
|
|
2021-03-03 01:19:24 +00:00
|
|
|
// Write files
|
|
|
|
|
|
2024-06-10 19:49:45 +00:00
|
|
|
_, isRPM := pkger.(*rpm.RPM)
|
|
|
|
|
|
2022-05-02 18:18:59 +00:00
|
|
|
if err := writeSystemdUnit(opt, rootDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write systemd unit: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:18:59 +00:00
|
|
|
if err := writeEnvFile(opt, rootDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write env file: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-18 23:06:33 +00:00
|
|
|
if err := writeOsqueryFlagfile(opt, orbitRoot); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write flagfile: %w", err)
|
2021-11-18 23:06:33 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-19 01:17:05 +00:00
|
|
|
if err := writeOsqueryCertPEM(opt, orbitRoot); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write certs.pem: %w", err)
|
2021-11-19 01:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-03 01:19:24 +00:00
|
|
|
postInstallPath := filepath.Join(tmpDir, "postinstall.sh")
|
|
|
|
|
if err := writePostInstall(opt, postInstallPath); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write postinstall script: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
2022-04-19 12:32:47 +00:00
|
|
|
preRemovePath := filepath.Join(tmpDir, "preremove.sh")
|
|
|
|
|
if err := writePreRemove(opt, preRemovePath); err != nil {
|
|
|
|
|
return "", fmt.Errorf("write preremove script: %w", err)
|
|
|
|
|
}
|
|
|
|
|
postRemovePath := filepath.Join(tmpDir, "postremove.sh")
|
2024-06-10 19:49:45 +00:00
|
|
|
if err := writePostRemove(postRemovePath); err != nil {
|
2022-04-19 12:32:47 +00:00
|
|
|
return "", fmt.Errorf("write postremove script: %w", err)
|
|
|
|
|
}
|
2024-06-10 19:49:45 +00:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
|
2021-04-24 01:03:48 +00:00
|
|
|
if opt.FleetCertificate != "" {
|
2023-04-27 11:44:39 +00:00
|
|
|
if err := writeFleetServerCertificate(opt, orbitRoot); err != nil {
|
|
|
|
|
return "", fmt.Errorf("write fleet server certificate: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if opt.FleetTLSClientCertificate != "" {
|
|
|
|
|
if err := writeFleetClientCertificate(opt, orbitRoot); err != nil {
|
|
|
|
|
return "", fmt.Errorf("write fleet client certificate: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if opt.UpdateTLSServerCertificate != "" {
|
|
|
|
|
if err := writeUpdateServerCertificate(opt, orbitRoot); err != nil {
|
|
|
|
|
return "", fmt.Errorf("write update server certificate: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if opt.UpdateTLSClientCertificate != "" {
|
|
|
|
|
if err := writeUpdateClientCertificate(opt, orbitRoot); err != nil {
|
|
|
|
|
return "", fmt.Errorf("write update client certificate: %w", err)
|
2021-04-24 01:03:48 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 01:19:24 +00:00
|
|
|
// Pick up all file contents
|
|
|
|
|
|
|
|
|
|
contents := files.Contents{
|
|
|
|
|
&files.Content{
|
2022-05-02 18:18:59 +00:00
|
|
|
Source: filepath.Join(rootDir, "**"),
|
2021-03-03 01:19:24 +00:00
|
|
|
Destination: "/",
|
|
|
|
|
},
|
2022-05-02 18:18:59 +00:00
|
|
|
// Symlink current into /opt/orbit/bin/orbit/orbit
|
2021-03-03 01:19:24 +00:00
|
|
|
&files.Content{
|
2024-10-28 23:40:19 +00:00
|
|
|
Source: "/opt/orbit/bin/orbit/" + updateOpt.Targets[constant.OrbitTUFTargetName].Platform + "/" + opt.OrbitChannel + "/orbit",
|
2022-05-02 18:18:59 +00:00
|
|
|
Destination: "/opt/orbit/bin/orbit/orbit",
|
2021-03-03 01:19:24 +00:00
|
|
|
Type: "symlink",
|
|
|
|
|
FileInfo: &files.ContentFileInfo{
|
|
|
|
|
Mode: constant.DefaultExecutableMode | os.ModeSymlink,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
// Symlink current into /usr/local/bin
|
|
|
|
|
&files.Content{
|
2022-05-02 18:18:59 +00:00
|
|
|
Source: "/opt/orbit/bin/orbit/orbit",
|
2021-03-03 01:19:24 +00:00
|
|
|
Destination: "/usr/local/bin/orbit",
|
|
|
|
|
Type: "symlink",
|
|
|
|
|
FileInfo: &files.ContentFileInfo{
|
|
|
|
|
Mode: constant.DefaultExecutableMode | os.ModeSymlink,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-19 12:32:01 +00:00
|
|
|
// Add empty folders to be created.
|
|
|
|
|
for _, emptyFolder := range []string{"/var/log/osquery", "/var/log/orbit"} {
|
|
|
|
|
contents = append(contents, (&files.Content{
|
|
|
|
|
Destination: emptyFolder,
|
|
|
|
|
Type: "dir",
|
|
|
|
|
}).WithFileInfoDefaults())
|
|
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
|
2022-05-03 19:46:02 +00:00
|
|
|
if varLibSymlink {
|
|
|
|
|
contents = append(contents,
|
|
|
|
|
// Symlink needed to support old versions of orbit.
|
|
|
|
|
&files.Content{
|
|
|
|
|
Source: "/opt/orbit",
|
|
|
|
|
Destination: "/var/lib/orbit",
|
|
|
|
|
Type: "symlink",
|
|
|
|
|
FileInfo: &files.ContentFileInfo{
|
|
|
|
|
Mode: os.ModeSymlink,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 18:18:59 +00:00
|
|
|
contents, err = files.ExpandContentGlobs(contents, false)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("glob contents: %w", err)
|
|
|
|
|
}
|
|
|
|
|
for _, c := range contents {
|
|
|
|
|
log.Debug().Interface("file", c).Msg("added file")
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-10 19:49:45 +00:00
|
|
|
rpmInfo := nfpm.RPM{}
|
|
|
|
|
if _, ok := pkger.(*rpm.RPM); ok {
|
|
|
|
|
rpmInfo.Scripts.PostTrans = postTransPath
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-19 12:32:01 +00:00
|
|
|
// Build package
|
2021-03-03 01:19:24 +00:00
|
|
|
info := &nfpm.Info{
|
2021-11-19 01:43:52 +00:00
|
|
|
Name: "fleet-osquery",
|
2021-03-03 01:19:24 +00:00
|
|
|
Version: opt.Version,
|
2021-11-19 01:43:52 +00:00
|
|
|
Description: "Fleet osquery -- runtime and autoupdater",
|
2024-07-17 20:07:59 +00:00
|
|
|
Arch: opt.Architecture,
|
2022-11-21 18:55:12 +00:00
|
|
|
Maintainer: "Fleet Device Management",
|
|
|
|
|
Vendor: "Fleet Device Management",
|
|
|
|
|
License: "https://github.com/fleetdm/fleet/blob/main/LICENSE",
|
2021-11-19 01:43:52 +00:00
|
|
|
Homepage: "https://fleetdm.com",
|
2021-03-03 01:19:24 +00:00
|
|
|
Overridables: nfpm.Overridables{
|
|
|
|
|
Contents: contents,
|
|
|
|
|
Scripts: nfpm.Scripts{
|
|
|
|
|
PostInstall: postInstallPath,
|
2022-04-19 12:32:47 +00:00
|
|
|
PreRemove: preRemovePath,
|
|
|
|
|
PostRemove: postRemovePath,
|
2021-03-03 01:19:24 +00:00
|
|
|
},
|
2024-06-10 19:49:45 +00:00
|
|
|
RPM: rpmInfo,
|
2021-03-03 01:19:24 +00:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
filename := pkger.ConventionalFileName(info)
|
2022-07-11 12:49:13 +00:00
|
|
|
if opt.NativeTooling {
|
|
|
|
|
filename = filepath.Join("build", filename)
|
|
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
|
2023-11-22 19:04:38 +00:00
|
|
|
if err := os.Remove(filename); err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
|
|
|
return "", fmt.Errorf("removing existing file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-18 14:32:55 +00:00
|
|
|
if opt.NativeTooling {
|
|
|
|
|
if err := secure.MkdirAll(filepath.Dir(filename), 0o700); err != nil {
|
[fleetctl] fix deb package build (#23796)
I'm trying to setup a GitLab CI job to build the deb packages, but it
fails with:
```
Error: open output file: open build/fleet-osquery_1.35.0_amd64.deb: no such file or directory
```
It happens because I can't mount the `build` volume as I would do on my
local pc. To reproduce:
```
docker run -it fleetdm/fleetctl package --type=deb --fleet-url=my.url --enroll-secret=mysecret
```
`pkg` and `msi` works fine. I can workaround it by creating the `build`
dir first, but I think that's also fleetctl job to create it.
# Checklist for submitter
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files)
for more information.
- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.
- [ ] Added/updated tests
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes
- [ ] If database migrations are included, checked table schema to
confirm autoupdate
- For database migrations:
- [ ] Checked schema for all modified table for columns that will
auto-update timestamps during migration.
- [ ] Confirmed that updating the timestamps is acceptable, and will not
cause unwanted side effects.
- [ ] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).
- [ ] Manual QA for all new/changed functionality
- For Orbit and Fleet Desktop changes:
- [ ] Orbit runs on macOS, Linux and Windows. Check if the orbit
feature/bugfix should only apply to one platform (`runtime.GOOS`).
- [ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-11-18 13:43:41 +00:00
|
|
|
return "", fmt.Errorf("cannot create build dir: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-11 14:02:22 +00:00
|
|
|
out, err := secure.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode)
|
2021-03-03 01:19:24 +00:00
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("open output file: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
defer out.Close()
|
|
|
|
|
|
|
|
|
|
if err := pkger.Package(info, out); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write package: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
2021-08-17 12:41:56 +00:00
|
|
|
if err := out.Sync(); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("sync output file: %w", err)
|
2021-08-17 12:41:56 +00:00
|
|
|
}
|
2021-03-03 01:19:24 +00:00
|
|
|
log.Info().Str("path", filename).Msg("wrote package")
|
|
|
|
|
|
2021-11-15 13:40:58 +00:00
|
|
|
return filename, nil
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func writeSystemdUnit(opt Options, rootPath string) error {
|
|
|
|
|
systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("create systemd dir: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
2023-10-27 18:28:54 +00:00
|
|
|
if err := os.WriteFile(
|
2021-03-03 01:19:24 +00:00
|
|
|
filepath.Join(systemdRoot, "orbit.service"),
|
|
|
|
|
[]byte(`
|
|
|
|
|
[Unit]
|
|
|
|
|
Description=Orbit osquery
|
|
|
|
|
After=network.service syslog.service
|
|
|
|
|
StartLimitIntervalSec=0
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
TimeoutStartSec=0
|
|
|
|
|
EnvironmentFile=/etc/default/orbit
|
2022-05-02 18:18:59 +00:00
|
|
|
ExecStart=/opt/orbit/bin/orbit/orbit
|
2021-03-03 01:19:24 +00:00
|
|
|
Restart=always
|
|
|
|
|
RestartSec=1
|
|
|
|
|
KillMode=control-group
|
|
|
|
|
KillSignal=SIGTERM
|
|
|
|
|
CPUQuota=20%
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
`),
|
2022-05-23 22:18:19 +00:00
|
|
|
constant.DefaultSystemdUnitMode,
|
2021-03-03 01:19:24 +00:00
|
|
|
); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var envTemplate = template.Must(template.New("env").Parse(`
|
2021-03-10 22:42:02 +00:00
|
|
|
ORBIT_UPDATE_URL={{ .UpdateURL }}
|
2021-03-10 00:27:35 +00:00
|
|
|
ORBIT_ORBIT_CHANNEL={{ .OrbitChannel }}
|
|
|
|
|
ORBIT_OSQUERYD_CHANNEL={{ .OsquerydChannel }}
|
2022-04-11 20:42:36 +00:00
|
|
|
ORBIT_UPDATE_INTERVAL={{ .OrbitUpdateInterval }}
|
2022-05-04 14:14:12 +00:00
|
|
|
{{ if .Desktop }}
|
|
|
|
|
ORBIT_FLEET_DESKTOP=true
|
|
|
|
|
ORBIT_DESKTOP_CHANNEL={{ .DesktopChannel }}
|
2023-04-27 11:44:39 +00:00
|
|
|
{{ if .FleetDesktopAlternativeBrowserHost }}
|
|
|
|
|
ORBIT_FLEET_DESKTOP_ALTERNATIVE_BROWSER_HOST={{ .FleetDesktopAlternativeBrowserHost }}
|
|
|
|
|
{{ end }}
|
2022-05-04 14:14:12 +00:00
|
|
|
{{ end }}
|
2021-03-10 00:27:35 +00:00
|
|
|
{{ if .Insecure }}ORBIT_INSECURE=true{{ end }}
|
2022-02-18 18:42:39 +00:00
|
|
|
{{ if .DisableUpdates }}ORBIT_DISABLE_UPDATES=true{{ end }}
|
2021-03-03 01:19:24 +00:00
|
|
|
{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }}
|
2022-05-02 18:18:59 +00:00
|
|
|
{{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/opt/orbit/fleet.pem{{ end }}
|
2023-04-27 11:44:39 +00:00
|
|
|
{{ if .UpdateTLSServerCertificate }}ORBIT_UPDATE_TLS_CERTIFICATE=/opt/orbit/update.pem{{ end }}
|
2021-03-03 01:19:24 +00:00
|
|
|
{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }}
|
2021-03-09 23:22:17 +00:00
|
|
|
{{ if .Debug }}ORBIT_DEBUG=true{{ end }}
|
2023-08-30 13:18:34 +00:00
|
|
|
{{ if .EnableScripts }}ORBIT_ENABLE_SCRIPTS=true{{ end }}
|
2023-12-15 18:26:32 +00:00
|
|
|
{{ if and (ne .HostIdentifier "") (ne .HostIdentifier "uuid") }}ORBIT_HOST_IDENTIFIER={{.HostIdentifier}}{{ end }}
|
2024-02-05 12:41:06 +00:00
|
|
|
{{ if .OsqueryDB }}ORBIT_OSQUERY_DB={{.OsqueryDB}}{{ end }}
|
2024-06-18 15:10:19 +00:00
|
|
|
{{ if .EndUserEmail }}ORBIT_END_USER_EMAIL={{.EndUserEmail}}{{ end }}
|
2021-03-03 01:19:24 +00:00
|
|
|
`))
|
|
|
|
|
|
|
|
|
|
func writeEnvFile(opt Options, rootPath string) error {
|
|
|
|
|
envRoot := filepath.Join(rootPath, "etc", "default")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(envRoot, constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("create env dir: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
|
if err := envTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-27 18:28:54 +00:00
|
|
|
if err := os.WriteFile(
|
2021-03-03 01:19:24 +00:00
|
|
|
filepath.Join(envRoot, "orbit"),
|
|
|
|
|
contents.Bytes(),
|
|
|
|
|
constant.DefaultFileMode,
|
|
|
|
|
); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 22:18:19 +00:00
|
|
|
var postInstallTemplate = template.Must(template.New("postinstall").Parse(`#!/bin/sh
|
2021-03-03 01:19:24 +00:00
|
|
|
|
|
|
|
|
# Exit on error
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
# If we have a systemd, daemon-reload away now
|
2022-01-31 23:56:05 +00:00
|
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
|
|
|
systemctl daemon-reload >/dev/null 2>&1
|
2021-03-03 01:19:24 +00:00
|
|
|
{{ if .StartService -}}
|
2022-01-01 23:18:30 +00:00
|
|
|
systemctl restart orbit.service 2>&1
|
2022-01-31 23:56:05 +00:00
|
|
|
systemctl enable orbit.service 2>&1
|
2021-03-03 01:19:24 +00:00
|
|
|
{{- end}}
|
|
|
|
|
fi
|
|
|
|
|
`))
|
|
|
|
|
|
|
|
|
|
func writePostInstall(opt Options, path string) error {
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
|
if err := postInstallTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-27 18:28:54 +00:00
|
|
|
if err := os.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-03-03 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2022-04-19 12:32:47 +00:00
|
|
|
|
|
|
|
|
func writePreRemove(opt Options, path string) error {
|
2022-05-04 14:14:12 +00:00
|
|
|
// We add `|| true` in case the service is not running
|
|
|
|
|
// or has been manually disabled already. Otherwise,
|
|
|
|
|
// uninstallation fails.
|
2022-06-21 19:26:14 +00:00
|
|
|
//
|
|
|
|
|
// "pkill fleet-desktop" is required because the application
|
|
|
|
|
// runs as user (separate from sudo command that launched it),
|
|
|
|
|
// so on some systems it's not killed properly.
|
2023-10-27 18:28:54 +00:00
|
|
|
if err := os.WriteFile(path, []byte(`#!/bin/sh
|
2022-04-19 12:32:47 +00:00
|
|
|
|
2022-05-04 14:14:12 +00:00
|
|
|
systemctl stop orbit.service || true
|
|
|
|
|
systemctl disable orbit.service || true
|
2022-06-21 19:26:14 +00:00
|
|
|
pkill fleet-desktop || true
|
2022-04-19 12:32:47 +00:00
|
|
|
`), constant.DefaultFileMode); err != nil {
|
|
|
|
|
return fmt.Errorf("write file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-10 19:49:45 +00:00
|
|
|
func writePostRemove(path string) error {
|
2023-10-27 18:28:54 +00:00
|
|
|
if err := os.WriteFile(path, []byte(`#!/bin/sh
|
2022-04-19 12:32:47 +00:00
|
|
|
|
2023-10-27 16:29:09 +00:00
|
|
|
# For RPM during uninstall, $1 is 0
|
|
|
|
|
# For Debian during remove, $1 is "remove"
|
|
|
|
|
if [ "$1" = 0 ] || [ "$1" = "remove" ]; then
|
|
|
|
|
rm -rf /var/lib/orbit /var/log/orbit /usr/local/bin/orbit /etc/default/orbit /usr/lib/systemd/system/orbit.service /opt/orbit
|
|
|
|
|
fi
|
2022-04-19 12:32:47 +00:00
|
|
|
`), constant.DefaultFileMode); err != nil {
|
|
|
|
|
return fmt.Errorf("write file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2024-06-10 19:49:45 +00:00
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|