Documentation ¶
Overview ¶
Package uci implements a binding to OpenWRT's UCI (Unified Configuration Interface) files in pure Go.
The typical use case is reading and modifying UCI config options:
import "github.com/digineo/go-uci" uci.Get("network", "lan", "ifname") //=> []string{"eth0.1"}, true uci.Set("network", "lan", "ipaddr", "192.168.7.1") uci.Commit() // or uci.Revert()
For more details head over to the OpenWRT wiki, or dive into UCI's C source code:
- https://openwrt.org/docs/guide-user/base-system/uci
- https://git.openwrt.org/?p=project/uci.git;a=summary
The lexer is heavily inspired by Rob Pike's 2011 GTUG Sydney talk "Lexical Scanning in Go" (https://talks.golang.org/2011/lex.slide, https://youtu.be/HxaD_trXwRE), which in turn was a presentation of an early version of Go's text/template parser. It follows, that this library borrows code from Go's standard library (BSD-style licensed).
The UCI grammar (for the purpose of this library) is defined as follows:
uci packageDecl* configDecl* packageDecl `package` value CRLF configDecl* configDecl `config` ident value? CRLF optionDecl* optionDecl `option` ident value `list` ident value ident [_a-zA-Z0-9]+ value `'` STRING `'` `"` STRING `"` ident
For now, UCI imports/exports (packageDecl production) are not supported yet. The STRING token (value production) is also somewhat vaguely defined, and needs to be aligned with the actual C implementation.
Index ¶
- Constants
- Variables
- func AddSection(config, section, typ string) error
- func Commit() error
- func Del(config, section, option string)
- func DelSection(config, section string)
- func Get(config, section, option string) ([]string, bool)
- func GetBool(config, section, option string) (bool, bool)
- func GetLast(config, section, option string) (string, bool)
- func GetSections(config, secType string) ([]string, bool)
- func IsConfigAlreadyLoaded(err error) booldeprecated
- func IsParseError(err error) booldeprecated
- func IsSectionTypeMismatch(err error) booldeprecated
- func LoadConfig(name string, forceReload bool) error
- func Revert(configs ...string)
- func Set(config, section, option string, values ...string) bool
- type ErrConfigAlreadyLoaded
- type ErrSectionTypeMismatch
- type ErrUnknownOptionType
- type OptionType
- type ParseError
- type Tree
Constants ¶
const DefaultTreePath = "/etc/config"
DefaultTreePath points to the default UCI location.
Variables ¶
var ( ErrImplausibleSectionSelector = errors.New("implausible section selector: must be at least 5 characters long") ErrMustStartWithAt = errors.New("invalid syntax: section selector must start with @ sign") ErrMultipleAtSigns = errors.New("invalid syntax: multiple @ signs found") ErrMultipleOpenBrackets = errors.New("invalid syntax: multiple open brackets found") ErrMultipleCloseBrackets = errors.New("invalid syntax: multiple closed brackets found") ErrInvalidSectionSelector = errors.New("invalid syntax: section selector must have format '@type[index]'") )
var ErrUnnamedIndexOutOfBounds = errors.New("invalid name: index out of bounds")
Functions ¶
func AddSection ¶
AddSection delegates to the default tree. See Tree for details.
func Del ¶
func Del(config, section, option string)
Del delegates to the default tree. See Tree for details.
func DelSection ¶
func DelSection(config, section string)
DelSection delegates to the default tree. See Tree for details.
func GetSections ¶
GetSections delegates to the default tree. See Tree for details.
func IsConfigAlreadyLoaded
deprecated
func IsParseError
deprecated
func IsSectionTypeMismatch
deprecated
func LoadConfig ¶
LoadConfig delegates to the default tree. See Tree for details.
Types ¶
type ErrConfigAlreadyLoaded ¶
type ErrConfigAlreadyLoaded struct {
Name string
}
ErrConfigAlreadyLoaded is returned by LoadConfig, if the given config name is already present.
func (ErrConfigAlreadyLoaded) Error ¶
func (err ErrConfigAlreadyLoaded) Error() string
type ErrSectionTypeMismatch ¶
type ErrSectionTypeMismatch struct {
Config, Section string // name
ExistingType string
NewType string
}
ErrSectionTypeMismatch is returned by AddSection if the section-to-add already exists with a different type.
func (ErrSectionTypeMismatch) Error ¶
func (err ErrSectionTypeMismatch) Error() string
type ErrUnknownOptionType ¶
type ErrUnknownOptionType struct {
Type string
}
ErrUnknownOptionType is returned when trying to parse an invalid OptionType.
func (ErrUnknownOptionType) Error ¶
func (err ErrUnknownOptionType) Error() string
type OptionType ¶
type OptionType int
const ( TypeOption OptionType = iota // option is not a list TypeList // option is a list )
func (OptionType) MarshalJSON ¶
func (ot OptionType) MarshalJSON() ([]byte, error)
MarshalJSON implements encoding/json.Marshaler.
func (*OptionType) UnmarshalJSON ¶
func (ot *OptionType) UnmarshalJSON(b []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type ParseError ¶
type ParseError string
func (ParseError) Error ¶
func (err ParseError) Error() string
type Tree ¶
type Tree interface { // LoadConfig reads a config file into memory and returns nil. If the // config is already loaded, and forceReload is false, an error of type // ErrConfigAlreadyLoaded is returned. Errors reading the config file // are returned verbatim. // // You don't need to explicitly call LoadConfig(): Accessing configs // (and their sections) via Get, Set, Add, Delete, DeleteAll will // load missing files automatically. LoadConfig(name string, forceReload bool) error // Commit writes all changes back to the system. // // Note: this is not transaction safe. If, for whatever reason, the // writing of any file fails, the succeeding files are left untouched // while the preceding files are not reverted. Commit() error // Revert undoes changes to the config files given as arguments. If // no argument is given, all changes are reverted. This clears the // internal memory and does not access the file system. Revert(configs ...string) // GetSections returns the names of all sections of a certain type // in a config, and a boolean indicating whether the config file exists. GetSections(config, secType string) ([]string, bool) // Get retrieves (all) values for a fully qualified option, and a // boolean indicating whether the config file and the config section // within exists. Get(config, section, option string) ([]string, bool) // GetLast retrieves the last value that was defined for a fully // qualified option, and a boolean indicating whether the config file, // config section and the option exists. GetLast(config, section, option string) (string, bool) // GetBool works the same way as GetLast does but interprets the last // specified value as a boolean. If the found value can't be // interpreted as either true or false, it will return nil and false. GetBool(config, section, option string) (bool, bool) // Set replaces the fully qualified option with the given values. It // returns whether the config file and section exists. For new files // and sections, you first need to initialize them with AddSection(). // // Set will determine the option type by the number of values given. // In particular, it will always choose TypeOption when len(values) // is 1. // // Deprecated: Use SetType() to control the type. Set(config, section, option string, values ...string) bool // SetType replaces the fully qualified option with the given values. // It returns whether the config file and section exists. For new // files and sections, you first need to initialize them with // AddSection(). SetType(config, section, option string, typ OptionType, values ...string) bool // Del removes a fully qualified option. Del(config, section, option string) // AddSection adds a new config section. If the section already exists, // and the types match (existing type and given type), nothing happens. // Otherwise an ErrSectionTypeMismatch is returned. AddSection(config, section, typ string) error // DelSection remove a config section and its options. DelSection(config, section string) }
Tree defines the base directory for UCI config files. The default value on OpenWRT devices point to /etc/config, so that is what the default tree uses as well (you can access the default tree with the package level functions with the same signature as in this interface).