diff --git a/ocis/pkg/command/ocs.go b/ocis/pkg/command/ocs.go index f919719915..e576c086c0 100644 --- a/ocis/pkg/command/ocs.go +++ b/ocis/pkg/command/ocs.go @@ -4,6 +4,7 @@ package command import ( "github.com/micro/cli/v2" + "github.com/owncloud/ocis/ocis/pkg/version" "github.com/owncloud/ocis/ocs/pkg/command" svcconfig "github.com/owncloud/ocis/ocs/pkg/config" "github.com/owncloud/ocis/ocs/pkg/flagset" @@ -18,6 +19,9 @@ func OCSCommand(cfg *config.Config) *cli.Command { Usage: "Start ocs server", Category: "Extensions", Flags: flagset.ServerWithConfig(cfg.OCS), + Subcommands: []*cli.Command{ + command.PrintVersion(cfg.OCS), + }, Action: func(ctx *cli.Context) error { ocsCommand := command.Server(configureOCS(cfg)) @@ -34,6 +38,7 @@ func configureOCS(cfg *config.Config) *svcconfig.Config { cfg.OCS.Log.Level = cfg.Log.Level cfg.OCS.Log.Pretty = cfg.Log.Pretty cfg.OCS.Log.Color = cfg.Log.Color + cfg.OCS.Service.Version = version.String if cfg.Tracing.Enabled { cfg.OCS.Tracing.Enabled = cfg.Tracing.Enabled diff --git a/ocs/changelog/unreleased/add-version-command.md b/ocs/changelog/unreleased/add-version-command.md new file mode 100644 index 0000000000..d17b35df14 --- /dev/null +++ b/ocs/changelog/unreleased/add-version-command.md @@ -0,0 +1,6 @@ +Enhancement: Add version command + +Added a command to list the currently running services with their respective version. +Also added a metrics entry for build information which includes the service version. + +https://github.com/owncloud/product/issues/226 diff --git a/ocs/pkg/command/root.go b/ocs/pkg/command/root.go index 07ee6374ba..33cea710a5 100644 --- a/ocs/pkg/command/root.go +++ b/ocs/pkg/command/root.go @@ -32,12 +32,14 @@ func Execute() error { Flags: flagset.RootWithConfig(cfg), Before: func(c *cli.Context) error { + cfg.Service.Version = version.String return ParseConfig(c, cfg) }, Commands: []*cli.Command{ Server(cfg), Health(cfg), + PrintVersion(cfg), }, } diff --git a/ocs/pkg/command/server.go b/ocs/pkg/command/server.go index b14f6988e8..76e6b66ba7 100644 --- a/ocs/pkg/command/server.go +++ b/ocs/pkg/command/server.go @@ -135,6 +135,8 @@ func Server(cfg *config.Config) *cli.Command { defer cancel() + metrics.BuildInfo.WithLabelValues(cfg.Service.Version).Set(1) + { server, err := http.Server( http.Logger(logger), diff --git a/ocs/pkg/command/version.go b/ocs/pkg/command/version.go new file mode 100644 index 0000000000..6f4eae4872 --- /dev/null +++ b/ocs/pkg/command/version.go @@ -0,0 +1,45 @@ +package command + +import ( + "fmt" + "os" + + "github.com/micro/cli/v2" + "github.com/micro/go-micro/v2/registry/mdns" + tw "github.com/olekukonko/tablewriter" + "github.com/owncloud/ocis/ocs/pkg/config" + "github.com/owncloud/ocis/ocs/pkg/flagset" +) + +// PrintVersion prints the service versions of all running instances. +func PrintVersion(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "version", + Usage: "Print the versions of the running instances", + Flags: flagset.ListOcsWithConfig(cfg), + Action: func(c *cli.Context) error { + reg := mdns.NewRegistry() + services, err := reg.GetService(cfg.Service.Namespace + "." + cfg.Service.Name) + if err != nil { + fmt.Println(fmt.Errorf("could not get ocs services from the registry: %v", err)) + return err + } + + if len(services) == 0 { + fmt.Println("No running ocs service found.") + return nil + } + + table := tw.NewWriter(os.Stdout) + table.SetHeader([]string{"Version", "Address", "Id"}) + table.SetAutoFormatHeaders(false) + for _, s := range services { + for _, n := range s.Nodes { + table.Append([]string{s.Version, n.Address, n.Id}) + } + } + table.Render() + return nil + }, + } +} diff --git a/ocs/pkg/config/config.go b/ocs/pkg/config/config.go index 3e848a282b..b8589533d7 100644 --- a/ocs/pkg/config/config.go +++ b/ocs/pkg/config/config.go @@ -17,9 +17,15 @@ type Debug struct { // HTTP defines the available http configuration. type HTTP struct { - Addr string + Addr string + Root string +} + +// Service defines the available service configuration. +type Service struct { + Name string Namespace string - Root string + Version string } // Tracing defines the available tracing configuration. @@ -44,6 +50,7 @@ type Config struct { HTTP HTTP Tracing Tracing TokenManager TokenManager + Service Service } // New initializes a new configuration with or without defaults. diff --git a/ocs/pkg/flagset/flagset.go b/ocs/pkg/flagset/flagset.go index 67fc4ffd25..0e030a35c0 100644 --- a/ocs/pkg/flagset/flagset.go +++ b/ocs/pkg/flagset/flagset.go @@ -128,7 +128,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { Value: "com.owncloud.web", Usage: "Set the base namespace for the http namespace", EnvVars: []string{"OCS_NAMESPACE"}, - Destination: &cfg.HTTP.Namespace, + Destination: &cfg.Service.Namespace, + }, + &cli.StringFlag{ + Name: "name", + Value: "ocs", + Usage: "Service name", + EnvVars: []string{"OCS_NAME"}, + Destination: &cfg.Service.Name, }, &cli.StringFlag{ Name: "http-root", @@ -147,3 +154,23 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, } } + +// ListOcsWithConfig applies the config to the list commands flagset. +func ListOcsWithConfig(cfg *config.Config) []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: "http-namespace", + Value: "com.owncloud.web", + Usage: "Set the base namespace for the http namespace", + EnvVars: []string{"OCS_NAMESPACE"}, + Destination: &cfg.Service.Namespace, + }, + &cli.StringFlag{ + Name: "name", + Value: "ocs", + Usage: "Service name", + EnvVars: []string{"OCS_NAME"}, + Destination: &cfg.Service.Name, + }, + } +} diff --git a/ocs/pkg/metrics/metrics.go b/ocs/pkg/metrics/metrics.go index 13d533260e..2ed09458b6 100644 --- a/ocs/pkg/metrics/metrics.go +++ b/ocs/pkg/metrics/metrics.go @@ -1,5 +1,7 @@ package metrics +import "github.com/prometheus/client_golang/prometheus" + var ( // Namespace defines the namespace for the defines metrics. Namespace = "ocis" @@ -11,6 +13,7 @@ var ( // Metrics defines the available metrics of this service. type Metrics struct { // Counter *prometheus.CounterVec + BuildInfo *prometheus.GaugeVec } // New initializes the available metrics. @@ -22,11 +25,21 @@ func New() *Metrics { // Name: "greet_total", // Help: "How many greeting requests processed", // }, []string{}), + BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: Subsystem, + Name: "build_info", + Help: "Build Information", + }, []string{"version"}), } // prometheus.Register( // m.Counter, // ) + _ = prometheus.Register( + m.BuildInfo, + ) + return m } diff --git a/ocs/pkg/server/debug/server.go b/ocs/pkg/server/debug/server.go index b8b4f1b6e0..f3b4eaa1a4 100644 --- a/ocs/pkg/server/debug/server.go +++ b/ocs/pkg/server/debug/server.go @@ -4,9 +4,8 @@ import ( "io" "net/http" - "github.com/owncloud/ocis/ocs/pkg/config" - "github.com/owncloud/ocis/ocs/pkg/version" "github.com/owncloud/ocis/ocis-pkg/service/debug" + "github.com/owncloud/ocis/ocs/pkg/config" ) // Server initializes the debug service and server. @@ -15,8 +14,8 @@ func Server(opts ...Option) (*http.Server, error) { return debug.NewService( debug.Logger(options.Logger), - debug.Name("ocs"), - debug.Version(version.String), + debug.Name(options.Config.Service.Name), + debug.Version(options.Config.Service.Version), debug.Address(options.Config.Debug.Addr), debug.Token(options.Config.Debug.Token), debug.Pprof(options.Config.Debug.Pprof), diff --git a/ocs/pkg/server/http/server.go b/ocs/pkg/server/http/server.go index 4b85aa39dc..08aa12e2af 100644 --- a/ocs/pkg/server/http/server.go +++ b/ocs/pkg/server/http/server.go @@ -1,10 +1,9 @@ package http import ( - svc "github.com/owncloud/ocis/ocs/pkg/service/v0" - "github.com/owncloud/ocis/ocs/pkg/version" "github.com/owncloud/ocis/ocis-pkg/middleware" "github.com/owncloud/ocis/ocis-pkg/service/http" + svc "github.com/owncloud/ocis/ocs/pkg/service/v0" ) // Server initializes the http service and server. @@ -13,9 +12,9 @@ func Server(opts ...Option) (http.Service, error) { service := http.NewService( http.Logger(options.Logger), - http.Name("ocs"), - http.Version(version.String), - http.Namespace(options.Config.HTTP.Namespace), + http.Name(options.Config.Service.Name), + http.Version(options.Config.Service.Version), + http.Namespace(options.Config.Service.Namespace), http.Address(options.Config.HTTP.Addr), http.Context(options.Context), http.Flags(options.Flags...), @@ -31,8 +30,8 @@ func Server(opts ...Option) (http.Service, error) { middleware.Cors, middleware.Secure, middleware.Version( - "ocs", - version.String, + options.Config.Service.Name, + options.Config.Service.Version, ), middleware.Logger( options.Logger,