manager

package
v0.39.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2024 License: MPL-2.0 Imports: 24 Imported by: 89

Documentation

Overview

Example

This example demonstrates a minimum configuration to create, configure, and use a consul-template/manager from code. It is not comprehensive and does not demonstrate the dependencies, polling, and rerendering features available in the manager

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"path"

	"github.com/hashicorp/consul-template/config"
	"github.com/hashicorp/consul-template/manager"
)

func main() {
	// Consul-template uses the standard logger, which needs to be silenced
	// in this example
	log.SetOutput(io.Discard)

	// Define a template
	tmpl := `{{ "foo\nbar\n" | split "\n" | toJSONPretty }}`

	// Make a destination path to write the rendered template to
	outPath := path.Join(os.TempDir(), "tmpl.out") // Use the temp dir
	defer os.RemoveAll(outPath)                    // Defer the file cleanup

	// Create a TemplateConfig
	tCfg := config.DefaultTemplateConfig() // Start with the default configuration
	tCfg.Contents = &tmpl                  // Add the template to the configuration
	tCfg.Destination = &outPath            // Set the output destination
	tCfg.Finalize()                        // Finalize the template config

	// Create the (consul-template) Config
	cfg := config.DefaultConfig()                 // Start with default configuration
	cfg.Once = true                               // Perform a one-shot render
	cfg.Templates = &config.TemplateConfigs{tCfg} // Add the template created earlier
	cfg.Finalize()                                // Finalize the consul-template configuration

	// Instantiate a runner with the config and with `dry` == false
	runner, err := manager.NewRunner(cfg, false)
	if err != nil {
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}

	go runner.Start() // The runner blocks, so must be started in a goroutine
	defer runner.Stop()

	select {
	// When the runner is successfully done, it will emit a message on DoneCh
	case <-runner.DoneCh:
		break

	// When the runner encounters an error, it will emit an error on ErrCh and
	// then return.
	case err := <-runner.ErrCh:
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}

	// Read the rendered template from disk
	if b, e := os.ReadFile(outPath); e == nil {
		fmt.Println(string(b))
	} else {
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}
}
Output:

[
  "foo",
  "bar"
]
Example (CustomFuncMap)

ExampleCustomFuncMap demonstrates a minimum consul-template/manager configuration and supply custom templates to consul-template's internal text/template based renderer.

It is not comprehensive and does not demonstrate the dependencies, polling, and rerendering features available in the manager

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"path"
	"text/template"

	"github.com/hashicorp/consul-template/config"
	"github.com/hashicorp/consul-template/manager"
)

func main() {
	// Consul-template uses the standard logger, which needs to be silenced
	// in this example
	log.SetOutput(io.Discard)

	// Create a simple function to add to CT
	greet := func(n string) string { return "Hello, " + n + "!" }
	fm := template.FuncMap{"greet": greet}

	// Define a template that uses the new function
	tmpl := `{{greet "World"}}`

	// Make a destination path to write the rendered template to
	outPath := path.Join(os.TempDir(), "tmpl.out") // Use the temp dir
	defer os.RemoveAll(outPath)                    // Defer the file cleanup

	// Create a TemplateConfig
	tc1 := config.DefaultTemplateConfig() // Start with the default configuration
	tc1.ExtFuncMap = fm                   // Use the ExtFuncMap to add greet
	tc1.Contents = &tmpl                  // Add the template to the configuration
	tc1.Destination = &outPath            // Set the output destination
	tc1.Finalize()                        // Finalize the template config

	// Create the (consul-template) Config
	cfg := config.DefaultConfig()                // Start with default configuration
	cfg.Once = true                              // Perform a one-shot render
	cfg.Templates = &config.TemplateConfigs{tc1} // Add the template created earlier
	cfg.Finalize()                               // Finalize the consul-template configuration

	// Instantiate a runner with the config and with `dry` == false
	runner, err := manager.NewRunner(cfg, false)
	if err != nil {
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}

	go runner.Start() // The runner blocks, so must be started in a goroutine
	defer runner.Stop()

	select {

	// When the runner is successfully done, it will emit a message on DoneCh
	case <-runner.DoneCh:
		break

	// When the runner encounters an error, it will emit an error on ErrCh and
	// then return.
	case err := <-runner.ErrCh:
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}

	// Read the rendered template from disk
	if b, e := os.ReadFile(outPath); e == nil {
		fmt.Println(string(b))
	} else {
		fmt.Printf("[ERROR] %s\n", err.Error())
		return
	}

}
Output:

Hello, World!

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewClientSet added in v0.29.3

func NewClientSet(c *config.Config) (*dep.ClientSet, error)

NewClientSet creates a new client set from the given config.

Types

type DedupManager

type DedupManager struct {
	// contains filtered or unexported fields
}

DedupManager is used to de-duplicate which instance of Consul-Template is handling each template. For each template, a lock path is determined using the MD5 of the template. This path is used to elect a "leader" instance.

The leader instance operations like usual, but any time a template is rendered, any of the data required for rendering is stored in the Consul KV store under the lock path.

The follower instances depend on the leader to do the primary watching and rendering, and instead only watch the aggregated data in the KV. Followers wait for updates and re-render the template.

If a template depends on 50 views, and is running on 50 machines, that would normally require 2500 blocking queries. Using deduplication, one instance has 50 view queries, plus 50 additional queries on the lock path for a total of 100.

func NewDedupManager

func NewDedupManager(config *config.DedupConfig, clients *dep.ClientSet, brain *template.Brain, templates []*template.Template) (*DedupManager, error)

NewDedupManager creates a new Dedup manager

func (*DedupManager) IsLeader

func (d *DedupManager) IsLeader(tmpl *template.Template) bool

IsLeader checks if we are currently the leader instance

func (*DedupManager) Start

func (d *DedupManager) Start() error

Start is used to start the de-duplication manager

func (*DedupManager) Stop

func (d *DedupManager) Stop() error

Stop is used to stop the de-duplication manager

func (*DedupManager) UpdateCh

func (d *DedupManager) UpdateCh() <-chan struct{}

UpdateCh returns a channel to watch for dependency updates

func (*DedupManager) UpdateDeps

func (d *DedupManager) UpdateDeps(t *template.Template, deps []dep.Dependency) error

UpdateDeps is used to update the values of the dependencies for a template

type ErrChildDied

type ErrChildDied struct {
	// contains filtered or unexported fields
}

ErrChildDied is the error returned when the child process prematurely dies.

func NewErrChildDied

func NewErrChildDied(c int) *ErrChildDied

NewErrChildDied creates a new error with the given exit code.

func (*ErrChildDied) Error

func (e *ErrChildDied) Error() string

Error implements the error interface.

func (*ErrChildDied) ExitStatus

func (e *ErrChildDied) ExitStatus() int

ExitStatus implements the ErrExitable interface.

type ErrExitable

type ErrExitable interface {
	ExitStatus() int
}

ErrExitable is an interface that defines an integer ExitStatus() function.

type RenderEvent

type RenderEvent struct {
	// Missing is the list of dependencies that we do not yet have data for, but
	// are contained in the watcher. This is different from unwatched dependencies,
	// which includes dependencies the watcher has not yet started querying for
	// data.
	MissingDeps *dep.Set

	// Template is the template attempting to be rendered.
	Template *template.Template

	// Contents is the raw, rendered contents from the template.
	Contents []byte

	// TemplateConfigs is the list of template configs that correspond to this
	// template.
	TemplateConfigs []*config.TemplateConfig

	// Unwatched is the list of dependencies that are not present in the watcher.
	// This value may change over time due to the n-pass evaluation.
	UnwatchedDeps *dep.Set

	// UpdatedAt is the last time this render event was updated.
	UpdatedAt time.Time

	// Used is the full list of dependencies seen in the template. Because of
	// the n-pass evaluation, this number can change over time. The dependencies
	// in this list may or may not have data. This just contains the list of all
	// dependencies parsed out of the template with the current data.
	UsedDeps *dep.Set

	// WouldRender determines if the template would have been rendered. A template
	// would have been rendered if all the dependencies are satisfied, but may
	// not have actually rendered if the file was already present or if an error
	// occurred when trying to write the file.
	WouldRender bool

	// LastWouldRender marks the last time the template would have rendered.
	LastWouldRender time.Time

	// DidRender determines if the Template was actually written to disk. In dry
	// mode, this will always be false, since templates are not written to disk
	// in dry mode. A template is only rendered to disk if all dependencies are
	// satisfied and the template is not already in place with the same contents.
	DidRender bool

	// LastDidRender marks the last time the template was written to disk.
	LastDidRender time.Time

	// ForQuiescence determines if this event is returned early in the
	// render loop due to quiescence. When evaluating if all templates have
	// been rendered we need to know if the event is triggered by quiescence
	// and if we can skip evaluating it as a render event for those purposes
	ForQuiescence bool

	// Error contains the error encountered while rendering the template.
	Error error
}

RenderEvent captures the time and events that occurred for a template rendering.

type Runner

type Runner struct {
	// ErrCh and DoneCh are channels where errors and finish notifications occur.
	ErrCh  chan error
	DoneCh chan struct{}

	// ServerErrCh is a channel to surface error responses from the server up the calling stack
	// and will only hold a maximum of one error at a time
	ServerErrCh chan error

	// Env represents a custom set of environment variables to populate the
	// template and command runtime with. These environment variables will be
	// available in both the command's environment as well as the template's
	// environment.
	// NOTE this is only used when CT is being used as a library.
	Env map[string]string
	// contains filtered or unexported fields
}

Runner responsible rendering Templates and invoking Commands.

func NewRunner

func NewRunner(config *config.Config, dry bool) (*Runner, error)

NewRunner accepts a slice of TemplateConfigs and returns a pointer to the new Runner and any error that occurred during creation.

func (*Runner) Receive

func (r *Runner) Receive(d dep.Dependency, data interface{})

Receive accepts a Dependency and data for that dep. This data is cached on the Runner. This data is then used to determine if a Template is "renderable" (i.e. all its Dependencies have been downloaded at least once).

func (*Runner) RenderEventCh added in v0.19.1

func (r *Runner) RenderEventCh() <-chan struct{}

RenderEventCh returns a channel that will be triggered when there is a new render event.

func (*Runner) RenderEvents

func (r *Runner) RenderEvents() map[string]*RenderEvent

RenderEvents returns the render events for each template was rendered. The map is keyed by template ID.

func (*Runner) Run

func (r *Runner) Run() error

Run iterates over each template in this Runner and conditionally executes the template rendering and command execution.

The template is rendered atomically. If and only if the template render completes successfully, the optional commands will be executed, if given. Please note that all templates are rendered **and then** any commands are executed.

func (*Runner) SetErrStream added in v0.19.4

func (r *Runner) SetErrStream(err io.Writer)

SetErrStream modifies runner error stream. Defaults to stderr.

func (*Runner) SetOutStream added in v0.19.4

func (r *Runner) SetOutStream(out io.Writer)

SetOutStream modifies runner output stream. Defaults to stdout.

func (*Runner) SetReadyChannel added in v0.39.1

func (r *Runner) SetReadyChannel(ch chan struct{})

SetReadyChannel sets the readyCh channel which is used to signal readiness to the systemd init system. The channel should be a struct{} channel, and when an empty struct is sent on this channel, it will trigger a notification to systemd that the application is ready.

func (*Runner) Signal

func (r *Runner) Signal(s os.Signal) error

Signal sends a signal to the child process, if it exists. Any errors that occur are returned.

func (*Runner) Start

func (r *Runner) Start()

Start begins the polling for this runner. Any errors that occur will cause this function to push an item onto the runner's error channel and the halt execution. This function is blocking and should be called as a goroutine.

func (*Runner) Stop

func (r *Runner) Stop()

Stop halts the execution of this runner and its subprocesses.

func (*Runner) StopImmediately added in v0.22.0

func (r *Runner) StopImmediately()

StopImmediately behaves like Stop but won't wait for any splay on any child process it may be running.

func (*Runner) TemplateConfigMapping

func (r *Runner) TemplateConfigMapping() map[string][]*config.TemplateConfig

TemplateConfigMapping returns a mapping between the template ID and the set of TemplateConfig represented by the template ID

func (*Runner) TemplateRenderedCh

func (r *Runner) TemplateRenderedCh() <-chan struct{}

TemplateRenderedCh returns a channel that will be triggered when one or more templates are rendered.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL