Skip to content

Commit

Permalink
hive: Add title to Module() and enforce format
Browse files Browse the repository at this point in the history
To support short module identifiers for use in logs the module
name is now an identifier with forced format (lower-case, 30 chars).

This however hampers readability when visualizing the hive, so for
this purpose we add a title to the module. This is also forced
to only contain alpha-numeric characters and be at most 80 characters
in length to mostly keep the module line in "PrintObjects" short enough to
fit on one line.

Signed-off-by: Jussi Maki <[email protected]>
  • Loading branch information
joamaki authored and aanm committed Nov 1, 2022
1 parent e946cbb commit b8e8ca4
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 10 deletions.
2 changes: 2 additions & 0 deletions clustermesh-apiserver/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func (HealthAPIServerConfig) Flags(flags *pflag.FlagSet) {

var healthAPIServerCell = cell.Module(
"health-api-server",
"ClusterMesh Health API Server",

cell.Config(HealthAPIServerConfig{}),
cell.Invoke(registerHealthAPIServer),
)
Expand Down
2 changes: 2 additions & 0 deletions operator/cmd/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type LeaderLifecycle struct {
func WithLeaderLifecycle(cells ...cell.Cell) cell.Cell {
return cell.Module(
"leader-lifecycle",
"Operator Leader Lifecycle",

cell.Provide(
func() *LeaderLifecycle { return &LeaderLifecycle{} },
),
Expand Down
1 change: 1 addition & 0 deletions operator/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ var (
// Used also in tests.
OperatorCell = cell.Module(
"operator",
"Cilium Operator",

cell.Invoke(
registerOperatorHooks,
Expand Down
2 changes: 2 additions & 0 deletions pkg/gops/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
func Cell(defaultPort uint16) cell.Cell {
return cell.Module(
"gops",
"Gops Agent",

cell.Config(GopsConfig{GopsPort: defaultPort}),
cell.Invoke(registerGopsHooks),
)
Expand Down
49 changes: 39 additions & 10 deletions pkg/hive/cell/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,59 @@
package cell

import (
"fmt"
"regexp"

"github.com/sirupsen/logrus"

"github.com/cilium/cilium/pkg/logging/logfields"
)

// Module creates a named set of cells.
// The name will be included in the object dump (hive.PrintObjects) and
// in the dot graph (hive.PrintDotGraph).
func Module(name string, cells ...Cell) Cell {
return &module{name, cells}
// Module creates a scoped set of cells with a given identifier.
//
// The id and title will be included in the object dump (hive.PrintObjects).
// The id must be lower-case, at most 30 characters and only contain [a-z0-9-_].
// Title can contain [a-zA-Z0-9_- ] and must be shorter than 80 characters.
//
// Private constructors with a module (ProvidePrivate) are only accessible
// within this module and its sub-modules.
func Module(id, title string, cells ...Cell) Cell {
validateIdAndTitle(id, title)
return &module{id, title, cells}
}

var (
idRegex = regexp.MustCompile(`^[a-z][a-z0-9_\-]{1,30}$`)
titleRegex = regexp.MustCompile(`^[a-zA-Z0-9_\- ]{1,80}$`)
)

func validateIdAndTitle(id, title string) {
if !idRegex.MatchString(id) {
panic(fmt.Sprintf("Invalid hive.Module id: %q, expected to id match %s", id, idRegex))
}
if !titleRegex.MatchString(title) {
panic(fmt.Sprintf("Invalid hive.Module title: %q, expected to title match %s", title, titleRegex))
}
}

// module is a named set of cells.
type module struct {
name string
// id is the module identity. It is shown in object output and is used to derive
// the scoped logger.
id string

// title is a human-readable short title for the module. Shown in object output
// alongside the identifier.
title string

cells []Cell
}

func (m *module) logger(log logrus.FieldLogger) logrus.FieldLogger {
return log.WithField(logfields.LogSubsys, m.name)
return log.WithField(logfields.LogSubsys, m.id)
}

func (m *module) Apply(c container) error {
scope := c.Scope(m.name)
scope := c.Scope(m.id)

if err := scope.Decorate(m.logger); err != nil {
return err
Expand All @@ -42,7 +71,7 @@ func (m *module) Apply(c container) error {
}

func (m *module) Info() Info {
n := NewInfoNode("Ⓜ️ " + m.name)
n := NewInfoNode("Ⓜ️ " + m.id + " (" + m.title + ")")
for _, cell := range m.cells {
n.Add(cell.Info())
n.AddBreak()
Expand Down
2 changes: 2 additions & 0 deletions pkg/hive/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
// way around.
var exampleCell = cell.Module(
"example",
"Example",

cell.Config(defaultExampleConfig),
cell.Provide(newExampleObject),
cell.ProvidePrivate(newPrivateObject),
Expand Down
4 changes: 4 additions & 0 deletions pkg/hive/hive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestHiveGoodConfig(t *testing.T) {
var cfg Config
testCell := cell.Module(
"test",
"Test Module",
cell.Config(Config{}),
cell.Invoke(func(c Config) {
cfg = c
Expand Down Expand Up @@ -68,6 +69,7 @@ func (BadConfig) Flags(flags *pflag.FlagSet) {
func TestHiveBadConfig(t *testing.T) {
testCell := cell.Module(
"test",
"Test Module",
cell.Config(BadConfig{}),
cell.Invoke(func(c BadConfig) {}),
)
Expand All @@ -88,6 +90,7 @@ func TestProvideInvoke(t *testing.T) {

testCell := cell.Module(
"test",
"Test Module",
cell.Provide(func() *SomeObject { return &SomeObject{10} }),
cell.Invoke(func(*SomeObject) { invoked = true }),
)
Expand All @@ -106,6 +109,7 @@ func TestProvidePrivate(t *testing.T) {

testCell := cell.Module(
"test",
"Test Module",
cell.ProvidePrivate(func() *SomeObject { return &SomeObject{10} }),
cell.Invoke(func(*SomeObject) { invoked = true }),
)
Expand Down
1 change: 1 addition & 0 deletions pkg/k8s/client/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
// used by Cilium.
var Cell = cell.Module(
"k8s-client",
"Kubernetes Client",

cell.Config(defaultConfig),
cell.Provide(newClientset),
Expand Down
4 changes: 4 additions & 0 deletions pkg/k8s/resource/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func main() {

var resourcesCell = cell.Module(
"resources",
"Kubernetes Pod and Service resources",

cell.Provide(
func(lc hive.Lifecycle, c client.Clientset) resource.Resource[*corev1.Pod] {
if !c.IsEnabled() {
Expand All @@ -75,6 +77,8 @@ var resourcesCell = cell.Module(

var printServicesCell = cell.Module(
"print-services",
"Prints Kubernetes Services",

cell.Provide(newPrintServices),
)

Expand Down

0 comments on commit b8e8ca4

Please sign in to comment.