Skip to content

Instantly share code, notes, and snippets.

@mjameswh
Created December 17, 2019 14:56
Show Gist options
  • Save mjameswh/9e9f7ddfdcdc2e5f30c4547ad72b402e to your computer and use it in GitHub Desktop.
Save mjameswh/9e9f7ddfdcdc2e5f30c4547ad72b402e to your computer and use it in GitHub Desktop.
////////////////////////////////////////////////////////////////////////////////
// This is an example of a proposed configuration language for restic,
// based on Hashpicorp's HCL.
//
// The main feature of the grammar in this example are:
//
// - More than one repository can be defined in a single configuration file.
// - Some aspects of the configuration (i.e. backends definitions) can be
// shared by different repositories.
// - Support for multiple backends for a single repository.
//
// More over, using HCL as a base for this configuration language has the
// following intrinsic upsides:
//
// - Support for comments.
// - The syntax is very easy to understand (well, at least when not using ).
// - Relatively easy to implement in Go (the HCL2 module is both powerful
// and simple to use).
// - The HCL Go module has a very light dependency tree.
////////////////////////////////////////////////////////////////////////////////
defaults {
quiet = false
verbose = 0
}
////////////////////////////////////////////////////////////////////////////////
// Repositories specification
repo "myrepo" {
backends = [ backends.local1, backends.s3 ]
backup_options {
target = [
"/home/user/",
"/home/otheruser",
]
exclude = ["*.c"]
}
}
repo "myrepo" {
backend = backends.local1
}
////////////////////////////////////////////////////////////////////////////////
// Backends specification
backend "local" "local1" {
path = "/foo/bar"
}
backend "local" "local2" {
path = "/foo/bar"
}
backend "sftp" {
host = "bar"
port = 2222
user = "foo"
password = "secret"
path = "/foo/bar"
}
backend "s3" {
user = "foo"
host = "bar"
path = "/foo/bar"
}
// This is an outline of Go types required to support the HCL configuration
// proposed above. Anotations are based on HCL2 (see references).
//
// References:
// https://github.com/hashicorp/hcl2/tree/master/guide
// https://godoc.org/github.com/hashicorp/hcl2
type Config struct {
*Defaults DefaultRepositoryOptions `hcl:"defaults,block"`
Repositories Repository[] `hcl:"repo,block"`
Backends Backend[] `hcl:"backend,block"`
}
type Backend struct {
Type string `hcl:"type,label"`
*Name string `hcl:"name,label"`
// This will contain undecoded HCL attributes for this block
// that are specific to the backend type
Remain hcl.Body `hcl:",remain"`
// This will contain decoded attributes for this block;
// the exact struct type will depend on the value of the Type field
*BackendDetails interface{}
}
type BackendDetailsLocal struct {
Path string `hcl:"path"`
}
type BackendDetailsSFTP struct {
Host string `hcl:"host"`
*Port uint16 `hcl:"port"`
User string `hcl:"user"`
*Password string `hcl:"password"`
Path string `hcl:"path"`
}
type BackendDetailsS3 struct {
Bucket string `hcl:"bucket"`
AccessKey string `hcl:"access_key"`
AccessSecret string `hcl:"access_secret"`
*Path string `hcl:"path"`
}
type DefaultRepositoryOptions struct {
BackupOptions BackupOptions `hcl:"backup_options"`
Quiet bool `hcl:"quiet"`
Verbose uint8 `hcl:"verbose"`
}
type Repository struct {
Backends []Backend `hcl:"backends"`
BackupOptions BackupOptions `hcl:"backup_options"`
Quiet bool `hcl:"quiet"`
Verbose uint8 `hcl:"verbose"`
}
type BackupOptions struct {
Target []string `hcl:"target"`
Excludes []string `hcl:"exclude"`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment