Skip to content

Commit

Permalink
feat: Add error handling to service initializations
Browse files Browse the repository at this point in the history
  • Loading branch information
mattevans committed Dec 19, 2024
1 parent 5eb50c4 commit 47d0f4c
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 60 deletions.
5 changes: 4 additions & 1 deletion cmd/cli/commands/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func RegisterCommands(app *cli.App, opts *options.CommandOpts) error {
return fmt.Errorf("error creating docker sidecar service: %w", err)
}

binarySidecar := sidecar.NewBinarySidecar(log, sidecarConfig)
binarySidecar, err := sidecar.NewBinarySidecar(log, sidecarConfig, installerCfg)
if err != nil {
return fmt.Errorf("error creating binary sidecar service: %w", err)
}

return startContributoor(c, log, sidecarConfig, dockerSidecar, binarySidecar)
},
Expand Down
5 changes: 4 additions & 1 deletion cmd/cli/commands/stop/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func RegisterCommands(app *cli.App, opts *options.CommandOpts) error {
return fmt.Errorf("error creating docker sidecar service: %w", err)
}

binarySidecar := sidecar.NewBinarySidecar(log, sidecarConfig)
binarySidecar, err := sidecar.NewBinarySidecar(log, sidecarConfig, installerCfg)
if err != nil {
return fmt.Errorf("error creating binary sidecar service: %w", err)
}

return stopContributoor(c, log, sidecarConfig, dockerSidecar, binarySidecar)
},
Expand Down
11 changes: 9 additions & 2 deletions cmd/cli/commands/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,15 @@ func RegisterCommands(app *cli.App, opts *options.CommandOpts) error {
return fmt.Errorf("error creating docker sidecar service: %w", err)
}

binarySidecar := sidecar.NewBinarySidecar(log, sidecarConfig)
githubService := service.NewGitHubService(log, installerCfg)
binarySidecar, err := sidecar.NewBinarySidecar(log, sidecarConfig, installerCfg)
if err != nil {
return fmt.Errorf("error creating binary sidecar service: %w", err)
}

githubService, err := service.NewGitHubService(log, installerCfg)
if err != nil {
return fmt.Errorf("error creating github service: %w", err)
}

return updateContributoor(c, log, sidecarConfig, dockerSidecar, binarySidecar, githubService)
},
Expand Down
1 change: 1 addition & 0 deletions cmd/cli/commands/update/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

var confirmResponse bool

// For obvious reasons, we need to mock the confirm prompt. Tests can't be interactive.
func init() {
tui.Confirm = func(string) bool {
return confirmResponse
Expand Down
39 changes: 16 additions & 23 deletions internal/service/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,34 +58,32 @@ type GitHubRelease struct {

// githubService is a basic service for interacting with the GitHub API.
type githubService struct {
log *logrus.Logger
owner string
repo string
client *http.Client
config *installer.Config
log *logrus.Logger
client *http.Client
githubURL *url.URL
installerCfg *installer.Config
}

// NewGitHubService creates a new GitHubService.
func NewGitHubService(log *logrus.Logger, config *installer.Config) GitHubService {
func NewGitHubService(log *logrus.Logger, installerCfg *installer.Config) (GitHubService, error) {
githubURL, err := validateGitHubURL(installerCfg.GithubOrg, installerCfg.GithubRepo)
if err != nil {
return nil, fmt.Errorf("invalid github url: %w", err)
}

return &githubService{
log: log,
owner: config.GithubOrg,
repo: config.GithubRepo,
config: config,
log: log,
installerCfg: installerCfg,
githubURL: githubURL,
client: &http.Client{
Timeout: 10 * time.Second,
},
}
}, nil
}

// GetLatestVersion returns the latest version tag (e.g., "0.0.1") from GitHub releases.
func (s *githubService) GetLatestVersion() (string, error) {
u, err := validateGitHubURL(s.owner, s.repo)
if err != nil {
return "", fmt.Errorf("invalid GitHub URL: %w", err)
}

resp, err := s.client.Get(u.String())
resp, err := s.client.Get(s.githubURL.String())
if err != nil {
return "", fmt.Errorf("failed to fetch releases: %w", err)
}
Expand Down Expand Up @@ -164,12 +162,7 @@ func (s *githubService) GetLatestVersion() (string, error) {

// VersionExists checks if a specific version exists in the GitHub releases.
func (s *githubService) VersionExists(version string) (bool, error) {
u, err := validateGitHubURL(s.owner, s.repo)
if err != nil {
return false, fmt.Errorf("invalid GitHub URL: %w", err)
}

resp, err := s.client.Get(u.String())
resp, err := s.client.Get(s.githubURL.String())
if err != nil {
return false, fmt.Errorf("failed to fetch releases: %w", err)
}
Expand Down
14 changes: 12 additions & 2 deletions internal/service/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ func TestGitHubService_GetLatestVersion(t *testing.T) {
}
defer func() { validateGitHubURL = validate }()

svc := NewGitHubService(logrus.New(), installer.NewConfig())
svc, err := NewGitHubService(logrus.New(), installer.NewConfig())
if err != nil {
t.Errorf("NewGitHubService() error = %v", err)

return
}

got, err := svc.GetLatestVersion()
if (err != nil) != tt.wantErr {
Expand Down Expand Up @@ -143,7 +148,12 @@ func TestGitHubService_VersionExists(t *testing.T) {
}
defer func() { validateGitHubURL = validate }()

svc := NewGitHubService(logrus.New(), installer.NewConfig())
svc, err := NewGitHubService(logrus.New(), installer.NewConfig())
if err != nil {
t.Errorf("NewGitHubService() error = %v", err)

return
}

exists, err := svc.VersionExists(tt.version)

Expand Down
52 changes: 22 additions & 30 deletions internal/sidecar/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"regexp"
"runtime"

"github.com/ethpandaops/contributoor-installer/internal/installer"
"github.com/ethpandaops/contributoor-installer/internal/tui"
"github.com/mitchellh/go-homedir"
"github.com/sirupsen/logrus"
Expand All @@ -23,55 +24,42 @@ type BinarySidecar interface {

// binarySidecar is a basic service for interacting with the contributoor binary.
type binarySidecar struct {
logger *logrus.Logger
config ConfigManager
stdout *os.File
stderr *os.File
logger *logrus.Logger
config ConfigManager
installerCfg *installer.Config
stdout *os.File
stderr *os.File
}

// NewBinarySidecar creates a new BinarySidecar.
func NewBinarySidecar(logger *logrus.Logger, configService ConfigManager) BinarySidecar {
func NewBinarySidecar(logger *logrus.Logger, configService ConfigManager, installerCfg *installer.Config) (BinarySidecar, error) {
expandedDir, err := homedir.Expand(configService.Get().ContributoorDirectory)
if err != nil {
logger.Errorf("Failed to expand config path: %v", err)

return &binarySidecar{
logger: logger,
config: configService,
}
return nil, fmt.Errorf("failed to expand config path: %w", err)
}

logsDir := filepath.Join(expandedDir, "logs")

// Open log files
stdout, err := os.OpenFile(filepath.Join(logsDir, "debug.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
logger.Errorf("Failed to open stdout log file: %v", err)

return &binarySidecar{
logger: logger,
config: configService,
}
return nil, fmt.Errorf("failed to open stdout log file: %w", err)
}

stderr, err := os.OpenFile(filepath.Join(logsDir, "service.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
stdout.Close()

logger.Errorf("Failed to open stderr log file: %v", err)

return &binarySidecar{
logger: logger,
config: configService,
}
return nil, fmt.Errorf("failed to open stderr log file: %w", err)
}

return &binarySidecar{
logger: logger,
config: configService,
stdout: stdout,
stderr: stderr,
}
logger: logger,
config: configService,
stdout: stdout,
stderr: stderr,
installerCfg: installerCfg,
}, nil
}

// Start starts the binary service.
Expand Down Expand Up @@ -208,7 +196,9 @@ func (s *binarySidecar) Update() error {

// Download and verify checksums.
checksumURL := fmt.Sprintf(
"https://github.com/ethpandaops/contributoor/releases/download/v%s/contributoor_%s_checksums.txt",
"https://github.com/%s/%s/releases/download/v%s/contributoor_%s_checksums.txt",
s.installerCfg.GithubOrg,
s.installerCfg.GithubRepo,
cfg.Version,
cfg.Version,
)
Expand All @@ -232,7 +222,9 @@ func (s *binarySidecar) Update() error {
}

binaryURL := fmt.Sprintf(
"https://github.com/ethpandaops/contributoor/releases/download/v%s/contributoor_%s_%s_%s.tar.gz",
"https://github.com/%s/%s/releases/download/v%s/contributoor_%s_%s_%s.tar.gz",
s.installerCfg.GithubOrg,
s.installerCfg.GithubRepo,
cfg.Version,
cfg.Version,
platform,
Expand Down
2 changes: 1 addition & 1 deletion internal/sidecar/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func (s *dockerSidecar) IsRunning() (bool, error) {
func (s *dockerSidecar) Update() error {
cfg := s.configService.Get()

//nolint:gosec // validateComposePath() and filepath.Clean() in-use.
image := fmt.Sprintf("%s:%s", s.installerCfg.DockerImage, cfg.Version)

cmd := exec.Command("docker", "pull", image)
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to pull image %s: %w\nOutput: %s", image, err, string(output))
Expand Down

0 comments on commit 47d0f4c

Please sign in to comment.