Merge remote-tracking branch 'origin/main' into feat-software-installers
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Deploy Fleet on AWS ECS
|
||||
|
||||
> **This article was archived on May 15, 2024** and may be out of date. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
@@ -30,7 +30,7 @@ Alternatively you can bake the prepare command into the same task definition see
|
||||
<meta name="articleTitle" value="Deploy Fleet on AWS ECS">
|
||||
<meta name="authorGitHubUsername" value="edwardsb">
|
||||
<meta name="authorFullName" value="Ben Edwards">
|
||||
<meta name="publishedOn" value="2022-02-14">
|
||||
<meta name="publishedOn" value="2021-10-06">
|
||||
<meta name="category" value="guides">
|
||||
<meta name="articleImageUrl" value="../website/assets/images/articles/deploy-fleet-on-aws-ecs-800x450@2x.png">
|
||||
<meta name="description" value="Information for deploying Fleet on AWS ECS.">
|
||||
@@ -1,13 +1,13 @@
|
||||
# Deploy Fleet on AWS with Terraform
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
Learn how to deploy Fleet on AWS with Terraform IaC (infrastructure as code).
|
||||
|
||||
Deploying on AWS with Fleet’s reference architecture is an easy way to get a fully functional Fleet instance that can scale to your needs.
|
||||
|
||||
> Updated May 2023 to reflect Fleet's current Terraform Module setup.
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
- AWS CLI installed and configured.
|
||||
@@ -23,8 +23,7 @@ Remote state can be simple (local state) or complicated (S3, state locking, etc.
|
||||
|
||||
### Modules
|
||||
|
||||
[Fleet terraform](https://github.com/fleetdm/fleet/tree/main/terraform) is made up of multiple modules. These modules can be used independently, or as group to stand up an opinionated
|
||||
set of infrastructure that we have found success with.
|
||||
[Fleet terraform](https://github.com/fleetdm/fleet/tree/main/terraform) is made up of multiple modules. These modules can be used independently, or as group to stand up an opinionated set of infrastructure that we have found success with.
|
||||
|
||||
Each module defines the required resource and consumes the next nested module. The root module creates the VPC and then pulls in the `byo-vpc` module configuring it as necessary. The `byo-vpc` module creates the database and cache instances that get passed into the `byo-db` module. And finally the `byo-db` module creates the ECS cluster and load balancer to be consumed by the `byo-ecs` module.
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
# Deploy Fleet on CentOS
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
> Updated on December 2, 2020, by [Noah Talerman](https://github.com/noahtalerman).
|
||||
|
||||
In this guide, we're going to install Fleet and all of its application dependencies on a CentOS 7.1 server. Once we have Fleet up and running, we're going to install osquery on that same CentOS 7.1 host and enroll it in Fleet. This should give you a good understanding of both how to install Fleet as well as how to install and configure osquery such that it can communicate with Fleet.
|
||||
|
||||
## Setting up a host
|
||||
@@ -219,7 +223,7 @@ If you go back to [https://localhost:8080/hosts/manage](https://localhost:8080/h
|
||||
<meta name="articleTitle" value="Deploy Fleet on CentOS">
|
||||
<meta name="authorGitHubUsername" value="marpaia">
|
||||
<meta name="authorFullName" value="Mike Arpaia">
|
||||
<meta name="publishedOn" value="2022-06-27">
|
||||
<meta name="publishedOn" value="2017-09-22">
|
||||
<meta name="category" value="guides">
|
||||
<meta name="articleImageUrl" value="../website/assets/images/articles/deploy-fleet-on-centos-800x450@2x.png">
|
||||
<meta name="description" value="A guide to deploy Fleet on CentOS.">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Deploy Fleet on Cloud.gov (Cloud Foundry)
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
Cloud.gov is a [FEDRAMP moderate Platform-as-a-Service
|
||||
@@ -115,7 +117,7 @@ variables](https://fleetdm.com/docs/deploying/configuration#using-only-environme
|
||||
<meta name="articleTitle" value="Deploy Fleet on Cloud.gov">
|
||||
<meta name="authorGitHubUsername" value="JJediny">
|
||||
<meta name="authorFullName" value="John Jediny">
|
||||
<meta name="publishedOn" value="2022-04-24">
|
||||
<meta name="publishedOn" value="2022-09-08">
|
||||
<meta name="category" value="guides">
|
||||
<meta name="articleImageUrl" value="../website/assets/images/articles/deploy-fleet-on-cloudgov-800x450@2x.png">
|
||||
<meta name="description" value="Information for deploying Fleet on Cloud.gov.">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Deploy Fleet on Hetzner Cloud
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
Learn how to deploy Fleet on Hetzner Cloud using cloud-init and Docker. [Hetzner](https://hetzner.com) is a great price-performance provider for “root” (dedicated) and Virtual Private Servers (VPS), offering high performance and generous bandwidth.
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
# Deploy Fleet on Kubernetes
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
> Updated on May 10, 2022, by [Kelvin Oghenerhoro Omereshone](https://github.com/DominusKelvin).
|
||||
|
||||
In this guide, we will focus on deploying Fleet only on a Kubernetes cluster. Kubernetes is a container orchestration tool that was open sourced by Google in 2014.
|
||||
|
||||
There are 2 primary ways to deploy the Fleet server to a Kubernetes cluster. The first is via `kubectl` with a `deployment.yml` file. The second is using Helm, the Kubernetes Package Manager.
|
||||
@@ -194,7 +198,7 @@ Once you have the public IP address for the load balancer, create an A record in
|
||||
<meta name="articleTitle" value="Deploy Fleet on Kubernetes">
|
||||
<meta name="authorGitHubUsername" value="marpaia">
|
||||
<meta name="authorFullName" value="Mike Arpaia">
|
||||
<meta name="publishedOn" value="2022-05-10">
|
||||
<meta name="publishedOn" value="2017-11-18">
|
||||
<meta name="category" value="guides">
|
||||
<meta name="articleImageUrl" value="../website/assets/images/articles/deploy-fleet-on-kubernetes-800x450@2x.png">
|
||||
<meta name="description" value="Learn how to deploy Fleet on Kubernetes.">
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Deploy Fleet on Render
|
||||
|
||||
> **This article was archived on May 16, 2024,** and may be outdated. Check out [Deploy Fleet](https://fleetdm.com/docs/deploy/deploy-fleet) for our recommended deployment method.
|
||||
|
||||

|
||||
|
||||
> Updated May 2024 to reflect Fleet's recommended Render deployment.
|
||||
|
||||
[Render](https://render.com/) is a cloud hosting service that makes it easy to get up and running fast, without the typical configuration headaches of larger enterprise hosting providers. Our Render blueprint offers a one-click deploy of Fleet in under five minutes, and provides a scalable cloud environment with a lower barrier to entry, making it a great place to get some experience with [Fleet](https://fleetdm.com/) and [osquery](https://osquery.io/).
|
||||
|
||||
With one click, our Render blueprint will provision a Fleet web service, a MySQL database, and a Redis in-memory data store. Each service requires Render's `standard` plan at a cost of $7/mo each, totaling $21/mo to host your Fleet instance. If you prefer to follow a video, you can [watch us demonstrating the Render deployment process](https://www.loom.com/share/9373fb6bab2c43aa91949490ceb2678c?sid=081d70de-d736-4681-8107-2d80ec525235).
|
||||
With one click, our Render blueprint will provision a Fleet web service, a MySQL database, and a Redis in-memory data store. Each service requires Render's `standard` plan at a cost of $7/mo each, totaling $21/mo to host your Fleet instance. If you prefer to follow a video, you can [watch us demonstrating the Render deployment process](https://youtu.be/hly0tAOqveA).
|
||||
|
||||
## Deployment steps
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
- Fix a bug where a singular software version in the Software table generated a tooltip unnecessarily.
|
||||
@@ -0,0 +1 @@
|
||||
- Sort the host details page queries table case-insensitively.
|
||||
@@ -6,8 +6,8 @@ Deploy on Render for an easy one-click POC. Or, choose AWS with Terraform to dep
|
||||
<a href="#render">
|
||||
<div>
|
||||
<img src="/images/docs/render-logo-147x80@2x.png">
|
||||
<p>One click deploy</p>
|
||||
<span>Deploy on render in 5 minutes</span>
|
||||
<p>One-click deploy</p>
|
||||
<span>Deploy on Render in 5 minutes</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#aws">
|
||||
@@ -31,14 +31,14 @@ Render is a cloud hosting service that makes it easy to get up and running fast,
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Prerequisites</h2>
|
||||
### Prerequisites
|
||||
|
||||
- A Render account with payment information.
|
||||
|
||||
>The Fleet Render Blueprint will provision a web service, a MySQL database, and a Redis in-memory data store. Each service requires Render's standard plan at a cost of **$7/month** each, totaling **$21/month**.
|
||||
|
||||
|
||||
<h2>Instructions</h2>
|
||||
### Instructions
|
||||
|
||||
1. [Click here](https://render.com/deploy?repo=https://github.com/fleetdm/fleet) to open the Fleet Blueprint on Render. You will be prompted to create or log in to your Render account with associated payment information.
|
||||
|
||||
@@ -60,7 +60,7 @@ The simplest way to get started with Fleet at scale is to use AWS with Terraform
|
||||
|
||||
This workflow takes about 30 minutes to complete and supports between 10 and 350,000 hosts.
|
||||
|
||||
<h2>Prerequisites</h2>
|
||||
### Prerequisites
|
||||
|
||||
- A new or existing Amazon Web Services (AWS) account
|
||||
|
||||
@@ -72,7 +72,7 @@ This workflow takes about 30 minutes to complete and supports between 10 and 350
|
||||
|
||||
- A Fully-Qualified Domain Name (FQDN) for hosting Fleet
|
||||
|
||||
<h2>Instructions</h2>
|
||||
### Instructions
|
||||
|
||||
1. [Download](https://github.com/fleetdm/fleet/blob/main/terraform/example/main.tf) the Fleet `main.tf` Terraform file.
|
||||
|
||||
@@ -137,4 +137,4 @@ This workflow takes about 30 minutes to complete and supports between 10 and 350
|
||||
12. That’s it! You should now be able to log in to Fleet and [enroll a host](https://fleetdm.com/docs/using-fleet/enroll-hosts).
|
||||
|
||||
<meta name="pageOrderInSection" value="100">
|
||||
<meta name="description" value="Learn how to easily deploy Fleet on Render or AWS with Terraform.">
|
||||
<meta name="description" value="Learn how to easily deploy Fleet on Render or AWS with Terraform.">
|
||||
@@ -22,10 +22,11 @@ If a table is not available for your host, Fleet will generally handle things be
|
||||
Fleet's agent (fleetd) generated for MacOS by `fleetctl package` does not include native support for M1 Macs. Some values returned may reflect the information returned by Rosetta rather than the system. For example, a CPU will show up as `i486`.
|
||||
|
||||
### Linux
|
||||
Fleet's agent (fleetd) will run on Linux distributions where `glibc` is >= 2.2 (there is ongoing work to make osquery work with `glibc` 2.12+).
|
||||
If you aren't sure what version of `glibc` your distribution is using, [DistroWatch](https://distrowatch.com/) is a great resource.
|
||||
|
||||
> On Linux, Fleet Desktop only supports $DISPLAY `:0`.
|
||||
> Ubuntu Linux:
|
||||
> Fleet Desktop currently supports Xorg as X11 server, Wayland is currently not supported.
|
||||
> Ubuntu 24.04 comes with Wayland enabled by default. To use X11 instead of Wayland you can set
|
||||
> `WaylandEnable=false` in `/etc/gdm3/custom.conf` and reboot.
|
||||
|
||||
> Fedora, CentOS 8 and 9 require a [gnome extension](https://extensions.gnome.org/extension/615/appindicator-support/) and Google Chrome set to the default browser for Fleet Desktop.
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Fleet detects vulnerabilities for these software types:
|
||||
| Apps | ✅ | ✅ | ❌ |
|
||||
| Browser plugins | Chrome extensions, Firefox extensions | Chrome extensions, Firefox extensions | ❌ |
|
||||
| Packages | Python, Homebrew | Python, Atom, Chocolatey | Adhere to whatever is defined in the [OVAL definitions](https://github.com/fleetdm/nvd/blob/master/oval_sources.json), except for kernel vulnerabilities and vulnerabilities involving configuration files. Supported distributions: <ul><li>Ubuntu</li><li>RHEL based distros (Red Hat, CentOS, Fedora, and Amazon Linux)</li></ul> |
|
||||
| IDE extensions | VS Code extensions | VS Code extensions | VS Code extensions |
|
||||
|
||||
As of right now, only app names with all ASCII characters are supported. Apps with names featuring non-ASCII characters, such as Cyrillic, will not generate matches.
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ import { IconNames } from "components/icons";
|
||||
// @ts-ignore
|
||||
import InputFieldWithIcon from "../InputFieldWithIcon";
|
||||
|
||||
const baseClass = "search-field";
|
||||
|
||||
export interface ISearchFieldProps {
|
||||
placeholder: string;
|
||||
defaultValue?: string;
|
||||
@@ -37,7 +35,6 @@ const SearchField = ({
|
||||
name={icon}
|
||||
placeholder={placeholder}
|
||||
value={searchQueryInput}
|
||||
// inputWrapperClass={`${baseClass}__input-wrapper`}
|
||||
onChange={onInputChange}
|
||||
onClick={onClick}
|
||||
iconPosition="start"
|
||||
|
||||
@@ -11,6 +11,7 @@ should be discussed within the team and documented before merged.
|
||||
- [Typing](#typing)
|
||||
- [Utilities](#utilities)
|
||||
- [Components](#components)
|
||||
- [Forms] (#forms)
|
||||
- [React hooks](#react-hooks)
|
||||
- [React Context](#react-context)
|
||||
- [Fleet API calls](#fleet-api-calls)
|
||||
@@ -194,11 +195,30 @@ const PackComposerPage = ({ router }: IPackComposerPageProps): JSX.Element => {
|
||||
export default PackComposerPage;
|
||||
```
|
||||
|
||||
|
||||
## Forms
|
||||
|
||||
### Data validation
|
||||
|
||||
Forms should make use of a pure `validate` function whose input(s) correspond to form data (may include
|
||||
new and possibly former form data) and whose output is an object of formFieldName:errorMessage
|
||||
key-value pairs (`Record<string,string>`) e.g.
|
||||
|
||||
```
|
||||
const validate = (newFormData: IFormData) => {
|
||||
const errors = {};
|
||||
...
|
||||
return errors;
|
||||
}
|
||||
```
|
||||
The output of `validate` should be used by the calling `onChange` handler to set a `formErrors`
|
||||
state.
|
||||
|
||||
## React hooks
|
||||
|
||||
[Hooks](https://reactjs.org/docs/hooks-intro.html) are used to track state and use other features
|
||||
of React. Hooks are only allowed in functional components, which are created like so:
|
||||
|
||||
|
||||
```typescript
|
||||
import React, { useState, useEffect } from "React";
|
||||
|
||||
|
||||
@@ -44,14 +44,14 @@ interface IVersionCellProps<T extends { version: string }> {
|
||||
const VersionCell = <T extends { version: string }>({
|
||||
versions,
|
||||
}: IVersionCellProps<T>) => {
|
||||
const tooltipId = uniqueId();
|
||||
|
||||
// only one version, no need for tooltip
|
||||
const cellText = generateText(versions);
|
||||
if (!versions || versions.length <= 1) {
|
||||
return <>{cellText}</>;
|
||||
}
|
||||
|
||||
const tooltipId = uniqueId();
|
||||
|
||||
const versionTooltip = generateTooltip(versions, tooltipId);
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -50,6 +50,7 @@ interface IDataColumn {
|
||||
| ((props: IPerformanceImpactCell) => JSX.Element);
|
||||
disableHidden?: boolean;
|
||||
disableSortBy?: boolean;
|
||||
sortType?: string;
|
||||
}
|
||||
|
||||
// NOTE: cellProps come from react-table
|
||||
@@ -66,6 +67,7 @@ const generateColumnConfigs = (
|
||||
Cell: (cellProps: ICellProps) => (
|
||||
<TextCell value={cellProps.cell.value} />
|
||||
),
|
||||
sortType: "caseInsensitive",
|
||||
},
|
||||
{
|
||||
Header: () => {
|
||||
|
||||
-20
@@ -160,26 +160,6 @@ const generateTableHeaders = ({
|
||||
Observers can run this query.
|
||||
</ReactTooltip5>
|
||||
</div>
|
||||
|
||||
// <>
|
||||
// <span
|
||||
// className="tooltip-base"
|
||||
// data-tip
|
||||
// data-for={`observer-can-run-tooltip-${cellProps.row.original.id}`}
|
||||
// >
|
||||
// <Icon className="query-icon" name="query" size="small" />
|
||||
// </span>
|
||||
// <ReactTooltip
|
||||
// className="observer-can-run-tooltip"
|
||||
// place="top"
|
||||
// type="dark"
|
||||
// effect="solid"
|
||||
// id={`observer-can-run-tooltip-${cellProps.row.original.id}`}
|
||||
// backgroundColor={COLORS["tooltip-bg"]}
|
||||
// >
|
||||
// Observers can run this query.
|
||||
// </ReactTooltip>
|
||||
// </>
|
||||
)}
|
||||
{viewingTeamScope &&
|
||||
// inherited
|
||||
|
||||
@@ -290,7 +290,7 @@ Agenda:
|
||||
|
||||
|
||||
### Prepare for CEO office minutes
|
||||
Before the start of the meeting, the Apprentice to the CEO will prepare the "CEO office minutes" meeting [agenda](https://docs.google.com/document/d/12cd0N8KvHkfJxYlo7ggdisrvqw4MCErDoIzLjmBIdj4/edit) such that the following is true:
|
||||
Before the start of the meeting, the Apprentice will prepare the "CEO office minutes" meeting [agenda](https://docs.google.com/document/d/12cd0N8KvHkfJxYlo7ggdisrvqw4MCErDoIzLjmBIdj4/edit) such that the following is true:
|
||||
1. All agenda items are prefixed with a date of when the item will be covered and name of the person requesting to discuss the issue.
|
||||
2. All team members with an agenda item have added themselves **and their manager** to the correct calendar event. If the team member or manager hasn't been added to the calendar event before the meeting begins, the agenda item is de-prioritized in favor of others with representatives in attendance.
|
||||
3. If there are more that two team members attending, the Apprentice will work with the team members to schedule additional time to cover the agenda.
|
||||
@@ -482,7 +482,7 @@ Once a day the Apprentice will confirm check LinkedIn for unread messages.
|
||||
|
||||
|
||||
### Unroll a Slack thread
|
||||
From time to time the CEO will ask the Apprentice to the CEO to unroll a Slack thread into a well-named whiteboard google doc for safekeeping and future searching.
|
||||
From time to time the CEO will ask the Apprentice to unroll a Slack thread into a well-named whiteboard Google doc for safekeeping and future searching.
|
||||
1. Start with a new doc.
|
||||
2. Name the file with "yyyy-mm-dd - topic" (something empathetic and easy to find).
|
||||
3. Use CMD+SHFT+V to paste the Slack convo into the doc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: "Explore data (fleetdm.com) [DO NOT DELETE]"
|
||||
name: "Explore data (fleetdm.com)"
|
||||
team_settings:
|
||||
features:
|
||||
enable_host_users: true
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
* Added code to detect value of `DISPLAY` variable of user instead of defaulting to `:0` (to support Ubuntu 24.04 with Xorg).
|
||||
@@ -1,11 +1,15 @@
|
||||
package execuser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -19,23 +23,44 @@ func run(path string, opts eopts) error {
|
||||
return fmt.Errorf("get user: %w", err)
|
||||
}
|
||||
|
||||
// TODO(lucas): Default to display :0 if user DISPLAY environment variable
|
||||
// could not be found, revisit when working on multi-user/multi-session support.
|
||||
// This assumes there's only one desktop session and belongs to the
|
||||
// user returned in `getLoginUID'.
|
||||
defaultDisplay := ":0"
|
||||
|
||||
log.Info().
|
||||
Str("user", user.name).
|
||||
Int64("id", user.id).
|
||||
Msg("running sudo")
|
||||
Msg("attempting to get user's DISPLAY")
|
||||
|
||||
// Flag `-i` is needed to run the command with the user's context, from `man sudo`:
|
||||
// "The command is run with an environment similar to the one a user would receive at log in"
|
||||
arg := []string{"-i", "-u", user.name, "-H"}
|
||||
for _, nv := range opts.env {
|
||||
arg = append(arg, fmt.Sprintf("%s=%s", nv[0], nv[1]))
|
||||
display, err := getUserDisplay(user.name, opts)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("user", user.name).
|
||||
Int64("id", user.id).
|
||||
Err(err).
|
||||
Msgf("failed to get user's DISPLAY, using default %s", defaultDisplay)
|
||||
display = defaultDisplay
|
||||
} else if display == "" {
|
||||
log.Warn().
|
||||
Str("user", user.name).
|
||||
Int64("id", user.id).
|
||||
Msgf("user's DISPLAY not found, using default %s", defaultDisplay)
|
||||
display = defaultDisplay
|
||||
}
|
||||
|
||||
arg = append(arg,
|
||||
// TODO(lucas): Default to display 0, revisit when working on
|
||||
// multi-user/multi-session support. This assumes there's only
|
||||
// one desktop session and belongs to the user returned in `getLoginUID'.
|
||||
"DISPLAY=:0",
|
||||
log.Info().
|
||||
Str("path", path).
|
||||
Str("user", user.name).
|
||||
Int64("id", user.id).
|
||||
Str("display", display).
|
||||
Msg("running sudo")
|
||||
|
||||
args := argsForSudo(user, opts)
|
||||
|
||||
args = append(args,
|
||||
"DISPLAY="+display,
|
||||
// DBUS_SESSION_BUS_ADDRESS sets the location of the user login session bus.
|
||||
// Required by the libayatana-appindicator3 library to display a tray icon
|
||||
// on the desktop session.
|
||||
@@ -44,11 +69,14 @@ func run(path string, opts eopts) error {
|
||||
// (because it's already part of the user).
|
||||
fmt.Sprintf("DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%d/bus", user.id),
|
||||
// Append the packaged libayatana-appindicator3 libraries path to LD_LIBRARY_PATH.
|
||||
//
|
||||
// Fleet Desktop doesn't use libayatana-appindicator3 since 1.18.3, but we need to
|
||||
// keep this to support older versions of Fleet Desktop.
|
||||
fmt.Sprintf("LD_LIBRARY_PATH=%s:%s", filepath.Dir(path), os.ExpandEnv("$LD_LIBRARY_PATH")),
|
||||
path,
|
||||
)
|
||||
|
||||
cmd := exec.Command("sudo", arg...)
|
||||
cmd := exec.Command("sudo", args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
log.Printf("cmd=%s", cmd.String())
|
||||
@@ -64,6 +92,18 @@ type user struct {
|
||||
id int64
|
||||
}
|
||||
|
||||
func argsForSudo(u *user, opts eopts) []string {
|
||||
// -H: "[...] to set HOME environment to what's specified in the target's user password database entry."
|
||||
// -i: needed to run the command with the user's context, from `man sudo`:
|
||||
// "The command is run with an environment similar to the one a user would receive at log in"
|
||||
// -u: "[..]Run the command as a user other than the default target user (usually root)."
|
||||
args := []string{"-i", "-u", u.name, "-H"}
|
||||
for _, nv := range opts.env {
|
||||
args = append(args, fmt.Sprintf("%s=%s", nv[0], nv[1]))
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
// getLoginUID returns the name and uid of the first login user
|
||||
// as reported by the `users' command.
|
||||
//
|
||||
@@ -120,3 +160,30 @@ func parseIDOutput(s string) (int64, error) {
|
||||
}
|
||||
return uid, nil
|
||||
}
|
||||
|
||||
var whoLineRegexp = regexp.MustCompile(`(\w+)\s+(:\d+)\s+`)
|
||||
|
||||
func getUserDisplay(user string, opts eopts) (string, error) {
|
||||
cmd := exec.Command("who")
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", fmt.Errorf("run 'who' to get user display: %w", err)
|
||||
}
|
||||
return parseWhoOutputForDisplay(&stdout, user)
|
||||
}
|
||||
|
||||
func parseWhoOutputForDisplay(output io.Reader, user string) (string, error) {
|
||||
scanner := bufio.NewScanner(output)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
matches := whoLineRegexp.FindStringSubmatch(line)
|
||||
if len(matches) > 1 && matches[1] == user {
|
||||
return matches[2], nil
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", fmt.Errorf("scanner error: %w", err)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package execuser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseWhoOutputForDisplay(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
output string
|
||||
user string
|
||||
expectedDisplay string
|
||||
}{
|
||||
{
|
||||
"Ubuntu 22.04.2 (X11)",
|
||||
`foo :0 2024-05-14 17:34 (:0)`,
|
||||
"foo",
|
||||
":0",
|
||||
},
|
||||
{
|
||||
"Ubuntu 22.04.2 (X11) - user not listed",
|
||||
`foo :0 2024-05-14 17:34 (:0)`,
|
||||
"bar",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Ubuntu 24.04 (X11)",
|
||||
`foo seat0 2024-05-14 17:42 (login screen)
|
||||
foo :1 2024-05-14 17:42 (:1)`,
|
||||
"foo",
|
||||
":1",
|
||||
},
|
||||
{
|
||||
"Ubuntu 24.04 (Wayland) - DISPLAY not found",
|
||||
`foo seat0 2024-05-14 18:11 (login screen)
|
||||
foo tty2 2024-05-14 18:11 (tty2)`,
|
||||
"foo",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Empty",
|
||||
``,
|
||||
"foo",
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
display, err := parseWhoOutputForDisplay(bytes.NewReader([]byte(tc.output)), tc.user)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedDisplay, display)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -8689,8 +8689,11 @@ func testHostHealth(t *testing.T, ds *Datastore) {
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), h, false))
|
||||
|
||||
soft1 := h.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = h.Software[1]
|
||||
for _, item := range h.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cpes := []fleet.SoftwareCPE{{SoftwareID: soft1.ID, CPE: "somecpe"}}
|
||||
@@ -8700,8 +8703,11 @@ func testHostHealth(t *testing.T, ds *Datastore) {
|
||||
// Reload software so that 'GeneratedCPEID is set.
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), h, false))
|
||||
soft1 = h.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = h.Software[1]
|
||||
for _, item := range h.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
inserted, err := ds.InsertSoftwareVulnerability(
|
||||
|
||||
@@ -725,8 +725,11 @@ func (s *integrationTestSuite) TestVulnerableSoftware() {
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
|
||||
soft1 := host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cpes := []fleet.SoftwareCPE{{SoftwareID: soft1.ID, CPE: "somecpe"}}
|
||||
@@ -736,8 +739,11 @@ func (s *integrationTestSuite) TestVulnerableSoftware() {
|
||||
// Reload software so that 'GeneratedCPEID is set.
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
soft1 = host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
inserted, err := s.ds.InsertSoftwareVulnerability(
|
||||
@@ -10862,8 +10868,11 @@ func (s *integrationTestSuite) TestHostHealth() {
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
|
||||
soft1 := host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cpes := []fleet.SoftwareCPE{{SoftwareID: soft1.ID, CPE: "somecpe"}}
|
||||
@@ -10873,8 +10882,11 @@ func (s *integrationTestSuite) TestHostHealth() {
|
||||
// Reload software so that 'GeneratedCPEID is set.
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
soft1 = host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
inserted, err := s.ds.InsertSoftwareVulnerability(
|
||||
|
||||
@@ -7081,8 +7081,11 @@ func (s *integrationEnterpriseTestSuite) TestAllSoftwareTitles() {
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
|
||||
soft1 := host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cpes := []fleet.SoftwareCPE{{SoftwareID: soft1.ID, CPE: "somecpe"}}
|
||||
@@ -7092,8 +7095,11 @@ func (s *integrationEnterpriseTestSuite) TestAllSoftwareTitles() {
|
||||
// Reload software so that 'GeneratedCPEID is set.
|
||||
require.NoError(t, s.ds.LoadHostSoftware(context.Background(), host, false))
|
||||
soft1 = host.Software[0]
|
||||
if soft1.Name != "bar" {
|
||||
soft1 = host.Software[1]
|
||||
for _, item := range host.Software {
|
||||
if item.Name == "bar" {
|
||||
soft1 = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
inserted, err := s.ds.InsertSoftwareVulnerability(
|
||||
|
||||
@@ -29,7 +29,7 @@ SWIFT_DIALOG_MACOS_APP_VERSION=2.2.1
|
||||
SWIFT_DIALOG_MACOS_APP_BUILD_VERSION=4591
|
||||
|
||||
if [[ -z "$OSQUERY_VERSION" ]]; then
|
||||
OSQUERY_VERSION=5.11.0
|
||||
OSQUERY_VERSION=5.12.2
|
||||
fi
|
||||
|
||||
mkdir -p $TUF_PATH/tmp
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
@@ -7,6 +7,7 @@
|
||||
@core-fleet-black-50: #8b8fa2;
|
||||
@core-fleet-black-33: #B3B6C1;
|
||||
@core-fleet-black-25: #C5C7D1;
|
||||
@core-fleet-black-10: #E2E4EA;
|
||||
|
||||
@core-vibrant-red: #FF5C83;
|
||||
|
||||
|
||||
+25
-15
@@ -573,6 +573,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
line-height: 19.2px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
span {
|
||||
font-size: 12px;
|
||||
@@ -580,6 +581,7 @@
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
img {
|
||||
padding: 0;
|
||||
@@ -785,22 +787,30 @@
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
[purpose='slack-cta'] {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
margin-bottom: 40px;
|
||||
border-top: 1px solid @core-fleet-black-25;
|
||||
border-bottom: 1px solid @core-fleet-black-25;
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 0;
|
||||
border-bottom: 0;
|
||||
|
||||
[purpose='docs-start-cta'] {
|
||||
margin-top: 40px;
|
||||
border: 1px solid @core-fleet-black-10;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
[purpose='docs-start-cta-image'] {
|
||||
height: 180px;
|
||||
background-image: url('/images/docs-cta-stage-1-314x180@2x.png');
|
||||
background-size: cover;
|
||||
background-position-y: center;
|
||||
}
|
||||
}
|
||||
[purpose='improve-docs'] {
|
||||
h3 {
|
||||
border-bottom: 0;
|
||||
[purpose='docs-start-cta-content'] {
|
||||
h2 {
|
||||
padding: 0;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
[purpose='continue-button'] {
|
||||
font-size: 14px;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
}
|
||||
[purpose='checklist-item'] {
|
||||
|
||||
Vendored
-1
@@ -312,7 +312,6 @@ module.exports.routes = {
|
||||
'GET /handbook/customer-experience': '/handbook/customers',
|
||||
'GET /handbook/brand': '/handbook/digital-experience',
|
||||
'GET /guides/deploying-fleet-on-aws-with-terraform': '/deploy/deploying-fleet-on-aws-with-terraform',
|
||||
'GET /guides/deploy-fleet-on-hetzner-cloud':'/deploy/deploy-fleet-on-hetzner-cloud',
|
||||
'GET /guides/deploying-fleet-on-render': '/deploy/deploying-fleet-on-render',
|
||||
'GET /use-cases/correlate-network-connections-with-community-id-in-osquery': '/guides/correlate-network-connections-with-community-id-in-osquery',
|
||||
'GET /use-cases/converting-unix-timestamps-with-osquery': '/guides/converting-unix-timestamps-with-osquery',
|
||||
|
||||
+6
-13
@@ -203,21 +203,14 @@
|
||||
)
|
||||
) %>
|
||||
|
||||
<div class="d-block" purpose="slack-cta">
|
||||
<h3 class="pt-0" style="font-size: 24px; line-height: 28px;">Need more help?</h3>
|
||||
<div class="d-sm-flex">
|
||||
<a href="/support" target="_blank" class="d-flex btn btn-md btn-outline-secondary justify-content-center align-items-center mt-3 mt-sm-0" purpose="next-steps-button">
|
||||
<img class="pr-3" alt="Slack logo" src="/images/logo-slack-24x24@2x.png"/>
|
||||
Ask the community on Slack
|
||||
</a>
|
||||
<div purpose="docs-start-cta" class="d-flex flex-column flex-sm-row justify-content-between">
|
||||
<div purpose="docs-start-cta-image" class="col-sm-6 col-md-5 col-lg-6"></div>
|
||||
<div purpose="docs-start-cta-content" class="d-flex flex-column justify-content-center my-4 mx-auto text-center">
|
||||
<h2>Try it out</h2>
|
||||
<p>See what Fleet can do</p>
|
||||
<a purpose="continue-button" class="btn btn-primary" href="/register">Start now</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-block" purpose="improve-docs">
|
||||
<h3 class="pt-0 pb-4 m-0" style="font-size: 24px; line-height: 28px;">Did we miss anything?</h3>
|
||||
<p>
|
||||
If you notice something we've missed or could be improved on, please follow <a :href="'https://github.com/fleetdm/fleet/edit/main/docs/'+thisPage.sectionRelativeRepoPath" target="_blank">this link</a> and submit a pull request to the Fleet repo.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -7,7 +7,7 @@
|
||||
<%/* Hero text */%>
|
||||
<div purpose="hero-text" class="d-flex flex-column justify-content-center">
|
||||
<h1><%- partial('../partials/primary-tagline.partial.ejs') %></h1>
|
||||
<p>Replace the sprawl with open-source code that works the way you want.</p>
|
||||
<p>Replace the sprawl with open-source <%= primaryBuyingSituation === 'mdm'? 'MDM' : primaryBuyingSituation === 'vm'? 'reporting' : 'software' %> that works the way you want.</p>
|
||||
<div purpose="button-row" class="d-flex flex-sm-row flex-column justify-content-center align-items-center">
|
||||
<a purpose="cta-button" href="/register">Start now</a>
|
||||
<a purpose="animated-arrow-button-red" href="/contact">Talk to us</a>
|
||||
|
||||
Reference in New Issue
Block a user