The Shell Operator now provides a flexible, options-based API for initialization. Here are all the available ways to create a ShellOperator instance:
import (
"github.com/flant/shell-operator/pkg/shell-operator"
"log"
)
// Simple constructor - uses default logger and no metrics storage
operator := shell_operator.NewShellOperator()import (
"context"
"github.com/flant/shell-operator/pkg/shell-operator"
"github.com/flant/shell-operator/pkg/shell-operator/config"
)
// Using the flexible configuration system
operator, err := shell_operator.NewShellOperatorWithOptions(ctx,
config.WithLogger(logger),
config.WithMetricStorage(storage),
config.WithHookMetricStorage(hookStorage),
config.WithHooksDir("/custom/hooks"),
)import (
"github.com/flant/shell-operator/pkg/shell-operator"
metricsstorage "github.com/deckhouse/deckhouse/pkg/metrics-storage"
)
builtinStorage := metricsstorage.NewStorage("builtin-metrics")
hookStorage := metricsstorage.NewStorage("hook-metrics")
operator, err := shell_operator.NewShellOperatorWithOptions(ctx,
shell_operator.WithMetricStorage(builtinStorage),
shell_operator.WithHookMetricStorage(hookStorage),
)import (
"github.com/flant/shell-operator/pkg/shell-operator"
metricsstorage "github.com/deckhouse/deckhouse/pkg/metrics-storage"
)
storage := metricsstorage.NewStorage("my-app")
// Set both metric storages at once
operator, err := shell_operator.NewShellOperatorWithOptions(ctx,
config.WithMetricStorages(storage, storage), // Same storage for both
)// When you primarily need to provide a logger
operator, err := shell_operator.NewShellOperatorWithLogger(ctx, logger,
config.WithMetricStorage(storage),
)// Development configuration with sensible defaults
cfg := shell_operator.NewDevelopmentConfig()
operator, err := shell_operator.NewShellOperatorWithConfig(ctx, cfg)
// Production configuration
cfg := shell_operator.NewProductionConfig()
operator, err := shell_operator.NewShellOperatorWithConfig(ctx, cfg)// Full control over configuration
cfg := config.NewShellOperatorConfig(
config.WithLogger(customLogger),
config.WithMetricStorage(metricsStorage),
config.WithHookMetricStorage(hookMetricsStorage),
config.WithListenAddress("0.0.0.0"),
config.WithListenPort("9090"),
config.WithHooksDir("/app/hooks"),
config.WithTempDir("/tmp/shell-operator"),
)
operator, err := shell_operator.NewShellOperatorWithConfig(ctx, cfg)All configuration options are available in the config package:
config.WithLogger(logger *log.Logger)- Set the loggerconfig.WithMetricStorage(storage)- Set the main metrics storageconfig.WithHookMetricStorage(storage)- Set the hook-specific metrics storageconfig.WithMetricStorages(metricStorage, hookStorage)- Set both metric storages at onceconfig.WithListenAddress(address string)- HTTP server listen addressconfig.WithListenPort(port string)- HTTP server listen portconfig.WithHooksDir(dir string)- Directory containing hooksconfig.WithTempDir(dir string)- Temporary directoryconfig.WithDebugUnixSocket(socket string)- Debug unix socket pathconfig.WithDebugHttpServerAddr(addr string)- Debug HTTP server address
config.WithListenConfig(address, port string)- Set both listen address and portconfig.WithDirectories(hooksDir, tempDir string)- Set both hooks and temp directoriesconfig.WithDebugConfig(unixSocket, httpAddr string)- Set both debug configurationsconfig.WithMetricStorages(metricStorage, hookStorage)- Set both metric storages
// Old way - rigid initialization
operator, err := shell_operator.Init(logger, metricsStorage)// New way - flexible configuration options
operator, err := shell_operator.NewShellOperatorWithOptions(ctx,
config.WithLogger(logger),
config.WithMetricStorage(metricsStorage),
)
// Or using convenience function
operator, err := shell_operator.NewShellOperatorWithLogger(ctx, logger,
config.WithMetricStorage(metricsStorage),
)All constructor functions return an error if configuration validation fails:
operator, err := shell_operator.NewShellOperatorWithOptions(ctx,
shell_operator.WithHooksDir(""), // Invalid: empty hooks directory
)
if err != nil {
log.Fatalf("Failed to create operator: %v", err)
}- Use separate metric storage options:
WithMetricStorage()andWithHookMetricStorage()for explicit control - Use convenience functions when appropriate:
WithMetricStorages()when both storages are the same - Use configuration options for complex setups: When you need multiple configuration parameters
- Use presets for common scenarios: Development vs Production configurations
- Always handle errors: Constructor functions validate configuration and can fail
- Prefer explicit options: Makes configuration clear and maintainable
This API provides backward compatibility while enabling flexible, maintainable configuration patterns.