Skip to content

Commit e6aa4f5

Browse files
committed
Adds extension events
1 parent 941b79a commit e6aa4f5

8 files changed

Lines changed: 198 additions & 52 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ toolchain go1.24.5
66

77
require (
88
github.com/Azure/azure-extension-foundation v0.0.0-20250620154556-caff9e3c3c5c
9-
github.com/Azure/azure-extension-platform v0.0.0-20240610175536-404c704f82f8
9+
github.com/Azure/azure-extension-platform v0.0.0-20250107200156-aa20f765d49f
1010
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
1111
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0
1212
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/Azure/azure-extension-foundation v0.0.0-20250620154556-caff9e3c3c5c h
22
github.com/Azure/azure-extension-foundation v0.0.0-20250620154556-caff9e3c3c5c/go.mod h1:sNC6lMTUkXwjrQ+nttr6GXhDfvSGT7t3UDq30BEYzu8=
33
github.com/Azure/azure-extension-platform v0.0.0-20240610175536-404c704f82f8 h1:4AgLx0eXWAzh4nL7eBzwxoQaZEk5Hp2Ilq33YwYzEos=
44
github.com/Azure/azure-extension-platform v0.0.0-20240610175536-404c704f82f8/go.mod h1:nEQQIC3RKmMnpdc+RakYHIdu556jdcHv67ML8PdsQeQ=
5+
github.com/Azure/azure-extension-platform v0.0.0-20250107200156-aa20f765d49f h1:ddsUz/suc9txCMz/xWOslqNMvzhbWFMTflUrbcMNoSw=
6+
github.com/Azure/azure-extension-platform v0.0.0-20250107200156-aa20f765d49f/go.mod h1:0458BvQsi5ch6kn+KZtI5m88Z3L9UFXdoY1+6nKdivY=
57
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
68
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
79
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M=

internal/cmds/cmds.go

Lines changed: 112 additions & 29 deletions
Large diffs are not rendered by default.

internal/cmds/cmds_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ import (
77
"net/http"
88
"net/http/httptest"
99
"os"
10+
"path"
1011
"path/filepath"
1112
"strconv"
1213
"strings"
1314
"testing"
1415

16+
"github.com/Azure/azure-extension-platform/pkg/extensionevents"
17+
"github.com/Azure/azure-extension-platform/pkg/handlerenv"
18+
"github.com/Azure/azure-extension-platform/pkg/logging"
1519
"github.com/Azure/run-command-handler-linux/internal/constants"
1620
"github.com/Azure/run-command-handler-linux/internal/files"
1721
"github.com/Azure/run-command-handler-linux/internal/handlersettings"
@@ -74,7 +78,13 @@ func Test_CopyMrseqFiles_MrseqFilesAreCopied(t *testing.T) {
7478
os.Create(filepath.Join(previousStatusDirectory, "ABCD.1.status"))
7579
os.Create(filepath.Join(previousStatusDirectory, "abc.cs")) // this should not be copied to currentExtensionVersionDirectory
7680

77-
err = CopyStateForUpdate(log.NewContext(log.NewNopLogger()))
81+
handlerEnvironment := handlerenv.HandlerEnvironment{
82+
EventsFolder: path.Join(currentExtensionVersionDirectory, "events"),
83+
}
84+
85+
extensionLogger := logging.New(nil)
86+
extensionEventManager := extensionevents.New(extensionLogger, &handlerEnvironment)
87+
err = CopyStateForUpdate(log.NewContext(log.NewNopLogger()), extensionEventManager)
7888
require.Nil(t, err)
7989

8090
files, _ = ioutil.ReadDir(currentExtensionVersionDirectory)

internal/commandProcessor/commandProcessor.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"time"
1010

11+
"github.com/Azure/azure-extension-platform/pkg/handlerenv"
1112
"github.com/Azure/azure-extension-platform/pkg/logging"
1213
"github.com/Azure/run-command-handler-linux/internal/constants"
1314
"github.com/Azure/run-command-handler-linux/internal/handlersettings"
@@ -19,6 +20,10 @@ import (
1920
"github.com/pkg/errors"
2021
)
2122

23+
var (
24+
handlerEnvironmentGetter func(name, version string) (he *handlerenv.HandlerEnvironment, _ error) = handlerenv.GetHandlerEnvironment
25+
)
26+
2227
func ProcessImmediateHandlerCommand(cmd types.Cmd, hs handlersettings.HandlerSettingsFile, extensionName string, seqNum int) error {
2328
ctx := initializeLogger(cmd)
2429
ctx = ctx.With("extensionName", extensionName)

internal/immediatecmds/immediatecmds.go

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package immediatecmds
22

33
import (
4+
"fmt"
5+
6+
"github.com/Azure/azure-extension-platform/pkg/extensionevents"
47
"github.com/Azure/run-command-handler-linux/internal/constants"
58
"github.com/Azure/run-command-handler-linux/internal/handlersettings"
69
"github.com/Azure/run-command-handler-linux/internal/service"
@@ -11,42 +14,53 @@ import (
1114

1215
// Updates the service definition if any immediate run command service exists.
1316
// The action is skipped if the service has already been upgraded.
14-
func Update(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int) (int, error) {
17+
func Update(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int, extensionEvents *extensionevents.ExtensionEventManager) (int, error) {
1518
ctx.Log("message", "updating immediate run command")
1619
isInstalled, err := service.IsInstalled(ctx)
1720
if err != nil {
21+
errMessage := fmt.Sprintf("Failed to check if any runcommand service is installed: %v", err)
22+
extensionEvents.LogErrorEvent("immediateupdate", errMessage)
1823
return constants.ExitCode_CreateDataDirectoryFailed, errors.Wrap(err, "failed to check if any runcommand service is installed")
1924
}
2025

2126
if isInstalled {
22-
err = service.Register(ctx)
27+
err = service.Register(ctx, extensionEvents)
2328
if err != nil {
29+
errMessage := fmt.Sprintf("Failed to upgrade run command service: %v", err)
30+
extensionEvents.LogErrorEvent("immediateupdate", errMessage)
2431
return constants.ExitCode_UpgradeInstalledServiceFailed, errors.Wrap(err, "failed to upgrade run command service")
2532
}
2633
}
2734

2835
return constants.ExitCode_Okay, nil
2936
}
3037

31-
func Disable(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int) (int, error) {
38+
func Disable(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int, extensionEvents *extensionevents.ExtensionEventManager) (int, error) {
3239
isInstalled, err := service.IsInstalled(ctx)
3340
if err != nil {
41+
errMessage := fmt.Sprintf("Failed to check if runcommand service is installed: %v", err)
42+
extensionEvents.LogErrorEvent("immediatedisable", errMessage)
3443
return constants.ExitCode_DisableInstalledServiceFailed, errors.Wrap(err, "failed to check if runcommand service is installed")
3544
}
3645

3746
if isInstalled {
3847
isEnabled, err := service.IsEnabled(ctx)
3948
if err != nil {
49+
errMessage := fmt.Sprintf("Failed to check if service is enabled: %v", err)
50+
extensionEvents.LogErrorEvent("immediatedisable", errMessage)
4051
return constants.ExitCode_InstallServiceFailed, errors.Wrap(err, "failed to check if service is enabled")
4152
}
4253

4354
if isEnabled {
44-
err := service.Disable(ctx)
55+
err := service.Disable(ctx, extensionEvents)
4556
if err != nil {
57+
errMessage := fmt.Sprintf("Failed to disable run command service: %v", err)
58+
extensionEvents.LogErrorEvent("immediatedisable", errMessage)
4659
return constants.ExitCode_DisableInstalledServiceFailed, errors.Wrap(err, "failed to disable run command service")
4760
}
4861
} else {
4962
ctx.Log("message", "Service installed but already got disabled. Skipping request to disable")
63+
extensionEvents.LogInformationalEvent("immediatedisable", "Service installed but already got disabled. Skipping request to disable")
5064
}
5165
}
5266

@@ -58,51 +72,64 @@ func Install() (int, error) {
5872
return constants.ExitCode_Okay, nil
5973
}
6074

61-
func Uninstall(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int) (int, error) {
75+
func Uninstall(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int, extensionEvents *extensionevents.ExtensionEventManager) (int, error) {
6276
ctx.Log("message", "proceeding to uninstall immediate run command")
6377
isInstalled, err := service.IsInstalled(ctx)
6478
if err != nil {
79+
errMessage := fmt.Sprintf("Failed to check if runcommand service is installed: %v", err)
80+
extensionEvents.LogErrorEvent("immediatedisable", errMessage)
6581
return constants.ExitCode_RemoveDataDirectoryFailed, errors.Wrap(err, "failed to check if runcommand service is installed")
6682
}
6783

6884
if isInstalled {
69-
error := service.DeRegister(ctx)
85+
error := service.DeRegister(ctx, extensionEvents)
7086
if error != nil {
87+
errMessage := fmt.Sprintf("Failed to uninstall run command service: %v", error)
88+
extensionEvents.LogErrorEvent("immediatedisable", errMessage)
7189
return constants.ExitCode_UninstallInstalledServiceFailed, errors.Wrap(err, "failed to uninstall run command service")
7290
}
7391
}
7492
return constants.ExitCode_Okay, nil
7593
}
7694

77-
func Enable(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int, cfg handlersettings.HandlerSettings) (int, error) {
95+
func Enable(ctx *log.Context, h types.HandlerEnvironment, extName string, seqNum int, cfg handlersettings.HandlerSettings, extensionEvents *extensionevents.ExtensionEventManager) (int, error) {
7896
// If installService == true, then install RunCommand as a service
7997
if cfg.InstallAsService() {
8098
isInstalled, err2 := service.IsInstalled(ctx)
8199
if err2 != nil {
82100
ctx.Log("message", "could not check if service is already installed. Proceeding to overwrite configuration file to make sure it gets installed.")
101+
extensionEvents.LogErrorEvent("immediateenable", "could not check if service is already installed. Proceeding to overwrite configuration file to make sure it gets installed.")
83102
}
84103

85104
if !isInstalled {
86-
err3 := service.Register(ctx)
105+
err3 := service.Register(ctx, extensionEvents)
87106
if err3 != nil {
107+
errMessage := fmt.Sprintf("Failed to install RunCommand as a service: %v", err3)
108+
extensionEvents.LogErrorEvent("immediateenable", errMessage)
88109
return constants.ExitCode_InstallServiceFailed, errors.Wrap(err3, "failed to install RunCommand as a service")
89110
}
90111
} else {
91112
isEnabled, err3 := service.IsEnabled(ctx)
92113
if err3 != nil {
114+
errMessage := fmt.Sprintf("Failed to check if service is already enabled: %v", err3)
115+
extensionEvents.LogErrorEvent("immediateenable", errMessage)
93116
return constants.ExitCode_InstallServiceFailed, errors.Wrap(err3, "failed to check if service is already enabled")
94117
}
95118

96119
if !isEnabled {
97-
err4 := service.Enable(ctx)
120+
err4 := service.Enable(ctx, extensionEvents)
98121

99122
if err4 != nil {
123+
errMessage := fmt.Sprintf("Failed to enable service: %v", err4)
124+
extensionEvents.LogErrorEvent("immediateenable", errMessage)
100125
return constants.ExitCode_InstallServiceFailed, errors.Wrap(err4, "failed to enable service")
101126
}
102127

103-
err5 := service.Start(ctx)
128+
err5 := service.Start(ctx, extensionEvents)
104129

105130
if err5 != nil {
131+
errMessage := fmt.Sprintf("Failed to start service: %v", err5)
132+
extensionEvents.LogErrorEvent("immediateenable", errMessage)
106133
return constants.ExitCode_InstallServiceFailed, errors.Wrap(err5, "failed to start service")
107134
}
108135
}

internal/service/serviceinstall.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"strings"
77

8+
"github.com/Azure/azure-extension-platform/pkg/extensionevents"
89
"github.com/Azure/run-command-handler-linux/internal/constants"
910
"github.com/Azure/run-command-handler-linux/pkg/servicehandler"
1011
"github.com/Azure/run-command-handler-linux/pkg/systemd"
@@ -33,8 +34,9 @@ StandardError=append:%run_command_output_directory%
3334
WantedBy=multi-user.target`
3435
)
3536

36-
func Register(ctx *log.Context) error {
37+
func Register(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
3738
if !isSystemdSupported(ctx) {
39+
extensionEvents.LogErrorEvent("register", "Systemd not supported. Failed to register service")
3840
return errors.New("Systemd not supported. Failed to register service")
3941
}
4042
targetVersion := os.Getenv(constants.ExtensionVersionEnvName)
@@ -68,6 +70,8 @@ func Register(ctx *log.Context) error {
6870
execDirectory := os.Getenv(constants.ExtensionPathEnvName) + "/bin/immediate-run-command-handler"
6971
err = os.Chmod(execDirectory, 0744)
7072
if err != nil {
73+
errMessage := fmt.Sprintf("Error while marking the immediate run command binary as executable: %v", err)
74+
extensionEvents.LogErrorEvent("register", errMessage)
7175
return errors.Wrap(err, "error while marking the immediate run command binary as executable")
7276
}
7377

@@ -76,16 +80,17 @@ func Register(ctx *log.Context) error {
7680
return err
7781
}
7882

79-
err = Start(ctx)
83+
err = Start(ctx, extensionEvents)
8084
if err != nil {
8185
return err
8286
}
8387

88+
extensionEvents.LogInformationalEvent("register", "Service registration complete")
8489
ctx.Log("message", "Service registration complete")
8590
return nil
8691
}
8792

88-
func DeRegister(ctx *log.Context) error {
93+
func DeRegister(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
8994
if isSystemdSupported(ctx) {
9095
serviceHandler := getSystemdHandler(ctx)
9196

@@ -95,13 +100,14 @@ func DeRegister(ctx *log.Context) error {
95100
return err
96101
}
97102

103+
extensionEvents.LogInformationalEvent("deregister", "Service deregistration complete")
98104
ctx.Log("message", "Service deregistration complete")
99105
}
100106

101107
return nil
102108
}
103109

104-
func Start(ctx *log.Context) error {
110+
func Start(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
105111
if isSystemdSupported(ctx) {
106112
serviceHandler := getSystemdHandler(ctx)
107113

@@ -111,13 +117,14 @@ func Start(ctx *log.Context) error {
111117
return err
112118
}
113119

120+
extensionEvents.LogInformationalEvent("start", "Service started")
114121
ctx.Log("message", "Service started")
115122
}
116123

117124
return nil
118125
}
119126

120-
func Disable(ctx *log.Context) error {
127+
func Disable(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
121128
if isSystemdSupported(ctx) {
122129
serviceHandler := getSystemdHandler(ctx)
123130

@@ -133,13 +140,15 @@ func Disable(ctx *log.Context) error {
133140
if err != nil {
134141
return err
135142
}
143+
144+
extensionEvents.LogInformationalEvent("disable", "Service disabled")
136145
ctx.Log("message", "Service disabled")
137146
}
138147

139148
return nil
140149
}
141150

142-
func Enable(ctx *log.Context) error {
151+
func Enable(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
143152
if isSystemdSupported(ctx) {
144153
serviceHandler := getSystemdHandler(ctx)
145154

@@ -148,13 +157,15 @@ func Enable(ctx *log.Context) error {
148157
if err != nil {
149158
return err
150159
}
160+
161+
extensionEvents.LogInformationalEvent("enable", "Service enabled")
151162
ctx.Log("message", "Service enabled")
152163
}
153164

154165
return nil
155166
}
156167

157-
func Stop(ctx *log.Context) error {
168+
func Stop(ctx *log.Context, extensionEvents *extensionevents.ExtensionEventManager) error {
158169
if isSystemdSupported(ctx) {
159170
serviceHandler := getSystemdHandler(ctx)
160171

@@ -163,6 +174,8 @@ func Stop(ctx *log.Context) error {
163174
if err != nil {
164175
return err
165176
}
177+
178+
extensionEvents.LogInformationalEvent("stop", "Service stopped")
166179
ctx.Log("message", "Service stopped")
167180
}
168181

internal/types/handlerenvironment.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ type HandlerEnvironment struct {
66
Version float64 `json:"version"`
77
Name string `json:"name"`
88
HandlerEnvironment struct {
9-
HeartbeatFile string `json:"heartbeatFile"`
10-
StatusFolder string `json:"statusFolder"`
11-
ConfigFolder string `json:"configFolder"`
12-
LogFolder string `json:"logFolder"`
9+
HeartbeatFile string `json:"heartbeatFile"`
10+
StatusFolder string `json:"statusFolder"`
11+
ConfigFolder string `json:"configFolder"`
12+
LogFolder string `json:"logFolder"`
13+
EventsFolder string `json:"eventsFolder"`
14+
EventsFolderPreview string `json:"eventsFolder_preview"`
15+
DeploymentID string `json:"deploymentid"`
16+
RoleName string `json:"rolename"`
17+
Instance string `json:"instance"`
18+
HostResolverAddress string `json:"hostResolverAddress"`
1319
}
1420
}

0 commit comments

Comments
 (0)