Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion pkg/arc/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ var (
}

// Arc services that may be present (not all are guaranteed to exist on every installation)
arcServices = []string{"himdsd", "gcarcservice", "extd"}
arcServices = []string{"himdsd", "gcarcservice", "gcad", "extd"}

// Arc service groups required for installation verification. At least one
// service in each group must be active.
arcRequiredServiceGroups = [][]string{
{"himdsd"},
{"gcarcservice", "gcad"},
{"extd"},
}

// Arc agent binary paths
arcBinaryPaths = []string{
Expand All @@ -42,7 +50,9 @@ var (
arcServiceFiles = []string{
"/lib/systemd/system/himdsd.service",
"/lib/systemd/system/gcarcservice.service",
"/lib/systemd/system/gcad.service",
"/etc/systemd/system/himdsd.service",
"/etc/systemd/system/gcarcservice.service",
"/etc/systemd/system/gcad.service",
}
)
25 changes: 22 additions & 3 deletions pkg/arc/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,31 @@ func isArcServicesRunning(ctx context.Context, logger *slog.Logger) bool {
if !isArcAgentInstalled() {
return false
}
for _, service := range arcServices {
if !utilexec.IsServiceActive(ctx, logger, service) {
if !areArcServiceGroupsActive(ctx, logger, arcRequiredServiceGroups, utilexec.IsServiceActive) {
return false
}
return utilexec.RunCmdAt(ctx, logger, slog.LevelDebug, utilexec.Pgrep(), "-f", "azcmagent") == nil
}

func areArcServiceGroupsActive(
ctx context.Context,
logger *slog.Logger,
serviceGroups [][]string,
isServiceActive func(context.Context, *slog.Logger, string) bool,
) bool {
for _, serviceGroup := range serviceGroups {
serviceGroupActive := false
for _, service := range serviceGroup {
if isServiceActive(ctx, logger, service) {
serviceGroupActive = true
break
}
}
if !serviceGroupActive {
return false
}
}
return utilexec.RunCmdAt(ctx, logger, slog.LevelDebug, utilexec.Pgrep(), "-f", "azcmagent") == nil
return true
}

func ptrDeref[T any](p *T) T {
Expand Down
87 changes: 87 additions & 0 deletions pkg/arc/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package arc

import (
"context"
"io"
"log/slog"
"slices"
"testing"
)

func TestAreArcServiceGroupsActive(t *testing.T) {
t.Parallel()

ctx := context.Background()
logger := slog.New(slog.NewTextHandler(io.Discard, nil))

tests := []struct {
name string
activeServices map[string]bool
want bool
}{
{
name: "legacy service active",
activeServices: map[string]bool{
"himdsd": true,
"gcarcservice": true,
"extd": true,
},
want: true,
},
{
name: "renamed service active",
activeServices: map[string]bool{
"himdsd": true,
"gcad": true,
"extd": true,
},
want: true,
},
{
name: "neither service active",
activeServices: map[string]bool{
"himdsd": true,
"extd": true,
},
want: false,
},
{
name: "required service inactive",
activeServices: map[string]bool{
"gcad": true,
"extd": true,
},
want: false,
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

got := areArcServiceGroupsActive(ctx, logger, arcRequiredServiceGroups, func(_ context.Context, _ *slog.Logger, service string) bool {
return tt.activeServices[service]
})
if got != tt.want {
t.Fatalf("areArcServiceGroupsActive() = %v, want %v", got, tt.want)
}
})
}
}

func TestArcServiceConstantsIncludeRenamedService(t *testing.T) {
t.Parallel()

const renamedService = "gcad"

if !slices.Contains(arcServices, renamedService) {
t.Fatalf("arcServices must include gcad for azcmagent v1.62+ cleanup")
}
if !slices.Contains(arcServiceFiles, "/lib/systemd/system/"+renamedService+".service") {
t.Fatalf("arcServiceFiles must include /lib/systemd/system/gcad.service")
}
if !slices.Contains(arcServiceFiles, "/etc/systemd/system/"+renamedService+".service") {
t.Fatalf("arcServiceFiles must include /etc/systemd/system/gcad.service")
}
}
Loading