2021-02-09 03:23:50 +00:00
|
|
|
package packaging
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
|
|
|
|
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-11-15 18:01:48 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/file"
|
2021-08-24 12:50:03 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/secure"
|
2021-02-09 03:23:50 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// See helful docs in http://bomutils.dyndns.org/tutorial.html
|
|
|
|
|
|
|
|
// BuildPkg builds a macOS .pkg. So far this is tested only on macOS but in theory it works with bomutils on
|
|
|
|
// Linux.
|
2021-11-15 13:40:58 +00:00
|
|
|
func BuildPkg(opt Options) (string, error) {
|
2021-02-09 03:23:50 +00:00
|
|
|
// Initialize directories
|
2021-10-27 23:17:41 +00:00
|
|
|
tmpDir, err := initializeTempDir()
|
2021-02-09 03:23:50 +00:00
|
|
|
if err != nil {
|
2021-11-15 13:40:58 +00:00
|
|
|
return "", err
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
2021-02-17 02:05:18 +00:00
|
|
|
defer os.RemoveAll(tmpDir)
|
2021-02-09 03:23:50 +00:00
|
|
|
|
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-02-09 03:23:50 +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-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize autoupdate metadata
|
|
|
|
|
|
|
|
updateOpt := update.DefaultOptions
|
2022-03-15 19:04:12 +00:00
|
|
|
|
2021-02-09 03:23:50 +00:00
|
|
|
updateOpt.RootDirectory = orbitRoot
|
2021-03-10 22:42:02 +00:00
|
|
|
updateOpt.ServerURL = opt.UpdateURL
|
2022-03-15 19:04:12 +00:00
|
|
|
updateOpt.Targets = update.DarwinTargets
|
|
|
|
|
2022-03-21 17:53:53 +00:00
|
|
|
if opt.Desktop {
|
|
|
|
updateOpt.Targets["desktop"] = update.DesktopMacOSTarget
|
|
|
|
// Override default channel with the provided value.
|
|
|
|
updateOpt.Targets.SetTargetChannel("desktop", opt.DesktopChannel)
|
|
|
|
}
|
|
|
|
|
2022-03-15 19:04:12 +00:00
|
|
|
// Override default channels with the provided values.
|
2022-03-21 17:53:53 +00:00
|
|
|
updateOpt.Targets.SetTargetChannel("orbit", opt.OrbitChannel)
|
|
|
|
updateOpt.Targets.SetTargetChannel("osqueryd", opt.OsquerydChannel)
|
2022-03-15 19:04:12 +00:00
|
|
|
|
2021-03-23 00:38:32 +00:00
|
|
|
if opt.UpdateRoots != "" {
|
|
|
|
updateOpt.RootKeys = opt.UpdateRoots
|
|
|
|
}
|
2021-02-09 03:23:50 +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-02-09 03:23:50 +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-02-09 03:23:50 +00:00
|
|
|
|
2022-05-03 19:46:02 +00:00
|
|
|
if orbitSemVer, err := semver.NewVersion(updatesData.OrbitVersion); err == nil {
|
|
|
|
if orbitSemVer.LessThan(semver.MustParse("0.0.11")) {
|
|
|
|
opt.LegacyVarLibSymlink = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If err != nil we assume non-legacy Orbit.
|
|
|
|
|
2021-02-17 02:05:18 +00:00
|
|
|
// Write files
|
|
|
|
|
|
|
|
if err := writePackageInfo(opt, tmpDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write PackageInfo: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
if err := writeDistribution(opt, tmpDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write Distribution: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
if err := writeScripts(opt, tmpDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write postinstall: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
2021-02-18 00:22:27 +00:00
|
|
|
if err := writeSecret(opt, orbitRoot); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write enroll secret: %w", err)
|
2021-02-18 00:22:27 +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-02-17 02:05:18 +00:00
|
|
|
if opt.StartService {
|
2022-05-02 18:18:59 +00:00
|
|
|
if err := writeLaunchd(opt, rootDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write launchd: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-25 20:38:21 +00:00
|
|
|
if opt.FleetCertificate != "" {
|
|
|
|
if err := writeCertificate(opt, orbitRoot); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("write fleet certificate: %w", err)
|
2021-02-25 20:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-02 19:24:32 +00:00
|
|
|
|
2021-02-09 03:23:50 +00:00
|
|
|
// Build package
|
2021-03-09 23:22:17 +00:00
|
|
|
|
2021-02-09 03:23:50 +00:00
|
|
|
if err := xarBom(opt, tmpDir); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("build pkg: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
2021-02-17 21:25:56 +00:00
|
|
|
generatedPath := filepath.Join(tmpDir, "orbit.pkg")
|
|
|
|
|
|
|
|
if len(opt.SignIdentity) != 0 {
|
|
|
|
log.Info().Str("identity", opt.SignIdentity).Msg("productsign package")
|
|
|
|
if err := signPkg(generatedPath, opt.SignIdentity); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("productsign: %w", err)
|
2021-02-17 21:25:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-18 00:22:03 +00:00
|
|
|
if opt.Notarize {
|
2022-03-21 22:01:50 +00:00
|
|
|
if err := NotarizeStaple(generatedPath, "com.fleetdm.orbit"); err != nil {
|
2021-11-15 13:40:58 +00:00
|
|
|
return "", err
|
2021-02-18 00:22:03 +00:00
|
|
|
}
|
2021-02-17 21:25:56 +00:00
|
|
|
}
|
|
|
|
|
2021-11-19 01:43:52 +00:00
|
|
|
filename := "fleet-osquery.pkg"
|
2022-07-11 12:49:13 +00:00
|
|
|
if opt.NativeTooling {
|
|
|
|
filename = filepath.Join("build", filename)
|
|
|
|
}
|
2021-11-15 18:01:48 +00:00
|
|
|
if err := file.Copy(generatedPath, filename, constant.DefaultFileMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return "", fmt.Errorf("rename pkg: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
log.Info().Str("path", filename).Msg("wrote pkg package")
|
|
|
|
|
2021-11-15 13:40:58 +00:00
|
|
|
return filename, nil
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func writePackageInfo(opt Options, rootPath string) error {
|
2021-02-17 02:05:18 +00:00
|
|
|
// PackageInfo is metadata for the pkg
|
2021-02-09 03:23:50 +00:00
|
|
|
path := filepath.Join(rootPath, "flat", "base.pkg", "PackageInfo")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("mkdir: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
if err := macosPackageInfoTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-17 02:05:18 +00:00
|
|
|
func writeScripts(opt Options, rootPath string) error {
|
|
|
|
// Postinstall script
|
|
|
|
path := filepath.Join(rootPath, "scripts", "postinstall")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("mkdir: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
if err := macosPostinstallTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 17:53:53 +00:00
|
|
|
if err := ioutil.WriteFile(path, contents.Bytes(), 0o744); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-02-18 00:22:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-17 02:05:18 +00:00
|
|
|
func writeLaunchd(opt Options, rootPath string) error {
|
|
|
|
// launchd is the service mechanism on macOS
|
|
|
|
path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("mkdir: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
if err := macosLaunchdTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
2022-03-21 17:53:53 +00:00
|
|
|
if err := ioutil.WriteFile(path, contents.Bytes(), 0o644); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-09 03:23:50 +00:00
|
|
|
func writeDistribution(opt Options, rootPath string) error {
|
2021-02-17 02:05:18 +00:00
|
|
|
// Distribution file is metadata for the pkg
|
2021-02-09 03:23:50 +00:00
|
|
|
path := filepath.Join(rootPath, "flat", "Distribution")
|
2021-08-11 14:02:22 +00:00
|
|
|
if err := secure.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("mkdir: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var contents bytes.Buffer
|
|
|
|
if err := macosDistributionTemplate.Execute(&contents, opt); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("execute template: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write file: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-25 20:38:21 +00:00
|
|
|
func writeCertificate(opt Options, orbitRoot string) error {
|
|
|
|
// Fleet TLS certificate
|
|
|
|
dstPath := filepath.Join(orbitRoot, "fleet.pem")
|
|
|
|
|
2022-03-21 17:53:53 +00:00
|
|
|
if err := file.Copy(opt.FleetCertificate, dstPath, 0o644); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("write orbit: %w", err)
|
2021-02-25 20:38:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-09 03:23:50 +00:00
|
|
|
// xarBom creates the actual .pkg format. It's a xar archive with a BOM (Bill of
|
|
|
|
// materials?). See http://bomutils.dyndns.org/tutorial.html.
|
|
|
|
func xarBom(opt Options, rootPath string) error {
|
|
|
|
// Adapted from BSD licensed
|
|
|
|
// https://github.com/go-flutter-desktop/hover/blob/v0.46.2/cmd/packaging/darwin-pkg.go
|
|
|
|
|
2021-02-17 02:05:18 +00:00
|
|
|
// Copy payload/scripts
|
|
|
|
if err := cpio(
|
|
|
|
filepath.Join(rootPath, "root"),
|
|
|
|
filepath.Join(rootPath, "flat", "base.pkg", "Payload"),
|
|
|
|
); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("cpio Payload: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
2021-02-17 02:05:18 +00:00
|
|
|
if err := cpio(
|
|
|
|
filepath.Join(rootPath, "scripts"),
|
|
|
|
filepath.Join(rootPath, "flat", "base.pkg", "Scripts"),
|
|
|
|
); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("cpio Scripts: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make bom
|
|
|
|
var cmdMkbom *exec.Cmd
|
2022-07-11 12:49:13 +00:00
|
|
|
var isDarwin = runtime.GOOS == "darwin"
|
|
|
|
var isLinuxNative = runtime.GOOS == "linux" && opt.NativeTooling
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case isDarwin, isLinuxNative:
|
2021-02-09 03:23:50 +00:00
|
|
|
cmdMkbom = exec.Command("mkbom", filepath.Join(rootPath, "root"), filepath.Join("flat", "base.pkg", "Bom"))
|
2021-10-27 23:17:41 +00:00
|
|
|
cmdMkbom.Dir = rootPath
|
|
|
|
default:
|
|
|
|
cmdMkbom = exec.Command(
|
|
|
|
"docker", "run", "--rm", "-v", rootPath+":/root", "fleetdm/bomutils",
|
|
|
|
"mkbom", "-u", "0", "-g", "80",
|
|
|
|
// Use / instead of filepath.Join because these will always be paths within the Docker
|
|
|
|
// container (so Linux file paths)
|
|
|
|
"/root/root", "/root/flat/base.pkg/Bom",
|
|
|
|
)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
2022-07-11 12:49:13 +00:00
|
|
|
|
|
|
|
cmdMkbom.Stdout, cmdMkbom.Stderr = os.Stdout, os.Stderr
|
2021-02-09 03:23:50 +00:00
|
|
|
if err := cmdMkbom.Run(); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("mkbom: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// List files for xar
|
|
|
|
var files []string
|
2021-02-17 21:39:25 +00:00
|
|
|
err := filepath.Walk(
|
|
|
|
filepath.Join(rootPath, "flat"),
|
|
|
|
func(path string, info os.FileInfo, _ error) error {
|
|
|
|
relativePath, err := filepath.Rel(filepath.Join(rootPath, "flat"), path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
files = append(files, relativePath)
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("iterate files: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make xar
|
2021-10-27 23:17:41 +00:00
|
|
|
var cmdXar *exec.Cmd
|
2022-07-11 12:49:13 +00:00
|
|
|
switch {
|
|
|
|
case isDarwin, isLinuxNative:
|
2021-10-27 23:17:41 +00:00
|
|
|
cmdXar = exec.Command("xar", append([]string{"--compression", "none", "-cf", filepath.Join("..", "orbit.pkg")}, files...)...)
|
|
|
|
cmdXar.Dir = filepath.Join(rootPath, "flat")
|
|
|
|
default:
|
|
|
|
cmdXar = exec.Command(
|
|
|
|
"docker", "run", "--rm", "-v", rootPath+":/root", "-w", "/root/flat", "fleetdm/bomutils",
|
|
|
|
"xar",
|
|
|
|
)
|
|
|
|
cmdXar.Args = append(cmdXar.Args, append([]string{"--compression", "none", "-cf", "/root/orbit.pkg"}, files...)...)
|
|
|
|
}
|
2021-02-09 03:23:50 +00:00
|
|
|
|
2022-07-11 12:49:13 +00:00
|
|
|
cmdXar.Stdout, cmdXar.Stderr = os.Stdout, os.Stderr
|
2021-02-09 03:23:50 +00:00
|
|
|
if err := cmdXar.Run(); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("run xar: %w", err)
|
2021-02-09 03:23:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2021-02-17 02:05:18 +00:00
|
|
|
|
|
|
|
func cpio(srcPath, dstPath string) error {
|
|
|
|
// This is the compression routine that is expected for pkg files.
|
2022-03-21 17:53:53 +00:00
|
|
|
dst, err := secure.OpenFile(dstPath, os.O_RDWR|os.O_CREATE, 0o755)
|
2021-02-17 02:05:18 +00:00
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("open dst: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
defer dst.Close()
|
|
|
|
|
|
|
|
cmdFind := exec.Command("find", ".")
|
|
|
|
cmdFind.Dir = srcPath
|
|
|
|
cmdCpio := exec.Command("cpio", "-o", "--format", "odc", "-R", "0:80")
|
|
|
|
cmdCpio.Dir = srcPath
|
|
|
|
cmdGzip := exec.Command("gzip", "-c")
|
|
|
|
|
|
|
|
// Pipes like this: find | cpio | gzip > dstPath
|
|
|
|
cmdCpio.Stdin, err = cmdFind.StdoutPipe()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("pipe cpio: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
cmdGzip.Stdin, err = cmdCpio.StdoutPipe()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("pipe gzip: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
cmdGzip.Stdout = dst
|
|
|
|
|
|
|
|
err = cmdGzip.Start()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("start gzip: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
err = cmdCpio.Start()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("start cpio: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
err = cmdFind.Run()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("run find: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
err = cmdCpio.Wait()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("wait cpio: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
err = cmdGzip.Wait()
|
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("wait gzip: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
2021-08-17 12:41:56 +00:00
|
|
|
err = dst.Sync()
|
2021-02-17 02:05:18 +00:00
|
|
|
if err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("sync dst: %w", err)
|
2021-02-17 02:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2021-02-17 21:25:56 +00:00
|
|
|
|
|
|
|
func signPkg(pkgPath, identity string) error {
|
|
|
|
var outBuf bytes.Buffer
|
|
|
|
cmdProductsign := exec.Command(
|
|
|
|
"productsign",
|
|
|
|
"--sign", identity,
|
|
|
|
pkgPath,
|
|
|
|
pkgPath+".signed",
|
|
|
|
)
|
|
|
|
cmdProductsign.Stdout = &outBuf
|
|
|
|
cmdProductsign.Stderr = &outBuf
|
|
|
|
if err := cmdProductsign.Run(); err != nil {
|
|
|
|
fmt.Println(outBuf.String())
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("productsign: %w", err)
|
2021-02-17 21:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Rename(pkgPath+".signed", pkgPath); err != nil {
|
2021-11-22 14:13:26 +00:00
|
|
|
return fmt.Errorf("rename signed: %w", err)
|
2021-02-17 21:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|