viaduct

package module
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: May 12, 2024 License: MIT Imports: 20 Imported by: 0

README

Viaduct CI Go Reference

A configuration management framework written in Go.

The framework allows you to write configuration in plain Go, which you would then compile and distribute as a binary to the target machines.

This means that you don't need to bootstrap an instance with configuration files or a runtime environment (eg "install chef"): simply download the binary, and run it!

I'm using Viaduct to set up my personal development environment at surminus/myduct.

Getting started

Create a project in main.go and create a new manifest:

import (
        "github.com/surminus/viaduct"
)

func main() {
        // m is our manifest object
        m := viaduct.New()
}

A standard set of resources are found in the resources package.

To add them:

import (
        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

func main() {
        m := viaduct.New()

        m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"})
}

All resources will run concurrently, so in this example we will declare a dependency so that the directory is created before the file:

func main() {
        m := viaduct.New()

        dir := m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"}, dir)
}

When you've added all the resources you need, we can apply them:

func main() {
        m := viaduct.New()

        dir := m.Add(&resources.Directory{Path: "/tmp/test"})
        m.Add(&resources.File{Path: "/tmp/test/foo"}, dir)

        m.Run()
}

Compile the package and run it:

go build -o viaduct
./viaduct

See the example in the examples directory.

CLI

The compiled binary comes with runtime flags:

./viaduct --help

Embedded files and templates

There are helper functions to allow us to use the embed package to flexibly work with files and templates.

To create a template, first create a file in templates/test.txt using Go template syntax:

My cat is called {{ .Name }}

We can then generate the data to create our file:

import (
        "embed"

        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

//go:embed templates
var templates embed.FS

func main() {
        m := viaduct.New()

        template := resources.NewTemplate(
                templates,
                "templates/test.txt",
                struct{ Name string }{Name: "Bella"},
        )

        // CreateFile is a helper function that takes two arguments
        m.Add(resources.CreateFile("test/foo", template))
}

The EmbeddedFile function works in a similar way, but without variables.

Attributes

Like any good configuration management tool, we also have access to node attributes under the Attribute variable:

import (
        "fmt"

        "github.com/surminus/viaduct"
        "github.com/surminus/viaduct/resources"
)

func main() {
        m := viaduct.New()

        // E is an alias for creating an Execute resource
        m.Add(resources.Exec(fmt.Sprintf("echo \"Hello %s!\"", viaduct.Attribute.User.Username)))
}

Sudo support

If you require to perform actions that require sudo access, such as using the Package resource, or creating files using File, then you should run the executible using sudo.

Otherwise, assigning permissions should be achieved by explicitly setting the user and group in the resource.

Alternatively, you can set a default user attribute:

func main() {
        viaduct.Attribute.SetUser("laura")
        m := viaduct.New()

        // Will print my home directory
        m.Add(resources.Echo(viaduct.Attribute.User.Homedir))

        m.Run()
}

Using custom resources

Custom resources just need to implement the ResourceAttributes interface.

See the example custom resource in the examples directory.

Documentation

Index

Constants

View Source
const LinuxOsReleaseFile = "/etc/os-release"

Variables

View Source
var (
	Attribute SystemAttributes
	Config    Configs
)

Functions

func CommandFalse added in v0.3.1

func CommandFalse(command string) bool

CommandFalse is the same as True, but returns the opposite.

func CommandOutput added in v0.3.1

func CommandOutput(command string) string

CommandOutput will run a command and provide the output. Can be useful in if statements for checking arbitary values. Will not error, but will return an empty string.

func CommandTrue added in v0.3.1

func CommandTrue(command string) bool

CommandTrue is similar to the "Unless" parameter found in some resources, but instead can be used freeform within configuration. If it exits cleanly, then it returns true.

func DirExists added in v0.1.11

func DirExists(path string) bool

DirExists returns true if the file exists, and is a directory

func ExpandPath added in v0.1.9

func ExpandPath(path string) string

ExpandPath ensures that "~" are expanded.

func ExpandPathRoot added in v0.1.11

func ExpandPathRoot(path string) string

ExpandPathRoot is like ExpandPath, but ignores the user attribute

func FileContents added in v0.3.0

func FileContents(path string) string

FileContents simply returns the file contents as a string

func FileExists added in v0.1.10

func FileExists(path string) bool

FileExists returns true if the file exists

func FileSize added in v0.3.1

func FileSize(path string) int64

FileSize returns the file size in bytes

func IsDirectory added in v0.3.3

func IsDirectory(path string) bool

IsDirectory is an alias for DirExists

func IsRoot added in v0.3.0

func IsRoot() bool

IsRoot returns true if the user is root

func IsUbuntu added in v0.1.9

func IsUbuntu() bool

IsUbuntu returns true if the distribution is Ubuntu

func LinkExists added in v0.3.0

func LinkExists(path string) bool

LinkExists returns true if the symlink exists

func ListFiles added in v0.3.3

func ListFiles(path string) (files []string, err error)

ListFiles returns all files within a path

func Log added in v0.3.1

func Log(v ...interface{})

func LoggerOutput added in v0.3.0

func LoggerOutput(resource, action string, v ...interface{}) string

func MatchChmod added in v0.1.11

func MatchChmod(path string, perms fs.FileMode) bool

MatchChmod returns true if the permissions of the path match

func MatchChown added in v0.1.11

func MatchChown(path string, user, group int) bool

MatchChown returns true if the path is owned by the specified user and group

func PrependSudo added in v0.1.9

func PrependSudo(args []string) []string

PrependSudo takes a slice of args and simply prepends sudo to the front.

func RunCommand added in v0.1.9

func RunCommand(command ...string) error

RunCommand is essentially a wrapper around exec.Command. Generally the Execute resource should be used, but sometimes it can be useful to run things directly.

func SudoCommand added in v0.1.9

func SudoCommand(command ...string) error

SudoCommand is the same as RunCommand but runs with sudo.

func TmpFile added in v0.3.1

func TmpFile(path string) string

TmpFile returns the path for a Viaduct temporary file

Types

type Configs

type Configs struct {
	DryRun           bool
	DumpManifest     bool
	OutputAttributes bool
	Quiet            bool
	Silent           bool
}

Configs sets different settings when running something with viaduct

func (*Configs) SetDryRun added in v0.3.1

func (c *Configs) SetDryRun()

SetDryRun enables dry run mode.

func (*Configs) SetDumpManifest added in v0.3.1

func (c *Configs) SetDumpManifest()

SetDumpManifest enables dumping the manifest.

func (*Configs) SetQuiet added in v0.3.1

func (c *Configs) SetQuiet()

SetQuiet enables quiet mode.

func (*Configs) SetSilent added in v0.3.1

func (c *Configs) SetSilent()

SetSilent enables silent mode.

type Error added in v0.3.1

type Error struct {
	Err     error  `json:"-"`
	Message string `json:"Message"`
}

type Logger added in v0.3.0

type Logger struct {
	// This is the resource type, such as git, file and directory
	Resource string

	// This denotes the action taken on the resource, such as create or delete
	Action string

	// Quiet disables all output other than errors
	Quiet bool

	// Silent disables all output
	Silent bool
}

Logger provides Viaduct log output.

func NewLogger added in v0.3.0

func NewLogger(resource, action string) *Logger

func NewQuietLogger added in v0.3.0

func NewQuietLogger(resource, action string) *Logger

func NewSilentLogger added in v0.3.0

func NewSilentLogger() *Logger

func NewStandardLogger added in v0.3.1

func NewStandardLogger(resource, action string) *Logger

func (*Logger) Critical added in v0.3.0

func (l *Logger) Critical(v ...interface{})

Critical is like Fatal, but without exiting

func (*Logger) Fatal added in v0.3.0

func (l *Logger) Fatal(v ...interface{})

func (*Logger) Info added in v0.3.0

func (l *Logger) Info(v ...interface{})

Info outputs informational messages

func (*Logger) Noop added in v0.3.0

func (l *Logger) Noop(v ...interface{})

Noop prints no operation messages

func (*Logger) Warn added in v0.3.0

func (l *Logger) Warn(v ...interface{})

Warn prints warning messages

type Manifest added in v0.2.0

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

Manifest is a map of resources to allow concurrent runs

func New added in v0.2.0

func New() *Manifest

func (*Manifest) Add added in v0.3.0

func (m *Manifest) Add(attributes ResourceAttributes, deps ...*Resource) *Resource

func (*Manifest) Run added in v0.2.0

func (m *Manifest) Run()

Run will run the specified resources concurrently, taking into account any dependencies that have been declared

func (*Manifest) SetDep added in v0.2.0

func (m *Manifest) SetDep(r *Resource, name string)

WithDep sets an explicit dependency using a name

func (*Manifest) SetName added in v0.2.0

func (m *Manifest) SetName(r *Resource, newName string)

SetName allows us to overwrite the generated ID with our name. This name still needs to be unique.

func (*Manifest) WithLock added in v0.2.0

func (m *Manifest) WithLock(r *Resource)

type PlatformAttributes

type PlatformAttributes struct {
	Name             string `json:"name"`
	Version          string `json:"version"`
	ID               string `json:"id"`
	IDLike           string `json:"idLike"`
	PrettyName       string `json:"prettyName"`
	VersionID        string `json:"versionId"`
	HomeURL          string `json:"homeUrl"`
	SupportURL       string `json:"supportUrl"`
	BugReportURL     string `json:"bugReportUrl"`
	PrivacyPolicyURL string `json:"privacyPolicyUrl"`
	VersionCodename  string `json:"versionCodename"`
	UbuntuCodename   string `json:"ubuntuCodename"`
}

PlatformAttributes has details about the platform (currently Linux only)

type Resource added in v0.2.0

type Resource struct {
	// ResourceID is the resources generated ID.
	ResourceID
	// ResourceKind is what the resource kind is, such as "File" or "Package".
	ResourceKind
	// Status denotes the current status of the resource.
	Status
	// Attributes are the resource type attributes.
	Attributes ResourceAttributes
	// DependsOn is a list of resource dependencies.
	DependsOn []ResourceID `json:"DependsOn,omitempty"`
	// GlobalLock will mean the resource will not run at the same time
	// as other resources that have this set to true.
	GlobalLock bool
	// Error contains any errors raised during a run.
	Error `json:"Error"`
}

Resource holds details about a particular resource during a Viaduct run.

func (*Resource) Failed added in v0.3.3

func (r *Resource) Failed() bool

type ResourceAttributes added in v0.3.0

type ResourceAttributes interface {
	// OperationName is a simple identifier for the operation type, such as
	// Create, Delete, Update or Run.
	OperationName() string

	// Params are a set of parameters that determine how a resource should
	// interact with Viaduct.
	Params() *ResourceParams

	// PreflightChecks are used to check that the resource parameters have been
	// correctly set, and to ensure that default parameters are assigned.
	PreflightChecks(log *Logger) error

	// Run performs the resource operation.
	Run(log *Logger) error
}

ResourceAttributes implement different resource types, such as File or Directory. As long as this interface is implemented, then custom resources can be directly integrated.

type ResourceID added in v0.2.0

type ResourceID string

ResourceID is an id of a resource.

type ResourceKind added in v0.2.0

type ResourceKind string

ResourceKind is the kind of resource, such as "File" or "Package".

type ResourceParams added in v0.3.0

type ResourceParams struct {
	// GlobalLock can be set to ensure that the resource uses a global
	// lock during operations
	GlobalLock bool
}

ResourceParams are a set of options that each resource can set depending on their logic

func NewResourceParams added in v0.3.0

func NewResourceParams() *ResourceParams

NewResourceParams creates a new ResourceParams.

func NewResourceParamsWithLock added in v0.3.0

func NewResourceParamsWithLock() *ResourceParams

NewResourceParamsWithLock creates a new ResourceParams, but with a global lock applied.

type Status added in v0.2.0

type Status string
const (
	// Statuses
	DependencyFailed Status = "DependencyFailed"
	Failed           Status = "Failed"
	Pending          Status = "Pending"
	Success          Status = "Success"
)

type SystemAttributes added in v0.3.0

type SystemAttributes struct {
	User     user.User          `json:"user"`
	OS       string             `json:"os"`
	Arch     string             `json:"arch"`
	Hostname string             `json:"hostname"`
	Platform PlatformAttributes `json:"platform"`
	Custom   map[string]string  `json:"custom"`
	TmpDir   string             `json:"tmp_dir"`
	// contains filtered or unexported fields
}

Attributes represents all possible attributes of a system

func (*SystemAttributes) AddCustom added in v0.3.0

func (a *SystemAttributes) AddCustom(key, value string)

AddCustom allows us to add custom attributes during a run

func (*SystemAttributes) GetCustom added in v0.3.0

func (a *SystemAttributes) GetCustom(key string) string

GetCustom returns the value of a custom attribute

func (*SystemAttributes) JSON added in v0.3.0

func (a *SystemAttributes) JSON() string

JSON returns a string representation of the loaded attributes

func (*SystemAttributes) SetUser added in v0.3.0

func (a *SystemAttributes) SetUser(username string)

SetUser allows us to assign a default username

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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