Skip to content

Commit

Permalink
fma missing pieces
Browse files Browse the repository at this point in the history
  • Loading branch information
roperzh committed Oct 3, 2024
1 parent 3727474 commit 669d68f
Show file tree
Hide file tree
Showing 51 changed files with 2,737 additions and 23 deletions.
30 changes: 29 additions & 1 deletion ee/server/service/maintained_apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,27 @@ import (
"context"
"crypto/sha256"
"encoding/hex"
"net/url"
"os"
"path/filepath"
"strings"
"time"

"github.com/fleetdm/fleet/v4/pkg/file"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/maintainedapps"
)

func (svc *Service) AddFleetMaintainedApp(ctx context.Context, teamID *uint, appID uint, installScript, preInstallQuery, postInstallScript string, selfService bool) error {
func (svc *Service) AddFleetMaintainedApp(
ctx context.Context,
teamID *uint,
appID uint,
installScript, preInstallQuery, postInstallScript, uninstallScript string,
selfService bool,
) error {
if err := svc.authz.Authorize(ctx, &fleet.SoftwareInstaller{TeamID: teamID}, fleet.ActionWrite); err != nil {
return err
}
Expand Down Expand Up @@ -59,6 +69,21 @@ func (svc *Service) AddFleetMaintainedApp(ctx context.Context, teamID *uint, app
filename = app.Name
}

installScript = file.Dos2UnixNewlines(installScript)
if installScript == "" {
installScript = app.InstallScript
}

uninstallScript = file.Dos2UnixNewlines(uninstallScript)
if uninstallScript == "" {
uninstallScript = app.UninstallScript
}

installerURL, err := url.Parse(app.InstallerURL)
if err != nil {
return err
}

installerReader := bytes.NewReader(installerBytes)
payload := &fleet.UploadSoftwareInstallerPayload{
InstallerFile: installerReader,
Expand All @@ -68,13 +93,16 @@ func (svc *Service) AddFleetMaintainedApp(ctx context.Context, teamID *uint, app
Version: app.Version,
Filename: filename,
Platform: string(app.Platform),
Source: "apps",
Extension: strings.TrimPrefix(filepath.Ext(installerURL.Path), "."),
BundleIdentifier: app.BundleIdentifier,
StorageID: app.SHA256,
FleetLibraryAppID: &app.ID,
PreInstallQuery: preInstallQuery,
PostInstallScript: postInstallScript,
SelfService: selfService,
InstallScript: installScript,
UninstallScript: uninstallScript,
}

// Create record in software installers table
Expand Down
4 changes: 3 additions & 1 deletion ee/server/service/software_installers.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func preProcessUninstallScript(payload *fleet.UploadSoftwareInstallerPayload) {
// Replace $PACKAGE_ID in the uninstall script with the package ID(s).
var packageID string
switch payload.Extension {
case "dmg", "zip":
return
case "pkg":
var sb strings.Builder
_, _ = sb.WriteString("(\n")
Expand Down Expand Up @@ -1515,7 +1517,7 @@ func packageExtensionToPlatform(ext string) string {
switch ext {
case ".msi", ".exe":
requiredPlatform = "windows"
case ".pkg":
case ".pkg", ".dmg", ".zip":
requiredPlatform = "darwin"
case ".deb", ".rpm":
requiredPlatform = "linux"
Expand Down
15 changes: 13 additions & 2 deletions frontend/interfaces/package_type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const unixPackageTypes = ["pkg", "deb", "rpm"] as const;
const fleetMaintainedPackageTypes = ["dmg", "zip"] as const;
const unixPackageTypes = ["pkg", "deb", "rpm", "dmg", "zip"] as const;
const windowsPackageTypes = ["msi", "exe"] as const;
export const packageTypes = [
...unixPackageTypes,
Expand All @@ -7,7 +8,11 @@ export const packageTypes = [

export type WindowsPackageType = typeof windowsPackageTypes[number];
export type UnixPackageType = typeof unixPackageTypes[number];
export type PackageType = WindowsPackageType | UnixPackageType;
export type FleetMaintainedPackageType = typeof fleetMaintainedPackageTypes[number];
export type PackageType =
| WindowsPackageType
| UnixPackageType
| FleetMaintainedPackageType;

export const isWindowsPackageType = (s: any): s is WindowsPackageType => {
return windowsPackageTypes.includes(s);
Expand All @@ -17,6 +22,12 @@ export const isUnixPackageType = (s: any): s is UnixPackageType => {
return unixPackageTypes.includes(s);
};

export const isFleetMaintainedPackageType = (
s: any
): s is FleetMaintainedPackageType => {
return fleetMaintainedPackageTypes.includes(s);
};

export const isPackageType = (s: any): s is PackageType => {
return packageTypes.includes(s);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
import {
isPackageType,
isWindowsPackageType,
isFleetMaintainedPackageType,
PackageType,
} from "interfaces/package_type";

Expand Down Expand Up @@ -46,6 +47,10 @@ const getPostInstallHelpText = (pkgType: PackageType) => {
};

const getUninstallHelpText = (pkgType: PackageType) => {
if (isFleetMaintainedPackageType(pkgType)) {
return "Currently, shell scripts are supported";
}

return (
<>
$PACKAGE_ID will be populated with the {PKG_TYPE_TO_ID_TEXT[pkgType]} from
Expand Down
2 changes: 2 additions & 0 deletions frontend/services/entities/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ interface IAddFleetMaintainedAppPostBody {
pre_install_query?: string;
install_script?: string;
post_install_script?: string;
uninstall_script?: string;
self_service?: boolean;
}

Expand Down Expand Up @@ -376,6 +377,7 @@ export default {
pre_install_query: formData.preInstallQuery,
install_script: formData.installScript,
post_install_script: formData.postInstallScript,
uninstall_script: formData.uninstallScript,
self_service: formData.selfService,
};

Expand Down
4 changes: 2 additions & 2 deletions server/datastore/mysql/maintained_apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ WHERE NOT EXISTS (
WHERE
st.bundle_identifier = fla.bundle_identifier
AND (
(si.platform = fla.platform AND si.team_id = ?)
(si.platform = fla.platform AND si.global_or_team_id = ?)
OR
(va.platform = fla.platform AND vat.team_id = ?)
(va.platform = fla.platform AND vat.global_or_team_id = ?)
)
)`

Expand Down
2 changes: 1 addition & 1 deletion server/fleet/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ type Service interface {
// Fleet-maintained apps

// AddFleetMaintainedApp adds a Fleet-maintained app to the given team.
AddFleetMaintainedApp(ctx context.Context, teamID *uint, appID uint, installScript, preInstallQuery, postInstallScript string, selfService bool) error
AddFleetMaintainedApp(ctx context.Context, teamID *uint, appID uint, installScript, preInstallQuery, postInstallScript, uninstallScript string, selfService bool) error
// ListFleetMaintainedApps lists Fleet-maintained apps available to a specific team
ListFleetMaintainedApps(ctx context.Context, teamID uint, opts ListOptions) ([]MaintainedApp, *PaginationMetadata, error)
// GetFleetMaintainedApp returns a Fleet-maintained app by ID
Expand Down
40 changes: 26 additions & 14 deletions server/mdm/maintainedapps/ingest.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ func (i ingester) ingestOne(ctx context.Context, app maintainedApp, client *http
return ctxerr.Wrapf(ctx, err, "parse URL for cask %s", app.Identifier)
}

installScript := installScriptForApp(app, &cask)
uninstallScript := uninstallScriptForApp(app, &cask)
installScript, err := installScriptForApp(app, &cask)
if err != nil {
return ctxerr.Wrapf(ctx, err, "create install script for cask %s", app.Identifier)
}
uninstallScript := uninstallScriptForApp(&cask)

_, err = i.ds.UpsertMaintainedApp(ctx, &fleet.MaintainedApp{
Name: cask.Name[0],
Expand All @@ -155,16 +158,6 @@ func (i ingester) ingestOne(ctx context.Context, app maintainedApp, client *http
return ctxerr.Wrap(ctx, err, "upsert maintained app")
}

func installScriptForApp(app maintainedApp, cask *brewCask) string {
// TODO: implement install script based on cask and app installer format
return "install"
}

func uninstallScriptForApp(app maintainedApp, cask *brewCask) string {
// TODO: implement uninstall script based on cask and app installer format
return "uninstall"
}

type brewCask struct {
Token string `json:"token"`
FullToken string `json:"full_token"`
Expand Down Expand Up @@ -195,9 +188,28 @@ type brewArtifact struct {
Binary []optjson.StringOr[*brewBinaryTarget] `json:"binary"`
}

// The choiceChanges file is a property list containing an array of dictionaries. Each dictionary has the following three keys:
//
// Key Description
// choiceIdentifier Identifier for the choice to be modified (string)
// choiceAttribute One of the attribute names described below (string)
// attributeSetting A setting that depends on the choiceAttribute, described below (number or string)
//
// The choiceAttribute and attributeSetting values are as follows:
//
// choiceAttribute attributeSetting Description
// selected (number) 1 to select the choice, 0 to deselect it
// enabled (number) 1 to enable the choice, 0 to disable it
// visible (number) 1 to show the choice, 0 to hide it
// customLocation (string) path at which to install the choice (see below)
type brewPkgConfig struct {
ChoiceIdentifier string `json:"choiceIdentifier" plist:"choiceIdentifier"`
ChoiceAttribute string `json:"choiceAttribute" plist:"choiceAttribute"`
AttributeSetting int `json:"attributeSetting" plist:"attributeSetting"`
}

type brewPkgChoices struct {
// At the moment we don't care about the "choices" field on the pkg.
Choices []any `json:"choices"`
Choices []brewPkgConfig `json:"choices"`
}

type brewBinaryTarget struct {
Expand Down
Loading

0 comments on commit 669d68f

Please sign in to comment.