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

API design: Fleet-maintained apps for macOS #21801

Closed
wants to merge 13 commits into from
132 changes: 131 additions & 1 deletion docs/REST API/rest-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8485,6 +8485,9 @@ Deletes the session specified by ID. When the user associated with the session n
- [Add package](#add-package)
- [List App Store apps](#list-app-store-apps)
- [Add App Store app](#add-app-store-app)
- [List Fleet-maintained apps](#list-fleet-maintained-apps)
- [Get Fleet-maintained app](#get-fleet-maintained-app)
- [Add Fleet-maintained app](#add-fleet-maintained-app)
- [Install package or App Store app](#install-package-or-app-store-app)
- [Get package install result](#get-package-install-result)
- [Download package](#download-package)
Expand Down Expand Up @@ -9122,7 +9125,7 @@ Add App Store (VPP) app purchased in Apple Business Manager.

#### Example

`POST /api/v1/fleet/software/app_store_apps?team_id=3`
`POST /api/v1/fleet/software/app_store_apps`

##### Request body

Expand All @@ -9138,6 +9141,133 @@ Add App Store (VPP) app purchased in Apple Business Manager.

`Status: 200`

### List Fleet-maintained apps

> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.
marko-lisica marked this conversation as resolved.
Show resolved Hide resolved

List available Fleet-maintained apps.

`GET /api/v1/fleet/software/fleet_maintained_apps`

#### Parameters

| Name | Type | In | Description |
| ---- | ---- | -- | ----------- |
| team_id | integer | query | **Required**. The team ID. Filters Fleet-maintained apps to only include apps available for the specified team. |
marko-lisica marked this conversation as resolved.
Show resolved Hide resolved

#### Example

`GET /api/v1/fleet/software/fleet_maintained_apps?team_id=3`


##### Default response

`Status: 200`

```json
{
marko-lisica marked this conversation as resolved.
Show resolved Hide resolved
"fleet_maintained_apps": [
{
"id": "1",
"name": "1Password",
"version": "8.10.40",
"platform": "darwin"
},
{
"id": "2",
"name": "Adobe Acrobat Reader",
"version": "24.002.21005",
"platform": "darwin"
},
{
"id": "3",
"name": "Box Drive",
"version": "2.39.179",
"platform": "darwin"
},
],
"meta": {
"has_next_results": false,
"has_previous_results": false
}
}
```

### Get Fleet-maintained app

> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.

Returns information about the specified Fleet-maintained app.

`GET /api/v1/fleet/software/fleet_maintained_apps/:id`

#### Parameters

| Name | Type | In | Description |
| ---- | ---- | -- | ----------- |
| id | integer | path | **Required.** The Fleet-maintained app's ID. |


#### Example

`GET /api/v1/fleet/software/fleet_maintained_apps/1`

##### Default response

`Status: 200`

```json
{
"fleet_maintained_app": {
"id": 1,
"name": "1Password",
"file_name": "1Password-8.10.44-aarch64.zip",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica The filename seems to be the installer's filename from this example. We don't have this info explicitly in the brew API, should I fill this with just the last section of the installer's URL? In most case this would give a sensible filename like what you have here, but for some apps (like WhatsApp: https://web.whatsapp.com/desktop/mac_native/release/?version=2.24.16.80&extension=zip&configuration=Release&branch=relbranch), the filename would end up a bit weird (in this case, the last path segment is release, and for VSCode it would be stable).

(side-note: I think this should be called filename without underscore? We have some API parameters that accept a filename and we use filename - or at least that's the field name for the name of the file in uploads)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mna, is there any other way to retrieve filename? Could we make it if the URL doesn't end with extensions like: .dmg, .zip, .pkg, etc. then Fleet tries to download a file to get the name? Is that too complex? I think having release or stable as filename could be confusing.

I agree, we should be consistent and use filename without _. I'll update PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot download it at the time we process the brew metadata, as this cron job only calls the JSON API, it does not start downloading the installers (we do this only when adding the maintained app to a team).

I'm curious though - what is the purpose of that field besides a light (non-critical) piece of information? Given a URL like WhatsApp , the filename of the installer could be whatever we want it to be (i.e. this is just a URL that sends some bytes, we can save those bytes under whatever filename we want). I'm thinking we could just generate a filename from the app name and installer type in this case (e.g. "whatsapp.dmg").

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mna I think I added it so users understand what will be added to Fleet. Is it .pkg, .dmg, or something else. They'll see the $INSTALLER_PATH variable in the install script, it will help understand what's behind that variable.

Since you brought this up, I think we should probably remove it or convey information that the installer will be downloaded and uploaded to Fleet server in a different way. I'm going to bring this to design review today for expedited drafting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it so users understand what will be added to Fleet. Is it .pkg, .dmg, or something else. They'll see the $INSTALLER_PATH variable in the install script, it will help understand what's behind that variable.

Gotcha, makes sense.

I'm going to bring this to design review today for expedited drafting.

Sounds good, not a blocker for the moment but of course the sooner we can clarify, the better. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica correct, yes we (will) have a JSON file that describes the list of maintained apps, (e.g. it contains the "brew identifier" - the part to use in the API call e.g. 1password in https://formulae.brew.sh/api/cask/1password.json), the bundle identifier associated with this app (since we can't get it from brew) and the "installer format" which is an arbitrary string that defines how the installer is bundled, and comes from your research in the google doc (e.g. "dmg:app"). At least that's the plan at the moment, see

.

Maybe we could add the filename as part of this hard-coded JSON file? Only thing is if we want to include the version as part of the filename, that part is dynamic (we could make the filename some kind of template string that we fill with brew data). But that's a possibility!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that we'd hardcode installer_format, but it makes sense.

Maybe we could add the filename as part of this hard-coded JSON file? Only thing is if we want to include the version as part of the filename, that part is dynamic (we could make the filename some kind of template string that we fill with brew data). But that's a possibility!

Could we simplify that, so filename is optional in this apps.json, and we provide it only for apps that have "weird" URLs (WhatsApp and VS Code)? Since we'll be defining apps that will appear in the Fleet-maintained tab, and we committed that we'll test it the first time to make sure, install/uninstall scripts work, we can do that as part of the process of adding new apps.

I think if we want accurate name we'll need it dynamic (template string that we fill with brew data)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we simplify that, so filename is optional in this apps.json, and we provide it only for apps that have "weird" URLs (WhatsApp and VS Code)?

Absolutely! Makes sense to me.

I think if we want accurate name we'll need it dynamic (template string that we fill with brew data)

Allright, so we want the version in there and the extension to reflect its format, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mna We decided to cut filename and use name instead. See Figma here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica sounds good, thanks!

"version": "8.10.40",
"platform": "darwin",
"install_script": "#!/bin/sh\ninstaller -pkg \"$INSTALLER_PATH\" -target /",
"uninstall_script": "#!/bin/sh\npkg_ids=$PACKAGE_ID\nfor pkg_id in '${pkg_ids[@]}'...",
}
}
```

### Add Fleet-maintained app

> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.

_Available in Fleet Premium._

Add Fleet-maintained app so it's available for install.

`POST /api/v1/fleet/software/fleet_maintained`

#### Parameters

| Name | Type | In | Description |
| ---- | ---- | -- | ----------- |
| fleet_maintained_app_id | string | body | **Required.** The ID of Fleet-maintained app. |
marko-lisica marked this conversation as resolved.
Show resolved Hide resolved
| team_id | integer | body | **Required**. The team ID. Adds Fleet-maintained app to the specified team. |
| install_script | string | form | Command that Fleet runs to install software. If not specified Fleet runs default install command for each Fleet-maintained app. |
| pre_install_query | string | form | Query that is pre-install condition. If the query doesn't return any result, Fleet won't proceed to install. |
| post_install_script | string | form | The contents of the script to run after install. If the specified script fails (exit code non-zero) software install will be marked as failed and rolled back. |
| self_service | boolean | form | Self-service software is optional and can be installed by the end user. |

#### Example

`POST /api/v1/fleet/software/fleet_maintained`

##### Request body

```json
{
"fleet_maintained_app_id": "3",
"team_id": 2,
}
```

##### Default response

`Status: 200`

### Download package

> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.
Expand Down
Loading