Просмотр исходного кода

chore: fieldalignment across code base to reduce memory usage

jamesread 3 недель назад
Родитель
Сommit
a1f03e7d33

+ 2 - 2
service/internal/acl/acl_test.go

@@ -9,10 +9,10 @@ import (
 func Test_hasGroupsMatch(t *testing.T) {
 	tests := []struct {
 		name               string
-		aclMatchUsergroups []string
 		usergroupLine      string
-		matches            bool
 		sep                string
+		aclMatchUsergroups []string
+		matches            bool
 	}{
 		{
 			name:               "No groups match",

+ 1 - 1
service/internal/api/api.go

@@ -63,9 +63,9 @@ func (api *oliveTinAPI) copyOfStreamingClients() []*streamingClient {
 type streamingClient struct {
 	channel           chan *apiv1.EventStreamResponse
 	AuthenticatedUser *authpublic.AuthenticatedUser
-	heartbeatStopOnce sync.Once
 	heartbeatStop     chan struct{}
 	heartbeatDone     chan struct{}
+	heartbeatStopOnce sync.Once
 }
 
 func (c *streamingClient) stopHeartbeat() {

+ 1 - 1
service/internal/api/apiActions.go

@@ -25,9 +25,9 @@ type DashboardRenderRequest struct {
 	AuthenticatedUser   *authpublic.AuthenticatedUser
 	cfg                 *config.Config
 	ex                  *executor.Executor
+	activeBindingStates map[string]bindingActiveState
 	EntityType          string
 	EntityKey           string
-	activeBindingStates map[string]bindingActiveState
 }
 
 func activeBindingID(entry *executor.InternalLogEntry) string {

+ 1 - 1
service/internal/api/api_test.go

@@ -226,9 +226,9 @@ func validateConsistency(t *testing.T, client apiv1connect.OliveTinApiServiceCli
 
 func TestEvaluateEnabledExpression(t *testing.T) {
 	tests := []struct {
+		entity         *entities.Entity
 		name           string
 		expression     string
-		entity         *entities.Entity
 		expectedResult bool
 	}{
 		{

+ 5 - 8
service/internal/auth/authpublic/authenticateduser.go

@@ -10,15 +10,12 @@ import (
 
 // User represents a person.
 type AuthenticatedUser struct {
-	Username      string
-	UsergroupLine string
-
-	Provider string
-	SID      string
-
-	Acls []string
-
 	EffectivePolicy *config.ConfigurationPolicy
+	Username        string
+	UsergroupLine   string
+	Provider        string
+	SID             string
+	Acls            []string
 }
 
 func (u *AuthenticatedUser) IsGuest() bool {

+ 1 - 1
service/internal/auth/authpublic/authenticateduser_test.go

@@ -10,8 +10,8 @@ func Test_parseUsergroupLine(t *testing.T) {
 	tests := []struct {
 		name           string
 		usergroupLine  string
-		expectedGroups []string
 		sep            string
+		expectedGroups []string
 	}{
 		{
 			name:           "Default separator (space)",

+ 2 - 2
service/internal/auth/otoauth2/restapi_auth_oauth2.go

@@ -22,9 +22,9 @@ import (
 
 type OAuth2Handler struct {
 	cfg                 *config.Config
-	mu                  sync.RWMutex
 	registeredStates    map[string]*oauth2State
 	registeredProviders map[string]*oauth2.Config
+	mu                  sync.RWMutex
 }
 
 func NewOAuth2Handler(cfg *config.Config) *OAuth2Handler {
@@ -58,11 +58,11 @@ func NewOAuth2Handler(cfg *config.Config) *OAuth2Handler {
 }
 
 type oauth2State struct {
+	createdAt      time.Time
 	providerConfig *oauth2.Config
 	providerName   string
 	Username       string
 	Usergroup      string
-	createdAt      time.Time
 }
 
 const (

+ 89 - 92
service/internal/config/config.go

@@ -13,34 +13,33 @@ const JustificationRequiredNoTemplate = " "
 // Action represents the core functionality of OliveTin - commands that show up
 // as buttons in the UI.
 type Action struct {
-	ID                     string           `koanf:"id"`
-	Title                  string           `koanf:"title"`
-	Icon                   string           `koanf:"icon"`
+	SaveLogs               SaveLogsConfig   `koanf:"saveLogs"`
 	Shell                  string           `koanf:"shell"`
-	Exec                   []string         `koanf:"exec"`
+	Icon                   string           `koanf:"icon"`
+	ExecOnCalendarFile     string           `koanf:"execOnCalendarFile"`
+	SourceFile             string           `koanf:"-"`
 	ShellAfterCompleted    string           `koanf:"shellAfterCompleted"`
-	Timeout                int              `koanf:"timeout"`
-	Acls                   []string         `koanf:"acls"`
+	Justification          string           `koanf:"justification"`
+	EnabledExpression      string           `koanf:"enabledExpression"`
 	Entity                 string           `koanf:"entity"`
-	Hidden                 bool             `koanf:"hidden"`
-	ExecOnStartup          bool             `koanf:"execOnStartup"`
-	ExecOnCron             []string         `koanf:"execOnCron"`
-	ExecOnFileCreatedInDir []string         `koanf:"execOnFileCreatedInDir"`
-	ExecOnFileChangedInDir []string         `koanf:"execOnFileChangedInDir"`
-	ExecOnCalendarFile     string           `koanf:"execOnCalendarFile"`
+	Title                  string           `koanf:"title"`
+	PopupOnStart           string           `koanf:"popupOnStart"`
+	OnClick                string           `koanf:"onclick"`
+	ID                     string           `koanf:"id"`
+	MaxRate                []RateSpec       `koanf:"maxRate"`
+	Acls                   []string         `koanf:"acls"`
 	ExecOnWebhook          []WebhookConfig  `koanf:"execOnWebhook"`
 	Triggers               []string         `koanf:"triggers"`
-	MaxConcurrent          int              `koanf:"maxConcurrent"`
-	MaxRate                []RateSpec       `koanf:"maxRate"`
+	Exec                   []string         `koanf:"exec"`
+	ExecOnFileCreatedInDir []string         `koanf:"execOnFileCreatedInDir"`
 	Arguments              []ActionArgument `koanf:"arguments"`
-	OnClick                string           `koanf:"onclick"`
-	PopupOnStart           string           `koanf:"popupOnStart"`
-	SaveLogs               SaveLogsConfig   `koanf:"saveLogs"`
-	EnabledExpression      string           `koanf:"enabledExpression"`
+	ExecOnCron             []string         `koanf:"execOnCron"`
 	Groups                 []string         `koanf:"groups"`
-	Justification          string           `koanf:"justification"`
-	// SourceFile is set by OliveTin when loading config (not user YAML).
-	SourceFile string `koanf:"-"`
+	ExecOnFileChangedInDir []string         `koanf:"execOnFileChangedInDir"`
+	Timeout                int              `koanf:"timeout"`
+	MaxConcurrent          int              `koanf:"maxConcurrent"`
+	Hidden                 bool             `koanf:"hidden"`
+	ExecOnStartup          bool             `koanf:"execOnStartup"`
 }
 
 func (action *Action) RequiresJustification() bool {
@@ -61,23 +60,23 @@ func (action *Action) JustificationTemplateText() string {
 
 // ActionGroup defines shared limits and metadata for a set of actions.
 type ActionGroup struct {
+	Icon          string `koanf:"icon"`
 	MaxConcurrent int    `koanf:"maxConcurrent"`
 	QueueSize     int    `koanf:"queueSize"`
-	Icon          string `koanf:"icon"`
 }
 
 // ActionArgument objects appear on Actions.
 type ActionArgument struct {
+	Suggestions           map[string]string      `koanf:"suggestions"`
 	Name                  string                 `koanf:"name"`
 	Title                 string                 `koanf:"title"`
 	Description           string                 `koanf:"description"`
 	Type                  string                 `koanf:"type"`
 	Default               string                 `koanf:"default"`
-	Choices               []ActionArgumentChoice `koanf:"choices"`
 	Entity                string                 `koanf:"entity"`
-	RejectNull            bool                   `koanf:"rejectNull"`
-	Suggestions           map[string]string      `koanf:"suggestions"`
 	SuggestionsBrowserKey string                 `koanf:"suggestionsBrowserKey"`
+	Choices               []ActionArgumentChoice `koanf:"choices"`
+	RejectNull            bool                   `koanf:"rejectNull"`
 }
 
 // ActionArgumentChoice represents a predefined choice for an argument.
@@ -88,8 +87,8 @@ type ActionArgumentChoice struct {
 
 // RateSpec allows you to set a max frequency for an action.
 type RateSpec struct {
-	Limit    int    `koanf:"limit"`
 	Duration string `koanf:"duration"`
+	Limit    int    `koanf:"limit"`
 }
 
 // WebhookConfig defines configuration for generic webhook triggers.
@@ -111,9 +110,8 @@ type EntityFile struct {
 	File       string           `koanf:"file"`
 	Name       string           `koanf:"name"`
 	Icon       string           `koanf:"icon"`
+	SourceFile string           `koanf:"-"`
 	Properties []EntityProperty `koanf:"properties"`
-	// SourceFile is set by OliveTin when loading config (not user YAML).
-	SourceFile string `koanf:"-"`
 }
 
 // EntityProperty defines a column shown when listing entity instances in the UI.
@@ -133,11 +131,11 @@ type PermissionsList struct {
 // AccessControlList defines what permissions apply to a user or user group.
 type AccessControlList struct {
 	Name             string              `koanf:"name"`
-	AddToEveryAction bool                `koanf:"addToEveryAction"`
 	MatchUsergroups  []string            `koanf:"matchUsergroups"`
 	MatchUsernames   []string            `koanf:"matchUsernames"`
 	Permissions      PermissionsList     `koanf:"permissions"`
 	Policy           ConfigurationPolicy `koanf:"policy"`
+	AddToEveryAction bool                `koanf:"addToEveryAction"`
 }
 
 // ConfigurationPolicy defines global settings which are overridden with an ACL.
@@ -154,88 +152,87 @@ type PrometheusConfig struct {
 
 // SecurityConfig allows users to fine tune the security related HTTP headers and cookie options.
 type SecurityConfig struct {
-	HeaderContentSecurityPolicy bool   `koanf:"headerContentSecurityPolicy"`
 	ContentSecurityPolicy       string `koanf:"contentSecurityPolicy"`
+	XFrameOptions               string `koanf:"xFrameOptions"`
+	HeaderContentSecurityPolicy bool   `koanf:"headerContentSecurityPolicy"`
 	HeaderXContentTypeOptions   bool   `koanf:"headerXContentTypeOptions"`
 	HeaderXFrameOptions         bool   `koanf:"headerXFrameOptions"`
-	XFrameOptions               string `koanf:"xFrameOptions"`
 	ForceSecureCookies          bool   `koanf:"forceSecureCookies"`
 }
 
 // Config is the global config used through the whole app.
 type Config struct {
-	UseSingleHTTPFrontend              bool                       `koanf:"useSingleHTTPFrontend"`
-	ThemeName                          string                     `koanf:"themeName"`
-	ThemeCacheDisabled                 bool                       `koanf:"themeCacheDisabled"`
-	ListenAddressSingleHTTPFrontend    string                     `koanf:"listenAddressSingleHTTPFrontend"`
-	ListenAddressWebUI                 string                     `koanf:"listenAddressWebUI"`
+	ActionGroups                       map[string]*ActionGroup    `koanf:"actionGroups"`
+	AuthOAuth2Providers                map[string]*OAuth2Provider `koanf:"authOAuth2Providers"`
+	SaveLogs                           SaveLogsConfig             `koanf:"saveLogs"`
+	DefaultIconForBack                 string                     `koanf:"defaultIconForBack"`
+	AuthOAuth2RedirectURL              string                     `koanf:"authOAuth2RedirectUrl"`
 	ListenAddressRestActions           string                     `koanf:"listenAddressRestActions"`
 	ListenAddressPrometheus            string                     `koanf:"listenAddressPrometheus"`
 	ExternalRestAddress                string                     `koanf:"externalRestAddress"`
 	LogLevel                           string                     `koanf:"logLevel"`
-	LogDebugOptions                    LogDebugOptions            `koanf:"logDebugOptions"`
-	LogHistoryPageSize                 int64                      `koanf:"logHistoryPageSize"`
-	ActionGroups                       map[string]*ActionGroup    `koanf:"actionGroups"`
-	Actions                            []*Action                  `koanf:"actions"`
-	Entities                           []*EntityFile              `koanf:"entities"`
-	Dashboards                         []*DashboardComponent      `koanf:"dashboards"`
-	CheckForUpdates                    bool                       `koanf:"checkForUpdates"`
+	ThemeName                          string                     `koanf:"themeName"`
+	ServiceLogs                        ServiceLogsConfig          `koanf:"serviceLogs"`
+	ListenAddressSingleHTTPFrontend    string                     `koanf:"listenAddressSingleHTTPFrontend"`
+	AuthJwtHmacSecret                  string                     `koanf:"authJwtHmacSecret"`
+	AuthJwtCertsURL                    string                     `koanf:"authJwtCertsUrl"`
+	DefaultIconForActions              string                     `koanf:"defaultIconForActions"`
+	Include                            string                     `koanf:"include"`
 	PageTitle                          string                     `koanf:"pageTitle"`
-	ShowFooter                         bool                       `koanf:"showFooter"`
-	ShowNavigation                     bool                       `koanf:"showNavigation"`
-	ShowNewVersions                    bool                       `koanf:"showNewVersions"`
-	ShowNavigateOnStartIcons           bool                       `koanf:"showNavigateOnStartIcons"`
-	EnableCustomJs                     bool                       `koanf:"enableCustomJs"`
+	BannerCSS                          string                     `koanf:"bannerCss"`
+	BannerMessage                      string                     `koanf:"bannerMessage"`
+	DefaultPopupOnStart                string                     `koanf:"defaultPopupOnStart"`
+	ServiceHostMode                    string                     `koanf:"serviceHostMode"`
+	DefaultOnClick                     string                     `koanf:"defaultOnClick"`
 	AuthJwtCookieName                  string                     `koanf:"authJwtCookieName"`
 	AuthJwtHeader                      string                     `koanf:"authJwtHeader"`
 	AuthJwtAud                         string                     `koanf:"authJwtAud"`
-	AuthJwtDomain                      string                     `koanf:"authJwtDomain"`
-	AuthJwtCertsURL                    string                     `koanf:"authJwtCertsUrl"`
-	AuthJwtHmacSecret                  string                     `koanf:"authJwtHmacSecret"` // mutually exclusive with pub key config fields
+	ListenAddressWebUI                 string                     `koanf:"listenAddressWebUI"`
+	SectionNavigationStyle             string                     `koanf:"sectionNavigationStyle"`
+	DefaultIconForDirectories          string                     `koanf:"defaultIconForDirectories"`
 	AuthJwtClaimUsername               string                     `koanf:"authJwtClaimUsername"`
 	AuthJwtClaimUserGroup              string                     `koanf:"authJwtClaimUserGroup"`
-	AuthJwtPubKeyPath                  string                     `koanf:"authJwtPubKeyPath"` // will read pub key from file on disk
+	AuthJwtPubKeyPath                  string                     `koanf:"authJwtPubKeyPath"`
 	AuthHttpHeaderUsername             string                     `koanf:"authHttpHeaderUsername"`
 	AuthHttpHeaderUserGroup            string                     `koanf:"authHttpHeaderUserGroup"`
 	AuthHttpHeaderUserGroupSep         string                     `koanf:"authHttpHeaderUserGroupSep"`
-	AuthLocalUsers                     AuthLocalUsersConfig       `koanf:"authLocalUsers"`
-	AuthLoginUrl                       string                     `koanf:"authLoginUrl"`
-	AuthRequireGuestsToLogin           bool                       `koanf:"authRequireGuestsToLogin"`
-	AuthOAuth2RedirectURL              string                     `koanf:"authOAuth2RedirectUrl"`
-	AuthOAuth2Providers                map[string]*OAuth2Provider `koanf:"authOAuth2Providers"`
-	DefaultPermissions                 PermissionsList            `koanf:"defaultPermissions"`
-	DefaultPolicy                      ConfigurationPolicy        `koanf:"defaultPolicy"`
-	AccessControlLists                 []*AccessControlList       `koanf:"accessControlLists"`
 	WebUIDir                           string                     `koanf:"webUIDir"`
-	CronSupportForSeconds              bool                       `koanf:"cronSupportForSeconds"`
-	SectionNavigationStyle             string                     `koanf:"sectionNavigationStyle"`
-	DefaultOnClick                     string                     `koanf:"defaultOnClick"`
-	DefaultPopupOnStart                string                     `koanf:"defaultPopupOnStart"`
-	InsecureAllowDumpOAuth2UserData    bool                       `koanf:"insecureAllowDumpOAuth2UserData"`
-	InsecureAllowDumpVars              bool                       `koanf:"insecureAllowDumpVars"`
-	InsecureAllowDumpServerDiagnostics bool                       `koanf:"insecureAllowDumpServerDiagnostics"`
-	InsecureAllowDumpActionMap         bool                       `koanf:"insecureAllowDumpActionMap"`
-	InsecureAllowDumpJwtClaims         bool                       `koanf:"insecureAllowDumpJwtClaims"`
-	Prometheus                         PrometheusConfig           `koanf:"prometheus"`
+	AuthLoginUrl                       string                     `koanf:"authLoginUrl"`
+	AuthJwtDomain                      string                     `koanf:"authJwtDomain"`
 	Security                           SecurityConfig             `koanf:"security"`
-	SaveLogs                           SaveLogsConfig             `koanf:"saveLogs"`
-	ServiceLogs                        ServiceLogsConfig          `koanf:"serviceLogs"`
-	DefaultIconForActions              string                     `koanf:"defaultIconForActions"`
-	DefaultIconForDirectories          string                     `koanf:"defaultIconForDirectories"`
-	DefaultIconForBack                 string                     `koanf:"defaultIconForBack"`
-	AdditionalNavigationLinks          []*NavigationLink          `koanf:"additionalNavigationLinks"`
-	ServiceHostMode                    string                     `koanf:"serviceHostMode"`
+	Actions                            []*Action                  `koanf:"actions"`
+	AccessControlLists                 []*AccessControlList       `koanf:"accessControlLists"`
 	StyleMods                          []string                   `koanf:"styleMods"`
-	BannerMessage                      string                     `koanf:"bannerMessage"`
-	BannerCSS                          string                     `koanf:"bannerCss"`
-	Include                            string                     `koanf:"include"`
-
-	sourceFiles []string
+	AdditionalNavigationLinks          []*NavigationLink          `koanf:"additionalNavigationLinks"`
+	Entities                           []*EntityFile              `koanf:"entities"`
+	Dashboards                         []*DashboardComponent      `koanf:"dashboards"`
+	sourceFiles                        []string
+	AuthLocalUsers                     AuthLocalUsersConfig `koanf:"authLocalUsers"`
+	LogHistoryPageSize                 int64                `koanf:"logHistoryPageSize"`
+	LogDebugOptions                    LogDebugOptions      `koanf:"logDebugOptions"`
+	DefaultPermissions                 PermissionsList      `koanf:"defaultPermissions"`
+	DefaultPolicy                      ConfigurationPolicy  `koanf:"defaultPolicy"`
+	Prometheus                         PrometheusConfig     `koanf:"prometheus"`
+	CheckForUpdates                    bool                 `koanf:"checkForUpdates"`
+	InsecureAllowDumpJwtClaims         bool                 `koanf:"insecureAllowDumpJwtClaims"`
+	InsecureAllowDumpActionMap         bool                 `koanf:"insecureAllowDumpActionMap"`
+	InsecureAllowDumpServerDiagnostics bool                 `koanf:"insecureAllowDumpServerDiagnostics"`
+	InsecureAllowDumpVars              bool                 `koanf:"insecureAllowDumpVars"`
+	InsecureAllowDumpOAuth2UserData    bool                 `koanf:"insecureAllowDumpOAuth2UserData"`
+	CronSupportForSeconds              bool                 `koanf:"cronSupportForSeconds"`
+	AuthRequireGuestsToLogin           bool                 `koanf:"authRequireGuestsToLogin"`
+	EnableCustomJs                     bool                 `koanf:"enableCustomJs"`
+	ShowNavigateOnStartIcons           bool                 `koanf:"showNavigateOnStartIcons"`
+	ShowNewVersions                    bool                 `koanf:"showNewVersions"`
+	ShowNavigation                     bool                 `koanf:"showNavigation"`
+	ShowFooter                         bool                 `koanf:"showFooter"`
+	UseSingleHTTPFrontend              bool                 `koanf:"useSingleHTTPFrontend"`
+	ThemeCacheDisabled                 bool                 `koanf:"themeCacheDisabled"`
 }
 
 type AuthLocalUsersConfig struct {
-	Enabled bool         `koanf:"enabled"`
 	Users   []*LocalUser `koanf:"users"`
+	Enabled bool         `koanf:"enabled"`
 }
 
 type LocalUser struct {
@@ -246,21 +243,21 @@ type LocalUser struct {
 }
 
 type OAuth2Provider struct {
-	Name               string   `koanf:"name"`
-	Title              string   `koanf:"title"`
+	AuthUrl            string   `koanf:"authUrl"`
+	UserGroupField     string   `koanf:"userGroupField"`
 	ClientID           string   `koanf:"clientId"`
 	ClientSecret       string   `koanf:"clientSecret"`
 	Icon               string   `koanf:"icon"`
-	Scopes             []string `koanf:"scopes"`
-	AuthUrl            string   `koanf:"authUrl"`
-	TokenUrl           string   `koanf:"tokenUrl"`
+	AddToUsergroup     string   `koanf:"addToUsergroup"`
+	Title              string   `koanf:"title"`
 	WhoamiUrl          string   `koanf:"whoamiUrl"`
+	Name               string   `koanf:"name"`
 	UsernameField      string   `koanf:"usernameField"`
-	UserGroupField     string   `koanf:"userGroupField"`
-	InsecureSkipVerify bool     `koanf:"insecureSkipVerify"`
-	CallbackTimeout    int      `koanf:"callbackTimeout"`
+	TokenUrl           string   `koanf:"tokenUrl"`
 	CertBundlePath     string   `koanf:"certBundlePath"`
-	AddToUsergroup     string   `koanf:"addToUsergroup"`
+	Scopes             []string `koanf:"scopes"`
+	CallbackTimeout    int      `koanf:"callbackTimeout"`
+	InsecureSkipVerify bool     `koanf:"insecureSkipVerify"`
 }
 
 type NavigationLink struct {

+ 4 - 4
service/internal/executor/arguments_test.go

@@ -981,12 +981,12 @@ func TestTypecheckActionArgumentHtmlWithoutName(t *testing.T) {
 
 func TestParseCommandForReplacements(t *testing.T) {
 	tests := []struct {
+		values         map[string]string
 		name           string
 		shellCommand   string
-		values         map[string]string
 		expectedOutput string
-		expectError    bool
 		errorContains  string
+		expectError    bool
 	}{
 		{
 			name:           "Simple replacement",
@@ -1052,10 +1052,10 @@ func TestParseCommandForReplacements(t *testing.T) {
 
 func TestArgumentChoicesValidation(t *testing.T) {
 	tests := []struct {
-		name        string
 		req         *ExecutionRequest
-		expectError bool
+		name        string
 		description string
+		expectError bool
 	}{
 		{
 			name: "Valid choice",

+ 39 - 52
service/internal/executor/executor.go

@@ -40,53 +40,46 @@ func isValidTrackingID(id string) bool {
 }
 
 type ActionBinding struct {
-	ID           string
 	Action       *config.Action
 	Entity       *entities.Entity
-	ConfigOrder  int
+	ID           string
 	OnDashboards []DashboardNavigationTarget
+	ConfigOrder  int
 }
 
 // Executor represents a helper class for executing commands. It's main method
 // is ExecRequest
 type Executor struct {
 	logs                  map[string]*InternalLogEntry
-	logsTrackingIdsByDate []string
 	LogsByBindingId       map[string][]*InternalLogEntry
-
-	logmutex sync.RWMutex
-
 	MapActionBindings     map[string]*ActionBinding
+	Cfg                   *config.Config
+	logsTrackingIdsByDate []string
+	listeners             []listener
+	chainOfCommand        []executorStepFunc
+	groupQueue            []*queuedExecution
+	logmutex              sync.RWMutex
 	MapActionBindingsLock sync.RWMutex
-
-	Cfg *config.Config
-
-	listeners   []listener
-	listenersMu sync.RWMutex
-
-	chainOfCommand []executorStepFunc
-
-	groupQueue   []*queuedExecution
-	groupQueueMu sync.Mutex
+	listenersMu           sync.RWMutex
+	groupQueueMu          sync.Mutex
 }
 
 // ExecutionRequest is a request to execute an action. It's passed to an
 // Executor. They're created from the api.
 type ExecutionRequest struct {
-	Binding           *ActionBinding
-	Arguments         map[string]string
-	TrackingID        string
-	Tags              []string
-	Cfg               *config.Config
-	AuthenticatedUser *authpublic.AuthenticatedUser
-	TriggerDepth      int
-	Justification     string
-
+	Arguments               map[string]string
+	Binding                 *ActionBinding
+	Cfg                     *config.Config
+	AuthenticatedUser       *authpublic.AuthenticatedUser
+	executor                *Executor
 	logEntry                *InternalLogEntry
 	finalParsedCommand      string
+	TrackingID              string
+	Justification           string
+	Tags                    []string
 	execArgs                []string
+	TriggerDepth            int
 	useDirectExec           bool
-	executor                *Executor
 	skipRequestRegistration bool
 }
 
@@ -104,12 +97,12 @@ func (req *ExecutionRequest) mutateLogEntry(mutator func(*InternalLogEntry)) {
 
 // LogEntrySnapshot is a copy of selected log entry fields for race-safe reads.
 type LogEntrySnapshot struct {
+	Output            string
+	ExitCode          int32
 	Queued            bool
 	Blocked           bool
 	ExecutionStarted  bool
 	ExecutionFinished bool
-	ExitCode          int32
-	Output            string
 }
 
 // SnapshotLog returns a copy of selected log entry fields under read lock.
@@ -136,34 +129,28 @@ func (e *Executor) SnapshotLog(trackingID string) (LogEntrySnapshot, bool) {
 // state of execution (even if the command is not executed). It's designed to be
 // easily serializable.
 type InternalLogEntry struct {
-	Binding             *ActionBinding
 	DatetimeStarted     time.Time
 	DatetimeFinished    time.Time
-	Output              string
-	TimedOut            bool
-	Blocked             bool
-	Queued              bool
-	QueuedForGroup      string
-	ExitCode            int32
-	Tags                []string
-	ExecutionStarted    bool
-	ExecutionFinished   bool
-	ExecutionTrackingID string
+	Binding             *ActionBinding
 	Process             *os.Process
+	Arguments           map[string]string
+	ExecutionTrackingID string
+	Justification       string
+	QueuedForGroup      string
+	ActionIcon          string
+	ActionTitle         string
+	ActionConfigTitle   string
+	Output              string
 	Username            string
-	Index               int64
 	EntityPrefix        string
-	ActionConfigTitle   string // This is the title of the action as defined in the config, not the final parsed title.
-
-	/*
-		The following 3 properties are obviously on Action normally, but it's useful
-		that logs are lightweight (so we don't need to have an action associated to
-		logs, etc. Therefore, we duplicate those values here.
-	*/
-	ActionTitle   string
-	ActionIcon    string
-	Justification string
-	Arguments     map[string]string
+	Tags                []string
+	Index               int64
+	ExitCode            int32
+	Blocked             bool
+	ExecutionFinished   bool
+	ExecutionStarted    bool
+	Queued              bool
+	TimedOut            bool
 }
 
 // .Binding can be nil, so we need to handle that.
@@ -1098,8 +1085,8 @@ func appendErrorToStderr(req *ExecutionRequest, err error) {
 
 type OutputStreamer struct {
 	Req    *ExecutionRequest
-	mu     sync.Mutex
 	output bytes.Buffer
+	mu     sync.Mutex
 }
 
 func (ost *OutputStreamer) Write(o []byte) (n int, err error) {

+ 3 - 3
service/internal/filehelper/file_change_notify.go

@@ -39,12 +39,12 @@ type WatchMeta struct {
 }
 
 type watchContext struct {
-	filename        string
-	filedir         string
 	callback        func(filename string)
-	interestedEvent fsnotify.Op
 	event           *fsnotify.Event
 	meta            WatchMeta
+	filename        string
+	filedir         string
+	interestedEvent fsnotify.Op
 }
 
 func WatchDirectoryCreate(fullpath string, callback func(filename string), meta WatchMeta) {

+ 1 - 1
service/internal/installationinfo/runtimeinfo.go

@@ -16,7 +16,6 @@ type RuntimeInfo struct {
 	OS                   string
 	OSReleasePrettyName  string
 	Arch                 string
-	InContainer          bool
 	LastBrowserUserAgent string
 	User                 string
 	Uid                  string
@@ -25,6 +24,7 @@ type RuntimeInfo struct {
 	AvailableVersion     string
 	WebuiDirectory       string
 	ThemesDirectory      string
+	InContainer          bool
 }
 
 var Runtime = &RuntimeInfo{

+ 2 - 2
service/internal/installationinfo/server_diagnostics.go

@@ -13,8 +13,6 @@ var (
 )
 
 type serverDiagnosticsConfig struct {
-	CountOfActions                  int
-	CountOfDashboards               int
 	LogLevel                        string
 	ListenAddressSingleHTTPFrontend string
 	ListenAddressWebUI              string
@@ -23,6 +21,8 @@ type serverDiagnosticsConfig struct {
 	TimeNow                         string
 	ConfigDirectory                 string
 	WebuiDirectory                  string
+	CountOfActions                  int
+	CountOfDashboards               int
 }
 
 func configToServerDiagnostics(cfg *config.Config) *serverDiagnosticsConfig {

+ 2 - 2
service/internal/logfilter/record.go

@@ -5,12 +5,12 @@ type Record struct {
 	Status   string
 	Action   string
 	User     string
+	Output   string
 	Tags     []string
+	ExitCode int32
 	Blocked  bool
 	TimedOut bool
 	Running  bool
-	ExitCode int32
-	Output   string
 }
 
 // StatusLabel matches the status text shown in the web UI.

+ 2 - 2
service/internal/updatecheck/updateCheck.go

@@ -13,9 +13,9 @@ import (
 )
 
 type versionMapType struct {
-	ApiVersion int
-	Latest     string
 	History    map[string]string
+	Latest     string
+	ApiVersion int
 }
 
 // StartUpdateChecker will start a job that runs periodically, checking

+ 4 - 4
service/scripts/find-flakey-tests-inf/main.go

@@ -42,20 +42,20 @@ type runSummary struct {
 }
 
 type jsonlRecord struct {
-	Run            int           `json:"run"`
 	Timestamp      string        `json:"timestamp"`
+	FailureDetails []testFailure `json:"failureDetails"`
+	Run            int           `json:"run"`
 	ExitCode       int           `json:"exitCode"`
 	DurationMs     int64         `json:"durationMs"`
 	Passes         int           `json:"passes"`
 	Failures       int           `json:"failures"`
 	Skipped        int           `json:"skipped"`
-	FailureDetails []testFailure `json:"failureDetails"`
 }
 
 type testRunState struct {
-	summary       runSummary
-	failures      []testFailure
 	failureOutput map[string]*strings.Builder
+	failures      []testFailure
+	summary       runSummary
 }
 
 func initLog() {