Skip to content

Commit

Permalink
feat(plan): add plan section support (#488)
Browse files Browse the repository at this point in the history
The plan library was originally written as a configuration schema for
the services manager (servstate). Over time the need arose to support
configurations for other managers such as checks (checkstate) and
log-targets (logstate). The configuration schema for these managers,
closely related to the services manager, has since also been built in to
the plan library.

The services manager and its related checks and log-targets
functionality will always be part of the Pebble core. However, as Pebble
is getting more functionality (additional managers) and also used as a
core in derivative projects, a more modular and dynamic approach to
extending the schema is needed.

Add an the ```SectionExtension``` interface for use by managers who
wishes to register a schema extension during Pebble startup.

Inside each layer, top level entries are now referred to as
```sections``` (built-in sections includes ```summary```,
```description```, ```services```, ```log-targets``` and ```checks```).

Each section has an associated ```field``` that is the top level key,
and if supplied by an extension, an opaque backing type ```Section```.

**SectionExtension interface:**

```
// SectionExtension allows the plan layer schema to be extended without
// adding centralised schema knowledge to the plan library.
type SectionExtension interface {
	// ParseSection returns a newly allocated concrete type containing the
	// unmarshalled section content.
	ParseSection(data yaml.Node) (LayerSection, error)

	// CombineSections returns a newly allocated concrete type containing the
	// result of combining the supplied sections in order.
	CombineSections(sections ...LayerSection) (LayerSection, error)

	// ValidatePlan takes the complete plan as input, and allows the
	// extension to validate the plan. This can be used for cross section
	// dependency validation.
	ValidatePlan(plan *Plan) error
}

type Section interface {
	// Validate checks whether the section is valid, returning an error if not.
	Validate() error
	
        // IsZero reports whether the section is empty.
	IsZero() bool
}
```

**Example usage:**

```
// New SectionExtension type
type fooExtension struct{}
func (f *fooExtension) ParseSection(data yaml.Node) (LayerSection, error) {...}
func (f *fooExtension) CombineSections(sections ...LayerSection) (LayerSection, error) {...}
func (f *fooExtension) ValidatePlan(plan *Plan) error {...}

// New Section type
type FooSection struct {
    Entries map[string]Bar `yaml:",inline,omitempty"`
}
type Bar struct {
    Name string `yaml:"name,omitempty"`
}
func (s *FooSection) Validate() error {...}
func (s *FooSection) IsZero() bool {...}
```
```
// Early startup
plan.RegisterExtension("foo", &fooExtension{})
:
// Load layers containing new section
newPlan := plan.ReadDir(layersDir)
:
// Show plan
yaml.Marshal(newPlan)
```
Example YAML output:
```
foo:
    bar1:
           name: test1
    bar2:
           name: test2          
```
  • Loading branch information
flotter authored Aug 30, 2024
1 parent 4e0e251 commit 9b7661a
Show file tree
Hide file tree
Showing 4 changed files with 1,127 additions and 13 deletions.
17 changes: 17 additions & 0 deletions internals/plan/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2024 Canonical Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 3 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package plan

var BuiltinSections = builtinSections
Loading

0 comments on commit 9b7661a

Please sign in to comment.