mirror of
https://github.com/outbackdingo/matchbox.git
synced 2026-01-27 10:19:35 +00:00
Merge pull request #479 from coreos/update-ignition-cloud-ct
Update Ignition, Container Linux Config transpiler, and Cloud-init
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
|
||||
# Cloud config
|
||||
|
||||
**Note:** We recommend migrating to [Ignition](ignition.md) for hardware provisioning.
|
||||
**Note:** We recommend migrating to [Container Linux Configs](container-linux-config.md) for hardware provisioning.
|
||||
|
||||
CoreOS Cloud-Config is a system for configuring machines with a Cloud-Config file or executable script from user-data. Cloud-Config runs in userspace on each boot and implements a subset of the [cloud-init spec](http://cloudinit.readthedocs.org/en/latest/topics/format.html#cloud-config-data). See the cloud-config [docs](https://coreos.com/os/docs/latest/cloud-config.html) for details.
|
||||
|
||||
|
||||
144
Documentation/container-linux-config.md
Normal file
144
Documentation/container-linux-config.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# Container Linux Configs
|
||||
|
||||
A Container Linux Config is a YAML document which declares how Container Linux instances' disks should be provisioned on network boot and first-boot from disk. Configs can declare disk paritions, write files (regular files, systemd units, networkd units, etc.), and configure users. See the Container Linux Config [spec](https://coreos.com/os/docs/latest/configuration.html).
|
||||
|
||||
### Ignition
|
||||
|
||||
Container Linux Configs are validated and converted to *machine-friendly* Ignition configs (JSON) by matchbox when serving to booting machines. [Ignition](https://coreos.com/ignition/docs/latest/), the provisioning utility shipped in Container Linux, will parse and execute the Ignition config to realize the desired configuration. Matchbox users usually only need to write Container Linux Configs.
|
||||
|
||||
*Note: Container Linux directory names are still named "ignition" for historical reasons as outlined below. A future breaking change will rename to "container-linux-config".*
|
||||
|
||||
## Adding Container Linux Configs
|
||||
|
||||
Container Linux Config templates can be added to the `/var/lib/matchbox/ignition` directory or in an `ignition` subdirectory of a custom `-data-path`. Template files may contain [Go template](https://golang.org/pkg/text/template/) elements which will be evaluated with group metadata, selectors, and query params.
|
||||
|
||||
```
|
||||
/var/lib/matchbox
|
||||
├── cloud
|
||||
├── ignition
|
||||
│ └── k8s-controller.yaml
|
||||
│ └── etcd.yaml
|
||||
│ └── k8s-worker.yaml
|
||||
│ └── raw.ign
|
||||
└── profiles
|
||||
```
|
||||
|
||||
## Referencing in Profiles
|
||||
|
||||
Profiles can include a Container Linux Config for provisioning machines. Specify the Container Linux Config in a [Profile](matchbox.md#profiles) with `ignition_id`. When PXE booting, use the kernel option `coreos.first_boot=1` and `coreos.config.url` to point to the `matchbox` [Ignition endpoint](api.md#ignition-config).
|
||||
|
||||
## Examples
|
||||
|
||||
Here is an example Container Linux Config template. Variables will be interpreted using group metadata, selectors, and query params. Matchbox will convert the config to Ignition to serve Container Linux machines.
|
||||
|
||||
ignition/format-disk.yaml.tmpl:
|
||||
|
||||
<!-- {% raw %} -->
|
||||
```yaml
|
||||
|
||||
---
|
||||
storage:
|
||||
disks:
|
||||
- device: /dev/sda
|
||||
wipe_table: true
|
||||
partitions:
|
||||
- label: ROOT
|
||||
filesystems:
|
||||
- name: root
|
||||
mount:
|
||||
device: "/dev/sda1"
|
||||
format: "ext4"
|
||||
create:
|
||||
force: true
|
||||
options:
|
||||
- "-LROOT"
|
||||
files:
|
||||
- filesystem: root
|
||||
path: /home/core/foo
|
||||
mode: 0644
|
||||
user:
|
||||
id: 500
|
||||
group:
|
||||
id: 500
|
||||
contents:
|
||||
inline: |
|
||||
{{.example_contents}}
|
||||
{{ if index . "ssh_authorized_keys" }}
|
||||
passwd:
|
||||
users:
|
||||
- name: core
|
||||
ssh_authorized_keys:
|
||||
{{ range $element := .ssh_authorized_keys }}
|
||||
- {{$element}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
```
|
||||
<!-- {% endraw %} -->
|
||||
|
||||
The Ignition config response (formatted) to a query `/ignition?label=value` for a CoreOS instance supporting Ignition 2.0.0 would be:
|
||||
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "2.0.0",
|
||||
"config": {}
|
||||
},
|
||||
"storage": {
|
||||
"disks": [
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
"wipeTable": true,
|
||||
"partitions": [
|
||||
{
|
||||
"label": "ROOT",
|
||||
"number": 0,
|
||||
"size": 0,
|
||||
"start": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"name": "root",
|
||||
"mount": {
|
||||
"device": "/dev/sda1",
|
||||
"format": "ext4",
|
||||
"create": {
|
||||
"force": true,
|
||||
"options": [
|
||||
"-LROOT"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"filesystem": "root",
|
||||
"path": "/home/core/foo",
|
||||
"contents": {
|
||||
"source": "data:,Example%20file%20contents%0A",
|
||||
"verification": {}
|
||||
},
|
||||
"mode": 420,
|
||||
"user": {
|
||||
"id": 500
|
||||
},
|
||||
"group": {
|
||||
"id": 500
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"systemd": {},
|
||||
"networkd": {},
|
||||
"passwd": {}
|
||||
}
|
||||
```
|
||||
|
||||
See [examples/ignition](../examples/ignition) for numerous Container Linux Config template examples.
|
||||
|
||||
### Raw Ignition
|
||||
|
||||
If you prefer to design your own templating solution, raw Ignition files (suffixed with `.ign` or `.ignition`) are served directly.
|
||||
@@ -1,169 +0,0 @@
|
||||
# Ignition
|
||||
|
||||
Ignition is a system for declaratively provisioning disks during the initramfs, before systemd starts. It runs only on the first boot and handles partitioning disks, formatting partitions, writing files (regular files, systemd units, networkd units, etc.), and configuring users. See the Ignition [docs](https://coreos.com/ignition/docs/latest/) for details.
|
||||
|
||||
## Fuze configs
|
||||
|
||||
Ignition 2.0.0+ configs are versioned, *machine-friendly* JSON documents (which contain encoded file contents). Operators should write and maintain configs in a *human-friendly* format, such as CoreOS [fuze](https://github.com/coreos/fuze) configs. As of `matchbox` v0.4.0, Fuze configs are the primary way to use CoreOS Ignition.
|
||||
|
||||
The [Fuze schema](https://github.com/coreos/fuze/blob/master/doc/configuration.md) formalizes and improves upon the YAML to Ignition JSON transform. Fuze provides better support for Ignition 2.0.0+, handles file content encoding, patches Ignition bugs, performs better validations, and lets services (like `matchbox`) negotiate the Ignition version required by a CoreOS client.
|
||||
|
||||
### Adding Fuze configs
|
||||
|
||||
Fuze template files can be added in the `/var/lib/matchbox/ignition` directory or in an `ignition` subdirectory of a custom `-data-path`. Template files may contain [Go template](https://golang.org/pkg/text/template/) elements which will be evaluated with group metadata, selectors, and query params.
|
||||
|
||||
```
|
||||
/var/lib/matchbox
|
||||
├── cloud
|
||||
├── ignition
|
||||
│ └── k8s-controller.yaml
|
||||
│ └── etcd.yaml
|
||||
│ └── k8s-worker.yaml
|
||||
│ └── raw.ign
|
||||
└── profiles
|
||||
```
|
||||
|
||||
### Reference
|
||||
|
||||
Reference an Fuze config in a [Profile](matchbox.md#profiles) with `ignition_id`. When PXE booting, use the kernel option `coreos.first_boot=1` and `coreos.config.url` to point to the `matchbox` [Ignition endpoint](api.md#ignition-config).
|
||||
|
||||
### Migration from v0.3.0
|
||||
|
||||
In v0.4.0, `matchbox` switched to using the CoreOS [fuze](https://github.com/coreos/fuze) library, which formalizes and improves upon the YAML to Ignition JSON transform. Fuze provides better support for Ignition 2.0.0+, handles file content encoding, patches Ignition bugs, and performs better validations.
|
||||
|
||||
Upgrade your Ignition YAML templates to match the [Fuze config schema](https://github.com/coreos/fuze/blob/master/doc/configuration.md). Typically, you'll need to do the following:
|
||||
|
||||
* Remove `ignition_version: 1`, Fuze configs are version-less
|
||||
* Update `filesystems` section and set the `name`
|
||||
* Update `files` section to use `inline` as shown below
|
||||
* Replace `uid` and `gid` with `user` and `group` objects as shown above
|
||||
|
||||
Maintain readable inline file contents in Fuze:
|
||||
|
||||
```
|
||||
...
|
||||
files:
|
||||
- path: /etc/foo.conf
|
||||
filesystem: root
|
||||
contents:
|
||||
inline: |
|
||||
foo bar
|
||||
```
|
||||
|
||||
Support for the older Ignition v1 format has been dropped, so CoreOS machines must be **1010.1.0 or newer**. Read the upstream Ignition v1 to 2.0.0 [migration guide](https://coreos.com/ignition/docs/latest/migrating-configs.html) to understand the reasons behind schema changes.
|
||||
|
||||
## Examples
|
||||
|
||||
Here is an example Fuze template. This template will be rendered into a Fuze config (YAML), using group metadata, selectors, and query params as template variables. Finally, the Fuze config is served to client machines as Ignition JSON.
|
||||
|
||||
ignition/format-disk.yaml.tmpl:
|
||||
|
||||
<!-- {% raw %} -->
|
||||
```yaml
|
||||
|
||||
---
|
||||
storage:
|
||||
disks:
|
||||
- device: /dev/sda
|
||||
wipe_table: true
|
||||
partitions:
|
||||
- label: ROOT
|
||||
filesystems:
|
||||
- name: root
|
||||
mount:
|
||||
device: "/dev/sda1"
|
||||
format: "ext4"
|
||||
create:
|
||||
force: true
|
||||
options:
|
||||
- "-LROOT"
|
||||
files:
|
||||
- filesystem: root
|
||||
path: /home/core/foo
|
||||
mode: 0644
|
||||
user:
|
||||
id: 500
|
||||
group:
|
||||
id: 500
|
||||
contents:
|
||||
inline: |
|
||||
{{.example_contents}}
|
||||
{{ if index . "ssh_authorized_keys" }}
|
||||
passwd:
|
||||
users:
|
||||
- name: core
|
||||
ssh_authorized_keys:
|
||||
{{ range $element := .ssh_authorized_keys }}
|
||||
- {{$element}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
```
|
||||
<!-- {% endraw %} -->
|
||||
|
||||
The Ignition config response (formatted) to a query `/ignition?label=value` for a CoreOS instance supporting Ignition 2.0.0 would be:
|
||||
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "2.0.0",
|
||||
"config": {}
|
||||
},
|
||||
"storage": {
|
||||
"disks": [
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
"wipeTable": true,
|
||||
"partitions": [
|
||||
{
|
||||
"label": "ROOT",
|
||||
"number": 0,
|
||||
"size": 0,
|
||||
"start": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"name": "root",
|
||||
"mount": {
|
||||
"device": "/dev/sda1",
|
||||
"format": "ext4",
|
||||
"create": {
|
||||
"force": true,
|
||||
"options": [
|
||||
"-LROOT"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"filesystem": "root",
|
||||
"path": "/home/core/foo",
|
||||
"contents": {
|
||||
"source": "data:,Example%20file%20contents%0A",
|
||||
"verification": {}
|
||||
},
|
||||
"mode": 420,
|
||||
"user": {
|
||||
"id": 500
|
||||
},
|
||||
"group": {
|
||||
"id": 500
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"systemd": {},
|
||||
"networkd": {},
|
||||
"passwd": {}
|
||||
}
|
||||
```
|
||||
|
||||
See [examples/ignition](../examples/ignition) for numerous Fuze template examples.
|
||||
|
||||
### Raw Ignition
|
||||
|
||||
If you prefer to design your own templating solution, raw Ignition files (suffixed with `.ign` or `.ignition`) are served directly.
|
||||
@@ -130,16 +130,16 @@ Group selectors can use any key/value pairs you find useful. However, several la
|
||||
|
||||
### Config templates
|
||||
|
||||
Profiles can reference various templated configs. Ignition JSON configs can be generated from [Fuze config](https://github.com/coreos/fuze/blob/master/doc/configuration.md) template files. Cloud-Config templates files can be used to render a script or Cloud-Config. Generic template files can be used to render arbitrary untyped configs (experimental). Each template may contain [Go template](https://golang.org/pkg/text/template/) elements which will be rendered with machine group metadata, selectors, and query params.
|
||||
Profiles can reference various templated configs. Ignition JSON configs can be generated from [Container Linux Config](https://github.com/coreos/container-linux-config-transpiler/blob/master/doc/configuration.md) template files. Cloud-Config templates files can be used to render a script or Cloud-Config. Generic template files can be used to render arbitrary untyped configs (experimental). Each template may contain [Go template](https://golang.org/pkg/text/template/) elements which will be rendered with machine group metadata, selectors, and query params.
|
||||
|
||||
For details and examples:
|
||||
|
||||
* [Ignition Config](ignition.md)
|
||||
* [Container Linux Config](container-linux-config.md)
|
||||
* [Cloud-Config](cloud-config.md)
|
||||
|
||||
#### Variables
|
||||
|
||||
Within Ignition/Fuze templates, Cloud-Config templates, or generic templates, you can use group metadata, selectors, or request-scoped query params. For example, a request `/generic?mac=52-54-00-89-d8-10&foo=some-param&bar=b` would match the `node1.json` machine group shown above. If the group's profile ("etcd") referenced a generic template, the following variables could be used.
|
||||
Within Container Linux Config templates, Cloud-Config templates, or generic templates, you can use group metadata, selectors, or request-scoped query params. For example, a request `/generic?mac=52-54-00-89-d8-10&foo=some-param&bar=b` would match the `node1.json` machine group shown above. If the group's profile ("etcd") referenced a generic template, the following variables could be used.
|
||||
|
||||
<!-- {% raw %} -->
|
||||
```
|
||||
|
||||
@@ -21,7 +21,7 @@ Network boot and provision CoreOS clusters on virtual or physical hardware.
|
||||
* [Profiles](Documentation/matchbox.md#profiles)
|
||||
* [Groups](Documentation/matchbox.md#groups)
|
||||
* Config Templates
|
||||
* [Ignition](Documentation/ignition.md)
|
||||
* [Container Linux Config](Documentation/container-linux-config.md)
|
||||
* [Cloud-Config](Documentation/cloud-config.md)
|
||||
* [Configuration](Documentation/config.md)
|
||||
* [HTTP API](Documentation/api.md)
|
||||
|
||||
26
glide.lock
generated
26
glide.lock
generated
@@ -1,38 +1,42 @@
|
||||
hash: 9b6db105e9175308cb3a911161d68bbc80a5ee762bb7f08c926101cc5389b115
|
||||
updated: 2017-04-10T15:46:19.530989294-07:00
|
||||
hash: 205de0b66ed059a1f10d3fb36c7d465439818123940a9aaa68ddc71cc3bbfddd
|
||||
updated: 2017-04-17T17:09:48.864562358-07:00
|
||||
imports:
|
||||
- name: github.com/ajeddeloh/go-json
|
||||
version: 73d058cf8437a1989030afe571eeab9f90eebbbd
|
||||
- name: github.com/ajeddeloh/yaml
|
||||
version: 1072abfea31191db507785e2e0c1b8d1440d35a5
|
||||
- name: github.com/alecthomas/units
|
||||
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
|
||||
version: 6b4e7dc5e3143b85ea77909c72caf89416fc2915
|
||||
- name: github.com/camlistore/camlistore
|
||||
version: 9106ce829629773474c689b34aacd7d3aaa99426
|
||||
- name: github.com/coreos/coreos-cloudinit
|
||||
version: 4c333e657bfbaa8f6594298b48324f45e6bf5961
|
||||
subpackages:
|
||||
- config
|
||||
- name: github.com/coreos/fuze
|
||||
version: 63c72bc1c8875f7f4ca11800a1a8de0478a69a12
|
||||
- name: github.com/coreos/container-linux-config-transpiler
|
||||
version: 12554ca0a5ce8ea4a6c594242ccb23d8b9bff493
|
||||
subpackages:
|
||||
- config
|
||||
- config/templating
|
||||
- config/types
|
||||
- name: github.com/coreos/coreos-cloudinit
|
||||
version: 5be99bf577f2768193c7fb587ef5a8806c1503cf
|
||||
subpackages:
|
||||
- config
|
||||
- name: github.com/coreos/go-semver
|
||||
version: 294930c1e79c64e7dbe360054274fdad492c8cf5
|
||||
version: 5e3acbb5668c4c3deb4842615c4098eb61fb6b1e
|
||||
subpackages:
|
||||
- semver
|
||||
- name: github.com/coreos/go-systemd
|
||||
version: 43e4800a6165b4e02bb2a36673c54b230d6f7b26
|
||||
subpackages:
|
||||
- journal
|
||||
- unit
|
||||
- name: github.com/coreos/ignition
|
||||
version: 3ffd793b1292c6b0b3519bce214bdb41f336faa7
|
||||
version: d75d0aa3bf307f0954ce4ea8cac56dacec8d16ce
|
||||
subpackages:
|
||||
- config
|
||||
- config/types
|
||||
- config/v1
|
||||
- config/v1/types
|
||||
- config/v2_0
|
||||
- config/v2_0/types
|
||||
- config/validate
|
||||
- config/validate/astjson
|
||||
- config/validate/report
|
||||
|
||||
29
glide.yaml
29
glide.yaml
@@ -17,9 +17,15 @@ import:
|
||||
- naming
|
||||
- peer
|
||||
- transport
|
||||
# Ignition and Fuze parse machine configs
|
||||
# Container Linux Config Transpiler and Ignition
|
||||
- package: github.com/coreos/container-linux-config-transpiler
|
||||
version: v0.2.2
|
||||
subpackages:
|
||||
- config
|
||||
- config/types
|
||||
- config/templating
|
||||
- package: github.com/coreos/ignition
|
||||
version: 3ffd793b1292c6b0b3519bce214bdb41f336faa7
|
||||
version: d75d0aa3bf307f0954ce4ea8cac56dacec8d16ce
|
||||
subpackages:
|
||||
- config
|
||||
- config/types
|
||||
@@ -28,17 +34,18 @@ import:
|
||||
- config/validate
|
||||
- config/validate/astjson
|
||||
- config/validate/report
|
||||
- package: github.com/coreos/fuze
|
||||
version: 63c72bc1c8875f7f4ca11800a1a8de0478a69a12
|
||||
subpackages:
|
||||
- config
|
||||
- config/types
|
||||
- package: github.com/ajeddeloh/yaml
|
||||
version: 1072abfea31191db507785e2e0c1b8d1440d35a5
|
||||
- package: github.com/vincent-petithory/dataurl
|
||||
version: 9a301d65acbb728fcc3ace14f45f511a4cfeea9c
|
||||
- package: github.com/alecthomas/units
|
||||
version: 6b4e7dc5e3143b85ea77909c72caf89416fc2915
|
||||
- package: github.com/coreos/go-semver
|
||||
version: 5e3acbb5668c4c3deb4842615c4098eb61fb6b1e
|
||||
subpackages:
|
||||
- semver
|
||||
- package: github.com/coreos/coreos-cloudinit
|
||||
version: v1.11.0
|
||||
version: v1.13.0
|
||||
subpackages:
|
||||
- config
|
||||
- package: github.com/coreos/pkg
|
||||
@@ -71,14 +78,8 @@ import:
|
||||
version: f7716cbe52baa25d2e9b0d0da546fcf909fc16b4
|
||||
- package: github.com/coreos/yaml
|
||||
version: 6b16a5714269b2f70720a45406b1babd947a17ef
|
||||
- package: github.com/alecthomas/units
|
||||
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
|
||||
- package: github.com/camlistore/camlistore
|
||||
version: 9106ce829629773474c689b34aacd7d3aaa99426
|
||||
- package: github.com/coreos/go-semver
|
||||
version: 294930c1e79c64e7dbe360054274fdad492c8cf5
|
||||
subpackages:
|
||||
- semver
|
||||
- package: github.com/coreos/go-systemd
|
||||
version: v12
|
||||
subpackages:
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"context"
|
||||
"github.com/Sirupsen/logrus"
|
||||
fuze "github.com/coreos/fuze/config"
|
||||
ct "github.com/coreos/container-linux-config-transpiler/config"
|
||||
ignition "github.com/coreos/ignition/config"
|
||||
|
||||
"github.com/coreos/matchbox/matchbox/server"
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
|
||||
// ignitionHandler returns a handler that responds with the Ignition config
|
||||
// matching the request. The Ignition file referenced in the Profile is parsed
|
||||
// as raw Ignition (for .ign/.ignition) or rendered to a Fuze config (YAML)
|
||||
// and converted to Ignition. Ignition configs are served as HTTP JSON
|
||||
// responses.
|
||||
// as raw Ignition (for .ign/.ignition) or rendered from a Container Linux
|
||||
// Config (YAML) and converted to Ignition. Ignition configs are served as HTTP
|
||||
// JSON responses.
|
||||
func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
group, err := groupFromContext(ctx)
|
||||
@@ -48,7 +48,7 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
"group": group.Id,
|
||||
"group_name": group.Name,
|
||||
"profile": group.Profile,
|
||||
}).Infof("No Ignition or Fuze template named: %s", profile.IgnitionId)
|
||||
}).Infof("No Ignition or Container Linux Config template named: %s", profile.IgnitionId)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
"labels": labelsFromRequest(nil, req),
|
||||
"group": group.Id,
|
||||
"profile": profile.Id,
|
||||
}).Debug("Matched an Ignition or Fuze template")
|
||||
}).Debug("Matched an Ignition or Container Linux Config template")
|
||||
|
||||
// Skip rendering if raw Ignition JSON is provided
|
||||
if isIgnition(profile.IgnitionId) {
|
||||
@@ -70,7 +70,7 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
return
|
||||
}
|
||||
|
||||
// Fuze Config template
|
||||
// Container Linux Config template
|
||||
|
||||
// collect data for rendering
|
||||
data, err := collectVariables(req, group)
|
||||
@@ -88,18 +88,18 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
return
|
||||
}
|
||||
|
||||
// Parse bytes into a Fuze Config
|
||||
config, report := fuze.Parse(buf.Bytes())
|
||||
// Parse bytes into a Container Linux Config
|
||||
config, report := ct.Parse(buf.Bytes())
|
||||
if report.IsFatal() {
|
||||
s.logger.Errorf("error parsing Fuze config: %s", report.String())
|
||||
s.logger.Errorf("error parsing Container Linux config: %s", report.String())
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
// Convert Fuze Config into an Ignition Config
|
||||
ign, report := fuze.ConvertAs2_0_0(config)
|
||||
// Convert Container Linux Config into an Ignition Config
|
||||
ign, report := ct.ConvertAs2_0(config, "")
|
||||
if report.IsFatal() {
|
||||
s.logger.Errorf("error converting Fuze config: %s", report.String())
|
||||
s.logger.Errorf("error converting Container Linux config: %s", report.String())
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestIgnitionHandler_V2JSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIgnitionHandler_V2YAML(t *testing.T) {
|
||||
// exercise templating features, not a realistic Fuze template
|
||||
// exercise templating features, not a realistic Container Linux Config template
|
||||
content := `
|
||||
systemd:
|
||||
units:
|
||||
@@ -66,7 +66,7 @@ systemd:
|
||||
req, _ := http.NewRequest("GET", "/?foo=some-param&bar=b", nil)
|
||||
h.ServeHTTP(ctx, w, req)
|
||||
// assert that:
|
||||
// - Fuze template rendered with Group selectors, metadata, and query variables
|
||||
// - Container Linux Config template rendered with Group selectors, metadata, and query variables
|
||||
// - Transformed to an Ignition config (JSON)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, jsonContentType, w.HeaderMap.Get(contentType))
|
||||
|
||||
@@ -26,35 +26,35 @@ var (
|
||||
ErrNotDocumentNode = errors.New("Can only convert from document node")
|
||||
)
|
||||
|
||||
type YamlNode struct {
|
||||
type yamlNode struct {
|
||||
key yaml.Node
|
||||
yaml.Node
|
||||
}
|
||||
|
||||
func FromYamlDocumentNode(n yaml.Node) (YamlNode, error) {
|
||||
func fromYamlDocumentNode(n yaml.Node) (yamlNode, error) {
|
||||
if n.Kind != yaml.DocumentNode {
|
||||
return YamlNode{}, ErrNotDocumentNode
|
||||
return yamlNode{}, ErrNotDocumentNode
|
||||
}
|
||||
|
||||
return YamlNode{
|
||||
return yamlNode{
|
||||
key: n,
|
||||
Node: *n.Children[0],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (n YamlNode) ValueLineCol(source io.ReadSeeker) (int, int, string) {
|
||||
func (n yamlNode) ValueLineCol(source io.ReadSeeker) (int, int, string) {
|
||||
return n.Line, n.Column, ""
|
||||
}
|
||||
|
||||
func (n YamlNode) KeyLineCol(source io.ReadSeeker) (int, int, string) {
|
||||
func (n yamlNode) KeyLineCol(source io.ReadSeeker) (int, int, string) {
|
||||
return n.key.Line, n.key.Column, ""
|
||||
}
|
||||
|
||||
func (n YamlNode) LiteralValue() interface{} {
|
||||
func (n yamlNode) LiteralValue() interface{} {
|
||||
return n.Value
|
||||
}
|
||||
|
||||
func (n YamlNode) SliceChild(index int) (validate.AstNode, bool) {
|
||||
func (n yamlNode) SliceChild(index int) (validate.AstNode, bool) {
|
||||
if n.Kind != yaml.SequenceNode {
|
||||
return nil, false
|
||||
}
|
||||
@@ -62,13 +62,13 @@ func (n YamlNode) SliceChild(index int) (validate.AstNode, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return YamlNode{
|
||||
return yamlNode{
|
||||
key: yaml.Node{},
|
||||
Node: *n.Children[index],
|
||||
}, true
|
||||
}
|
||||
|
||||
func (n YamlNode) KeyValueMap() (map[string]validate.AstNode, bool) {
|
||||
func (n yamlNode) KeyValueMap() (map[string]validate.AstNode, bool) {
|
||||
if n.Kind != yaml.MappingNode {
|
||||
return nil, false
|
||||
}
|
||||
@@ -77,7 +77,7 @@ func (n YamlNode) KeyValueMap() (map[string]validate.AstNode, bool) {
|
||||
for i := 0; i < len(n.Children); i += 2 {
|
||||
key := *n.Children[i]
|
||||
value := *n.Children[i+1]
|
||||
kvmap[key.Value] = YamlNode{
|
||||
kvmap[key.Value] = yamlNode{
|
||||
key: key,
|
||||
Node: value,
|
||||
}
|
||||
@@ -85,6 +85,6 @@ func (n YamlNode) KeyValueMap() (map[string]validate.AstNode, bool) {
|
||||
return kvmap, true
|
||||
}
|
||||
|
||||
func (n YamlNode) Tag() string {
|
||||
func (n yamlNode) Tag() string {
|
||||
return "yaml"
|
||||
}
|
||||
@@ -18,7 +18,8 @@ import (
|
||||
"reflect"
|
||||
|
||||
yaml "github.com/ajeddeloh/yaml"
|
||||
"github.com/coreos/fuze/config/types"
|
||||
"github.com/coreos/container-linux-config-transpiler/config/types"
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
@@ -39,7 +40,7 @@ func Parse(data []byte) (types.Config, report.Report) {
|
||||
})
|
||||
r.Merge(validate.ValidateWithoutSource(reflect.ValueOf(cfg)))
|
||||
} else {
|
||||
root, err := FromYamlDocumentNode(*nodes)
|
||||
root, err := fromYamlDocumentNode(*nodes)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
@@ -52,3 +53,7 @@ func Parse(data []byte) (types.Config, report.Report) {
|
||||
}
|
||||
return cfg, r
|
||||
}
|
||||
|
||||
func ConvertAs2_0(in types.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
return types.ConvertAs2_0(in, platform)
|
||||
}
|
||||
135
vendor/github.com/coreos/container-linux-config-transpiler/config/templating/templating.go
generated
vendored
Normal file
135
vendor/github.com/coreos/container-linux-config-transpiler/config/templating/templating.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package templating
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnknownPlatform = fmt.Errorf("unsupported platform")
|
||||
ErrUnknownField = fmt.Errorf("unknown field")
|
||||
)
|
||||
|
||||
const (
|
||||
PlatformAzure = "azure"
|
||||
PlatformDO = "digitalocean"
|
||||
PlatformEC2 = "ec2"
|
||||
PlatformGCE = "gce"
|
||||
PlatformPacket = "packet"
|
||||
PlatformOpenStackMetadata = "openstack-metadata"
|
||||
)
|
||||
|
||||
var Platforms = []string{
|
||||
PlatformAzure,
|
||||
PlatformDO,
|
||||
PlatformEC2,
|
||||
PlatformGCE,
|
||||
PlatformPacket,
|
||||
PlatformOpenStackMetadata,
|
||||
}
|
||||
|
||||
const (
|
||||
fieldHostname = "HOSTNAME"
|
||||
fieldV4Private = "PRIVATE_IPV4"
|
||||
fieldV4Public = "PUBLIC_IPV4"
|
||||
fieldV6Private = "PRIVATE_IPV6"
|
||||
fieldV6Public = "PUBLIC_IPV6"
|
||||
)
|
||||
|
||||
var platformTemplatingMap = map[string]map[string]string{
|
||||
PlatformAzure: {
|
||||
// TODO: is this right?
|
||||
fieldV4Private: "COREOS_AZURE_IPV4_DYNAMIC",
|
||||
fieldV4Public: "COREOS_AZURE_IPV4_VIRTUAL",
|
||||
},
|
||||
PlatformDO: {
|
||||
// TODO: unused: COREOS_DIGITALOCEAN_IPV4_ANCHOR_0
|
||||
fieldHostname: "COREOS_DIGITALOCEAN_HOSTNAME",
|
||||
fieldV4Private: "COREOS_DIGITALOCEAN_IPV4_PRIVATE_0",
|
||||
fieldV4Public: "COREOS_DIGITALOCEAN_IPV4_PUBLIC_0",
|
||||
fieldV6Private: "COREOS_DIGITALOCEAN_IPV6_PRIVATE_0",
|
||||
fieldV6Public: "COREOS_DIGITALOCEAN_IPV6_PUBLIC_0",
|
||||
},
|
||||
PlatformEC2: {
|
||||
fieldHostname: "COREOS_EC2_HOSTNAME",
|
||||
fieldV4Private: "COREOS_EC2_IPV4_LOCAL",
|
||||
fieldV4Public: "COREOS_EC2_IPV4_PUBLIC",
|
||||
},
|
||||
PlatformGCE: {
|
||||
fieldHostname: "COREOS_GCE_HOSTNAME",
|
||||
fieldV4Private: "COREOS_GCE_IP_EXTERNAL_0",
|
||||
fieldV4Public: "COREOS_GCE_IP_LOCAL_0",
|
||||
},
|
||||
PlatformPacket: {
|
||||
fieldHostname: "COREOS_PACKET_HOSTNAME",
|
||||
fieldV4Private: "COREOS_PACKET_IPV4_PRIVATE_0",
|
||||
fieldV4Public: "COREOS_PACKET_IPV4_PUBLIC_0",
|
||||
fieldV6Public: "COREOS_PACKET_IPV6_PUBLIC_0",
|
||||
},
|
||||
PlatformOpenStackMetadata: {
|
||||
fieldHostname: "COREOS_OPENSTACK_HOSTNAME",
|
||||
fieldV4Private: "COREOS_OPENSTACK_IPV4_LOCAL",
|
||||
fieldV4Public: "COREOS_OPENSTACK_IPV4_PUBLIC",
|
||||
},
|
||||
}
|
||||
|
||||
// HasTemplating returns whether or not any of the environment variables present
|
||||
// in the passed in list use ct templating
|
||||
func HasTemplating(vars []string) bool {
|
||||
for _, v := range vars {
|
||||
if strings.ContainsRune(v, '{') || strings.ContainsRune(v, '}') {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func PerformTemplating(platform string, vars []string) ([]string, error) {
|
||||
if _, ok := platformTemplatingMap[platform]; !ok {
|
||||
return nil, ErrUnknownPlatform
|
||||
}
|
||||
|
||||
for i := range vars {
|
||||
startIndex := strings.IndexRune(vars[i], '{')
|
||||
endIndex := strings.IndexRune(vars[i], '}')
|
||||
for startIndex != -1 && endIndex != -1 && startIndex < endIndex {
|
||||
fieldName := vars[i][startIndex+1 : endIndex]
|
||||
fieldVal, ok := platformTemplatingMap[platform][fieldName]
|
||||
if !ok {
|
||||
return nil, ErrUnknownField
|
||||
}
|
||||
vars[i] = strings.Replace(vars[i], "{"+fieldName+"}", "${"+fieldVal+"}", 1)
|
||||
|
||||
// start the search for a new start index from the old end index, or
|
||||
// we'll just find the curly braces we just substituted in
|
||||
startIndex = strings.IndexRune(vars[i][endIndex:], '{')
|
||||
if startIndex != -1 {
|
||||
startIndex += endIndex
|
||||
|
||||
// and start the search for a new end index from the new start
|
||||
// index, or as before we'll just find the curly braces we just
|
||||
// substituted in
|
||||
endIndex = strings.IndexRune(vars[i][startIndex:], '}')
|
||||
if endIndex != -1 {
|
||||
endIndex += startIndex
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return vars, nil
|
||||
}
|
||||
89
vendor/github.com/coreos/container-linux-config-transpiler/config/types/common.go
generated
vendored
Normal file
89
vendor/github.com/coreos/container-linux-config-transpiler/config/types/common.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/coreos/container-linux-config-transpiler/config/templating"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrPlatformUnspecified = fmt.Errorf("platform must be specified to use templating")
|
||||
)
|
||||
|
||||
func isZero(v interface{}) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
zv := reflect.Zero(reflect.TypeOf(v))
|
||||
return reflect.DeepEqual(v, zv.Interface())
|
||||
}
|
||||
|
||||
// assembleUnit will assemble the contents of a systemd unit dropin that will
|
||||
// have the given environment variables, and call the given exec line with the
|
||||
// provided args prepended to it
|
||||
func assembleUnit(exec string, args, vars []string, platform string) (string, error) {
|
||||
hasTemplating := templating.HasTemplating(args)
|
||||
|
||||
var out string
|
||||
if hasTemplating {
|
||||
if platform == "" {
|
||||
return "", ErrPlatformUnspecified
|
||||
}
|
||||
out = "[Unit]\nRequires=coreos-metadata.service\nAfter=coreos-metadata.service\n\n[Service]\nEnvironmentFile=/run/metadata/coreos\n"
|
||||
var err error
|
||||
args, err = templating.PerformTemplating(platform, args)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
out = "[Service]\n"
|
||||
}
|
||||
|
||||
for _, v := range vars {
|
||||
out += fmt.Sprintf("Environment=\"%s\"\n", v)
|
||||
}
|
||||
for _, a := range args {
|
||||
exec += fmt.Sprintf(" \\\n %s", a)
|
||||
}
|
||||
out += "ExecStart=\n"
|
||||
out += fmt.Sprintf("ExecStart=%s", exec)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// getCliArgs builds a list of --ARG=VAL from a struct with cli: tags on its members.
|
||||
func getCliArgs(e interface{}) []string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
et := reflect.TypeOf(e)
|
||||
ev := reflect.ValueOf(e)
|
||||
|
||||
vars := []string{}
|
||||
for i := 0; i < et.NumField(); i++ {
|
||||
if val := ev.Field(i).Interface(); !isZero(val) {
|
||||
if et.Field(i).Anonymous {
|
||||
vars = append(vars, getCliArgs(val)...)
|
||||
} else {
|
||||
key := et.Field(i).Tag.Get("cli")
|
||||
vars = append(vars, fmt.Sprintf("--%s=%q", key, val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vars
|
||||
}
|
||||
95
vendor/github.com/coreos/container-linux-config-transpiler/config/types/config.go
generated
vendored
Normal file
95
vendor/github.com/coreos/container-linux-config-transpiler/config/types/config.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Ignition Ignition `yaml:"ignition"`
|
||||
Storage Storage `yaml:"storage"`
|
||||
Systemd Systemd `yaml:"systemd"`
|
||||
Networkd Networkd `yaml:"networkd"`
|
||||
Passwd Passwd `yaml:"passwd"`
|
||||
Etcd *Etcd `yaml:"etcd"`
|
||||
Flannel *Flannel `yaml:"flannel"`
|
||||
Update *Update `yaml:"update"`
|
||||
Docker *Docker `yaml:"docker"`
|
||||
Locksmith *Locksmith `yaml:"locksmith"`
|
||||
}
|
||||
|
||||
type Ignition struct {
|
||||
Config IgnitionConfig `yaml:"config"`
|
||||
}
|
||||
|
||||
type IgnitionConfig struct {
|
||||
Append []ConfigReference `yaml:"append"`
|
||||
Replace *ConfigReference `yaml:"replace"`
|
||||
}
|
||||
|
||||
type ConfigReference struct {
|
||||
Source string `yaml:"source"`
|
||||
Verification Verification `yaml:"verification"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, ref := range in.Ignition.Config.Append {
|
||||
newRef, err := convertConfigReference(ref)
|
||||
if err != nil {
|
||||
return out, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Ignition.Config.Append = append(out.Ignition.Config.Append, newRef)
|
||||
}
|
||||
|
||||
if in.Ignition.Config.Replace != nil {
|
||||
newRef, err := convertConfigReference(*in.Ignition.Config.Replace)
|
||||
if err != nil {
|
||||
return out, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Ignition.Config.Replace = &newRef
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
|
||||
func convertConfigReference(in ConfigReference) (ignTypes.ConfigReference, error) {
|
||||
source, err := url.Parse(in.Source)
|
||||
if err != nil {
|
||||
return ignTypes.ConfigReference{}, err
|
||||
}
|
||||
|
||||
return ignTypes.ConfigReference{
|
||||
Source: ignTypes.Url(*source),
|
||||
Verification: convertVerification(in.Verification),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertVerification(in Verification) ignTypes.Verification {
|
||||
if in.Hash.Function == "" || in.Hash.Sum == "" {
|
||||
return ignTypes.Verification{}
|
||||
}
|
||||
|
||||
return ignTypes.Verification{
|
||||
&ignTypes.Hash{
|
||||
Function: in.Hash.Function,
|
||||
Sum: in.Hash.Sum,
|
||||
},
|
||||
}
|
||||
}
|
||||
58
vendor/github.com/coreos/container-linux-config-transpiler/config/types/converter.go
generated
vendored
Normal file
58
vendor/github.com/coreos/container-linux-config-transpiler/config/types/converter.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type converterFor2_0 func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report)
|
||||
|
||||
var convertersFor2_0 []converterFor2_0
|
||||
|
||||
func register2_0(f converterFor2_0) {
|
||||
convertersFor2_0 = append(convertersFor2_0, f)
|
||||
}
|
||||
|
||||
func ConvertAs2_0(in Config, platform string) (ignTypes.Config, report.Report) {
|
||||
out := ignTypes.Config{
|
||||
Ignition: ignTypes.Ignition{
|
||||
Version: ignTypes.IgnitionVersion{Major: 2, Minor: 0},
|
||||
},
|
||||
}
|
||||
|
||||
r := report.Report{}
|
||||
|
||||
for _, convert := range convertersFor2_0 {
|
||||
var subReport report.Report
|
||||
out, subReport = convert(in, out, platform)
|
||||
r.Merge(subReport)
|
||||
}
|
||||
if r.IsFatal() {
|
||||
return ignTypes.Config{}, r
|
||||
}
|
||||
|
||||
validationReport := validate.ValidateWithoutSource(reflect.ValueOf(out))
|
||||
r.Merge(validationReport)
|
||||
if r.IsFatal() {
|
||||
return ignTypes.Config{}, r
|
||||
}
|
||||
|
||||
return out, r
|
||||
}
|
||||
95
vendor/github.com/coreos/container-linux-config-transpiler/config/types/disks.go
generated
vendored
Normal file
95
vendor/github.com/coreos/container-linux-config-transpiler/config/types/disks.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/alecthomas/units"
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
const (
|
||||
BYTES_PER_SECTOR = 512
|
||||
)
|
||||
|
||||
type Disk struct {
|
||||
Device string `yaml:"device"`
|
||||
WipeTable bool `yaml:"wipe_table"`
|
||||
Partitions []Partition `yaml:"partitions"`
|
||||
}
|
||||
|
||||
type Partition struct {
|
||||
Label string `yaml:"label"`
|
||||
Number int `yaml:"number"`
|
||||
Size string `yaml:"size"`
|
||||
Start string `yaml:"start"`
|
||||
TypeGUID string `yaml:"type_guid"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, disk := range in.Storage.Disks {
|
||||
newDisk := ignTypes.Disk{
|
||||
Device: ignTypes.Path(disk.Device),
|
||||
WipeTable: disk.WipeTable,
|
||||
}
|
||||
|
||||
for _, partition := range disk.Partitions {
|
||||
size, err := convertPartitionDimension(partition.Size)
|
||||
if err != nil {
|
||||
return out, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
start, err := convertPartitionDimension(partition.Start)
|
||||
if err != nil {
|
||||
return out, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
newDisk.Partitions = append(newDisk.Partitions, ignTypes.Partition{
|
||||
Label: ignTypes.PartitionLabel(partition.Label),
|
||||
Number: partition.Number,
|
||||
Size: size,
|
||||
Start: start,
|
||||
TypeGUID: ignTypes.PartitionTypeGUID(partition.TypeGUID),
|
||||
})
|
||||
}
|
||||
|
||||
out.Storage.Disks = append(out.Storage.Disks, newDisk)
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
|
||||
func convertPartitionDimension(in string) (ignTypes.PartitionDimension, error) {
|
||||
if in == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
b, err := units.ParseBase2Bytes(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if b < 0 {
|
||||
return 0, fmt.Errorf("invalid dimension (negative): %q", in)
|
||||
}
|
||||
|
||||
// Translate bytes into sectors
|
||||
sectors := (b / BYTES_PER_SECTOR)
|
||||
if b%BYTES_PER_SECTOR != 0 {
|
||||
sectors++
|
||||
}
|
||||
return ignTypes.PartitionDimension(uint64(sectors)), nil
|
||||
}
|
||||
44
vendor/github.com/coreos/container-linux-config-transpiler/config/types/docker.go
generated
vendored
Normal file
44
vendor/github.com/coreos/container-linux-config-transpiler/config/types/docker.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Docker struct {
|
||||
Flags []string `yaml:"flags"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
if in.Docker != nil {
|
||||
contents := fmt.Sprintf("[Service]\nEnvironment=\"DOCKER_OPTS=%s\"", strings.Join(in.Docker.Flags, " "))
|
||||
out.Systemd.Units = append(out.Systemd.Units, ignTypes.SystemdUnit{
|
||||
Name: "docker.service",
|
||||
Enable: true,
|
||||
DropIns: []ignTypes.SystemdUnitDropIn{{
|
||||
Name: "20-clct-docker.conf",
|
||||
Contents: contents,
|
||||
}},
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
281
vendor/github.com/coreos/container-linux-config-transpiler/config/types/etcd.go
generated
vendored
Normal file
281
vendor/github.com/coreos/container-linux-config-transpiler/config/types/etcd.go
generated
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
EtcdVersionTooOld = errors.New("Etcd version specified is not valid (too old)")
|
||||
EtcdMinorVersionTooNew = errors.New("Etcd minor version specified is too new, only options available in the previous minor version will be accepted")
|
||||
EtcdMajorVersionTooNew = errors.New("Etcd version is not valid (too new)")
|
||||
OldestEtcd = *semver.New("2.3.0")
|
||||
EtcdDefaultVersion = *semver.New("3.0.0")
|
||||
)
|
||||
|
||||
// Options can be the options for any Etcd version
|
||||
type Options interface{}
|
||||
|
||||
type etcdCommon Etcd
|
||||
|
||||
type EtcdVersion semver.Version
|
||||
|
||||
func (e *EtcdVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
t := semver.Version(*e)
|
||||
if err := unmarshal(&t); err != nil {
|
||||
return err
|
||||
}
|
||||
*e = EtcdVersion(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EtcdVersion) Validate() report.Report {
|
||||
v := semver.Version(e)
|
||||
switch {
|
||||
case v.LessThan(OldestEtcd):
|
||||
return report.ReportFromError(EtcdVersionTooOld, report.EntryError)
|
||||
case v.Major == 2 && v.Minor > 3:
|
||||
fallthrough
|
||||
case v.Major == 3 && v.Minor > 1:
|
||||
return report.ReportFromError(EtcdMinorVersionTooNew, report.EntryWarning)
|
||||
case v.Major > 3:
|
||||
return report.ReportFromError(EtcdMajorVersionTooNew, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
func (e EtcdVersion) String() string {
|
||||
return semver.Version(e).String()
|
||||
}
|
||||
|
||||
// Etcd is a stub for yaml unmarshalling that figures out which
|
||||
// of the other Etcd structs to use and unmarshals to that. Options needs
|
||||
// to be an embedded type so that the structure of the yaml tree matches the
|
||||
// structure of the go config tree
|
||||
type Etcd struct {
|
||||
Version *EtcdVersion `yaml:"version"`
|
||||
Options
|
||||
}
|
||||
|
||||
func (etcd *Etcd) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
t := etcdCommon(*etcd)
|
||||
if err := unmarshal(&t); err != nil {
|
||||
return err
|
||||
}
|
||||
*etcd = Etcd(t)
|
||||
|
||||
var version semver.Version
|
||||
if etcd.Version == nil {
|
||||
version = EtcdDefaultVersion
|
||||
} else {
|
||||
version = semver.Version(*etcd.Version)
|
||||
}
|
||||
|
||||
if version.Major == 2 && version.Minor >= 3 {
|
||||
o := Etcd2{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
etcd.Options = o
|
||||
} else if version.Major == 3 && version.Minor == 0 {
|
||||
o := Etcd3_0{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
etcd.Options = o
|
||||
} else if version.Major == 3 && version.Minor >= 1 {
|
||||
o := Etcd3_1{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
etcd.Options = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
if in.Etcd != nil {
|
||||
contents, err := etcdContents(*in.Etcd, platform)
|
||||
if err != nil {
|
||||
return ignTypes.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Systemd.Units = append(out.Systemd.Units, ignTypes.SystemdUnit{
|
||||
Name: "etcd-member.service",
|
||||
Enable: true,
|
||||
DropIns: []ignTypes.SystemdUnitDropIn{{
|
||||
Name: "20-clct-etcd-member.conf",
|
||||
Contents: contents,
|
||||
}},
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
|
||||
// etcdContents creates the string containing the systemd drop in for etcd-member
|
||||
func etcdContents(etcd Etcd, platform string) (string, error) {
|
||||
args := getCliArgs(etcd.Options)
|
||||
var vars []string
|
||||
if etcd.Version != nil {
|
||||
vars = []string{fmt.Sprintf("ETCD_IMAGE_TAG=v%s", etcd.Version)}
|
||||
}
|
||||
|
||||
return assembleUnit("/usr/lib/coreos/etcd-wrapper $ETCD_OPTS", args, vars, platform)
|
||||
}
|
||||
|
||||
type Etcd3_0 struct {
|
||||
Name string `yaml:"name" cli:"name"`
|
||||
DataDir string `yaml:"data_dir" cli:"data-dir"`
|
||||
WalDir string `yaml:"wal_dir" cli:"wal-dir"`
|
||||
SnapshotCount int `yaml:"snapshot_count" cli:"snapshot-count"`
|
||||
HeartbeatInterval int `yaml:"heartbeat_interval" cli:"heartbeat-interval"`
|
||||
ElectionTimeout int `yaml:"election_timeout" cli:"election-timeout"`
|
||||
ListenPeerUrls string `yaml:"listen_peer_urls" cli:"listen-peer-urls"`
|
||||
ListenClientUrls string `yaml:"listen_client_urls" cli:"listen-client-urls"`
|
||||
MaxSnapshots int `yaml:"max_snapshots" cli:"max-snapshots"`
|
||||
MaxWals int `yaml:"max_wals" cli:"max-wals"`
|
||||
Cors string `yaml:"cors" cli:"cors"`
|
||||
InitialAdvertisePeerUrls string `yaml:"initial_advertise_peer_urls" cli:"initial-advertise-peer-urls"`
|
||||
InitialCluster string `yaml:"initial_cluster" cli:"initial-cluster"`
|
||||
InitialClusterState string `yaml:"initial_cluster_state" cli:"initial-cluster-state"`
|
||||
InitialClusterToken string `yaml:"initial_cluster_token" cli:"initial-cluster-token"`
|
||||
AdvertiseClientUrls string `yaml:"advertise_client_urls" cli:"advertise-client-urls"`
|
||||
Discovery string `yaml:"discovery" cli:"discovery"`
|
||||
DiscoverySrv string `yaml:"discovery_srv" cli:"discovery-srv"`
|
||||
DiscoveryFallback string `yaml:"discovery_fallback" cli:"discovery-fallback"`
|
||||
DiscoveryProxy string `yaml:"discovery_proxy" cli:"discovery-proxy"`
|
||||
StrictReconfigCheck bool `yaml:"strict_reconfig_check" cli:"strict-reconfig-check"`
|
||||
AutoCompactionRetention int `yaml:"auto_compaction_retention" cli:"auto-compaction-retention"`
|
||||
Proxy string `yaml:"proxy" cli:"proxy"`
|
||||
ProxyFailureWait int `yaml:"proxy_failure_wait" cli:"proxy-failure-wait"`
|
||||
ProxyRefreshInterval int `yaml:"proxy_refresh_interval" cli:"proxy-refresh-interval"`
|
||||
ProxyDialTimeout int `yaml:"proxy_dial_timeout" cli:"proxy-dial-timeout"`
|
||||
ProxyWriteTimeout int `yaml:"proxy_write_timeout" cli:"proxy-write-timeout"`
|
||||
ProxyReadTimeout int `yaml:"proxy_read_timeout" cli:"proxy-read-timeout"`
|
||||
CaFile string `yaml:"ca_file" cli:"ca-file" deprecated:"ca_file obsoleted by trusted_ca_file and client_cert_auth"`
|
||||
CertFile string `yaml:"cert_file" cli:"cert-file"`
|
||||
KeyFile string `yaml:"key_file" cli:"key-file"`
|
||||
ClientCertAuth bool `yaml:"client_cert_auth" cli:"client-cert-auth"`
|
||||
TrustedCaFile string `yaml:"trusted_ca_file" cli:"trusted-ca-file"`
|
||||
AutoTls bool `yaml:"auto_tls" cli:"auto-tls"`
|
||||
PeerCaFile string `yaml:"peer_ca_file" cli:"peer-ca-file" deprecated:"peer_ca_file obsoleted peer_trusted_ca_file and peer_client_cert_auth"`
|
||||
PeerCertFile string `yaml:"peer_cert_file" cli:"peer-cert-file"`
|
||||
PeerKeyFile string `yaml:"peer_key_file" cli:"peer-key-file"`
|
||||
PeerClientCertAuth bool `yaml:"peer_client_cert_auth" cli:"peer-client-cert-auth"`
|
||||
PeerTrustedCaFile string `yaml:"peer_trusted_ca_file" cli:"peer-trusted-ca-file"`
|
||||
PeerAutoTls bool `yaml:"peer_auto_tls" cli:"peer-auto-tls"`
|
||||
Debug bool `yaml:"debug" cli:"debug"`
|
||||
LogPackageLevels string `yaml:"log_package_levels" cli:"log-package-levels"`
|
||||
ForceNewCluster bool `yaml:"force_new_cluster" cli:"force-new-cluster"`
|
||||
}
|
||||
|
||||
type Etcd3_1 struct {
|
||||
Name string `yaml:"name" cli:"name"`
|
||||
DataDir string `yaml:"data_dir" cli:"data-dir"`
|
||||
WalDir string `yaml:"wal_dir" cli:"wal-dir"`
|
||||
SnapshotCount int `yaml:"snapshot_count" cli:"snapshot-count"`
|
||||
HeartbeatInterval int `yaml:"heartbeat_interval" cli:"heartbeat-interval"`
|
||||
ElectionTimeout int `yaml:"election_timeout" cli:"election-timeout"`
|
||||
ListenPeerUrls string `yaml:"listen_peer_urls" cli:"listen-peer-urls"`
|
||||
ListenClientUrls string `yaml:"listen_client_urls" cli:"listen-client-urls"`
|
||||
MaxSnapshots int `yaml:"max_snapshots" cli:"max-snapshots"`
|
||||
MaxWals int `yaml:"max_wals" cli:"max-wals"`
|
||||
Cors string `yaml:"cors" cli:"cors"`
|
||||
InitialAdvertisePeerUrls string `yaml:"initial_advertise_peer_urls" cli:"initial-advertise-peer-urls"`
|
||||
InitialCluster string `yaml:"initial_cluster" cli:"initial-cluster"`
|
||||
InitialClusterState string `yaml:"initial_cluster_state" cli:"initial-cluster-state"`
|
||||
InitialClusterToken string `yaml:"initial_cluster_token" cli:"initial-cluster-token"`
|
||||
AdvertiseClientUrls string `yaml:"advertise_client_urls" cli:"advertise-client-urls"`
|
||||
Discovery string `yaml:"discovery" cli:"discovery"`
|
||||
DiscoverySrv string `yaml:"discovery_srv" cli:"discovery-srv"`
|
||||
DiscoveryFallback string `yaml:"discovery_fallback" cli:"discovery-fallback"`
|
||||
DiscoveryProxy string `yaml:"discovery_proxy" cli:"discovery-proxy"`
|
||||
StrictReconfigCheck bool `yaml:"strict_reconfig_check" cli:"strict-reconfig-check"`
|
||||
AutoCompactionRetention int `yaml:"auto_compaction_retention" cli:"auto-compaction-retention"`
|
||||
Proxy string `yaml:"proxy" cli:"proxy"`
|
||||
ProxyFailureWait int `yaml:"proxy_failure_wait" cli:"proxy-failure-wait"`
|
||||
ProxyRefreshInterval int `yaml:"proxy_refresh_interval" cli:"proxy-refresh-interval"`
|
||||
ProxyDialTimeout int `yaml:"proxy_dial_timeout" cli:"proxy-dial-timeout"`
|
||||
ProxyWriteTimeout int `yaml:"proxy_write_timeout" cli:"proxy-write-timeout"`
|
||||
ProxyReadTimeout int `yaml:"proxy_read_timeout" cli:"proxy-read-timeout"`
|
||||
CaFile string `yaml:"ca_file" cli:"ca-file" deprecated:"ca_file obsoleted by trusted_ca_file and client_cert_auth"`
|
||||
CertFile string `yaml:"cert_file" cli:"cert-file"`
|
||||
KeyFile string `yaml:"key_file" cli:"key-file"`
|
||||
ClientCertAuth bool `yaml:"client_cert_auth" cli:"client-cert-auth"`
|
||||
TrustedCaFile string `yaml:"trusted_ca_file" cli:"trusted-ca-file"`
|
||||
AutoTls bool `yaml:"auto_tls" cli:"auto-tls"`
|
||||
PeerCaFile string `yaml:"peer_ca_file" cli:"peer-ca-file" deprecated:"peer_ca_file obsoleted peer_trusted_ca_file and peer_client_cert_auth"`
|
||||
PeerCertFile string `yaml:"peer_cert_file" cli:"peer-cert-file"`
|
||||
PeerKeyFile string `yaml:"peer_key_file" cli:"peer-key-file"`
|
||||
PeerClientCertAuth bool `yaml:"peer_client_cert_auth" cli:"peer-client-cert-auth"`
|
||||
PeerTrustedCaFile string `yaml:"peer_trusted_ca_file" cli:"peer-trusted-ca-file"`
|
||||
PeerAutoTls bool `yaml:"peer_auto_tls" cli:"peer-auto-tls"`
|
||||
Debug bool `yaml:"debug" cli:"debug"`
|
||||
LogPackageLevels string `yaml:"log_package_levels" cli:"log-package-levels"`
|
||||
ForceNewCluster bool `yaml:"force_new_cluster" cli:"force-new-cluster"`
|
||||
Metrics string `yaml:"metrics" cli:"metrics"`
|
||||
LogOutput string `yaml:"log_output" cli:"log-output"`
|
||||
}
|
||||
|
||||
type Etcd2 struct {
|
||||
AdvertiseClientURLs string `yaml:"advertise_client_urls" cli:"advertise-client-urls"`
|
||||
CAFile string `yaml:"ca_file" cli:"ca-file" deprecated:"ca_file obsoleted by trusted_ca_file and client_cert_auth"`
|
||||
CertFile string `yaml:"cert_file" cli:"cert-file"`
|
||||
ClientCertAuth bool `yaml:"client_cert_auth" cli:"client-cert-auth"`
|
||||
CorsOrigins string `yaml:"cors" cli:"cors"`
|
||||
DataDir string `yaml:"data_dir" cli:"data-dir"`
|
||||
Debug bool `yaml:"debug" cli:"debug"`
|
||||
Discovery string `yaml:"discovery" cli:"discovery"`
|
||||
DiscoveryFallback string `yaml:"discovery_fallback" cli:"discovery-fallback"`
|
||||
DiscoverySRV string `yaml:"discovery_srv" cli:"discovery-srv"`
|
||||
DiscoveryProxy string `yaml:"discovery_proxy" cli:"discovery-proxy"`
|
||||
ElectionTimeout int `yaml:"election_timeout" cli:"election-timeout"`
|
||||
EnablePprof bool `yaml:"enable_pprof" cli:"enable-pprof"`
|
||||
ForceNewCluster bool `yaml:"force_new_cluster" cli:"force-new-cluster"`
|
||||
HeartbeatInterval int `yaml:"heartbeat_interval" cli:"heartbeat-interval"`
|
||||
InitialAdvertisePeerURLs string `yaml:"initial_advertise_peer_urls" cli:"initial-advertise-peer-urls"`
|
||||
InitialCluster string `yaml:"initial_cluster" cli:"initial-cluster"`
|
||||
InitialClusterState string `yaml:"initial_cluster_state" cli:"initial-cluster-state"`
|
||||
InitialClusterToken string `yaml:"initial_cluster_token" cli:"initial-cluster-token"`
|
||||
KeyFile string `yaml:"key_file" cli:"key-file"`
|
||||
ListenClientURLs string `yaml:"listen_client_urls" cli:"listen-client-urls"`
|
||||
ListenPeerURLs string `yaml:"listen_peer_urls" cli:"listen-peer-urls"`
|
||||
LogPackageLevels string `yaml:"log_package_levels" cli:"log-package-levels"`
|
||||
MaxSnapshots int `yaml:"max_snapshots" cli:"max-snapshots"`
|
||||
MaxWALs int `yaml:"max_wals" cli:"max-wals"`
|
||||
Name string `yaml:"name" cli:"name"`
|
||||
PeerCAFile string `yaml:"peer_ca_file" cli:"peer-ca-file" deprecated:"peer_ca_file obsoleted peer_trusted_ca_file and peer_client_cert_auth"`
|
||||
PeerCertFile string `yaml:"peer_cert_file" cli:"peer-cert-file"`
|
||||
PeerKeyFile string `yaml:"peer_key_file" cli:"peer-key-file"`
|
||||
PeerClientCertAuth bool `yaml:"peer_client_cert_auth" cli:"peer-client-cert-auth"`
|
||||
PeerTrustedCAFile string `yaml:"peer_trusted_ca_file" cli:"peer-trusted-ca-file"`
|
||||
Proxy string `yaml:"proxy" cli:"proxy" valid:"^(on|off|readonly)$"`
|
||||
ProxyDialTimeout int `yaml:"proxy_dial_timeout" cli:"proxy-dial-timeout"`
|
||||
ProxyFailureWait int `yaml:"proxy_failure_wait" cli:"proxy-failure-wait"`
|
||||
ProxyReadTimeout int `yaml:"proxy_read_timeout" cli:"proxy-read-timeout"`
|
||||
ProxyRefreshInterval int `yaml:"proxy_refresh_interval" cli:"proxy-refresh-interval"`
|
||||
ProxyWriteTimeout int `yaml:"proxy_write_timeout" cli:"proxy-write-timeout"`
|
||||
SnapshotCount int `yaml:"snapshot_count" cli:"snapshot-count"`
|
||||
StrictReconfigCheck bool `yaml:"strict_reconfig_check" cli:"strict-reconfig-check"`
|
||||
TrustedCAFile string `yaml:"trusted_ca_file" cli:"trusted-ca-file"`
|
||||
WalDir string `yaml:"wal_dir" cli:"wal-dir"`
|
||||
}
|
||||
98
vendor/github.com/coreos/container-linux-config-transpiler/config/types/files.go
generated
vendored
Normal file
98
vendor/github.com/coreos/container-linux-config-transpiler/config/types/files.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
Filesystem string `yaml:"filesystem"`
|
||||
Path string `yaml:"path"`
|
||||
Mode int `yaml:"mode"`
|
||||
Contents FileContents `yaml:"contents"`
|
||||
User FileUser `yaml:"user"`
|
||||
Group FileGroup `yaml:"group"`
|
||||
}
|
||||
|
||||
type FileContents struct {
|
||||
Remote Remote `yaml:"remote"`
|
||||
Inline string `yaml:"inline"`
|
||||
}
|
||||
|
||||
type Remote struct {
|
||||
Url string `yaml:"url"`
|
||||
Compression string `yaml:"compression"`
|
||||
Verification Verification `yaml:"verification"`
|
||||
}
|
||||
|
||||
type FileUser struct {
|
||||
Id int `yaml:"id"`
|
||||
}
|
||||
|
||||
type FileGroup struct {
|
||||
Id int `yaml:"id"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, file := range in.Storage.Files {
|
||||
newFile := ignTypes.File{
|
||||
Filesystem: file.Filesystem,
|
||||
Path: ignTypes.Path(file.Path),
|
||||
Mode: ignTypes.FileMode(file.Mode),
|
||||
User: ignTypes.FileUser{Id: file.User.Id},
|
||||
Group: ignTypes.FileGroup{Id: file.Group.Id},
|
||||
}
|
||||
|
||||
if file.Contents.Inline != "" {
|
||||
newFile.Contents = ignTypes.FileContents{
|
||||
Source: ignTypes.Url{
|
||||
Scheme: "data",
|
||||
Opaque: "," + dataurl.EscapeString(file.Contents.Inline),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if file.Contents.Remote.Url != "" {
|
||||
source, err := url.Parse(file.Contents.Remote.Url)
|
||||
if err != nil {
|
||||
return out, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
newFile.Contents = ignTypes.FileContents{Source: ignTypes.Url(*source)}
|
||||
}
|
||||
|
||||
if newFile.Contents == (ignTypes.FileContents{}) {
|
||||
newFile.Contents = ignTypes.FileContents{
|
||||
Source: ignTypes.Url{
|
||||
Scheme: "data",
|
||||
Opaque: ",",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
newFile.Contents.Compression = ignTypes.Compression(file.Contents.Remote.Compression)
|
||||
newFile.Contents.Verification = convertVerification(file.Contents.Remote.Verification)
|
||||
|
||||
out.Storage.Files = append(out.Storage.Files, newFile)
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
71
vendor/github.com/coreos/container-linux-config-transpiler/config/types/filesystems.go
generated
vendored
Normal file
71
vendor/github.com/coreos/container-linux-config-transpiler/config/types/filesystems.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Filesystem struct {
|
||||
Name string `yaml:"name"`
|
||||
Mount *Mount `yaml:"mount"`
|
||||
Path string `yaml:"path"`
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
Device string `yaml:"device"`
|
||||
Format string `yaml:"format"`
|
||||
Create *Create `yaml:"create"`
|
||||
}
|
||||
|
||||
type Create struct {
|
||||
Force bool `yaml:"force"`
|
||||
Options []string `yaml:"options"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, filesystem := range in.Storage.Filesystems {
|
||||
newFilesystem := ignTypes.Filesystem{
|
||||
Name: filesystem.Name,
|
||||
Path: func(p ignTypes.Path) *ignTypes.Path {
|
||||
if p == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &p
|
||||
}(ignTypes.Path(filesystem.Path)),
|
||||
}
|
||||
|
||||
if filesystem.Mount != nil {
|
||||
newFilesystem.Mount = &ignTypes.FilesystemMount{
|
||||
Device: ignTypes.Path(filesystem.Mount.Device),
|
||||
Format: ignTypes.FilesystemFormat(filesystem.Mount.Format),
|
||||
}
|
||||
|
||||
if filesystem.Mount.Create != nil {
|
||||
newFilesystem.Mount.Create = &ignTypes.FilesystemCreate{
|
||||
Force: filesystem.Mount.Create.Force,
|
||||
Options: ignTypes.MkfsOptions(filesystem.Mount.Create.Options),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.Storage.Filesystems = append(out.Storage.Filesystems, newFilesystem)
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
157
vendor/github.com/coreos/container-linux-config-transpiler/config/types/flannel.go
generated
vendored
Normal file
157
vendor/github.com/coreos/container-linux-config-transpiler/config/types/flannel.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFlannelTooOld = errors.New("invalid flannel version (too old)")
|
||||
ErrFlannelMinorTooNew = errors.New("flannel minor version too new. Only options available in the previous minor version will be supported")
|
||||
OldestFlannelVersion = *semver.New("0.5.0")
|
||||
FlannelDefaultVersion = *semver.New("0.6.0")
|
||||
)
|
||||
|
||||
type Flannel struct {
|
||||
Version *FlannelVersion `yaml:"version"`
|
||||
Options
|
||||
}
|
||||
|
||||
type flannelCommon Flannel
|
||||
|
||||
type FlannelVersion semver.Version
|
||||
|
||||
func (v *FlannelVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
t := semver.Version(*v)
|
||||
if err := unmarshal(&t); err != nil {
|
||||
return err
|
||||
}
|
||||
*v = FlannelVersion(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fv FlannelVersion) Validate() report.Report {
|
||||
v := semver.Version(fv)
|
||||
switch {
|
||||
case v.LessThan(OldestFlannelVersion):
|
||||
return report.ReportFromError(ErrFlannelTooOld, report.EntryError)
|
||||
case v.Major == 0 && fv.Minor > 7:
|
||||
return report.ReportFromError(ErrFlannelMinorTooNew, report.EntryWarning)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
func (fv FlannelVersion) String() string {
|
||||
return semver.Version(fv).String()
|
||||
}
|
||||
|
||||
func (flannel *Flannel) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
t := flannelCommon(*flannel)
|
||||
if err := unmarshal(&t); err != nil {
|
||||
return err
|
||||
}
|
||||
*flannel = Flannel(t)
|
||||
|
||||
var v semver.Version
|
||||
if flannel.Version == nil {
|
||||
v = FlannelDefaultVersion
|
||||
} else {
|
||||
v = semver.Version(*flannel.Version)
|
||||
}
|
||||
|
||||
if v.Major == 0 && v.Minor >= 7 {
|
||||
o := Flannel0_7{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
flannel.Options = o
|
||||
} else if v.Major == 0 && v.Minor == 6 {
|
||||
o := Flannel0_6{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
flannel.Options = o
|
||||
} else if v.Major == 0 && v.Minor == 5 {
|
||||
o := Flannel0_5{}
|
||||
if err := unmarshal(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
flannel.Options = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
if in.Flannel != nil {
|
||||
contents, err := flannelContents(*in.Flannel, platform)
|
||||
if err != nil {
|
||||
return ignTypes.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Systemd.Units = append(out.Systemd.Units, ignTypes.SystemdUnit{
|
||||
Name: "flanneld.service",
|
||||
Enable: true,
|
||||
DropIns: []ignTypes.SystemdUnitDropIn{{
|
||||
Name: "20-clct-flannel.conf",
|
||||
Contents: contents,
|
||||
}},
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
|
||||
// flannelContents creates the string containing the systemd drop in for flannel
|
||||
func flannelContents(flannel Flannel, platform string) (string, error) {
|
||||
args := getCliArgs(flannel.Options)
|
||||
vars := []string{fmt.Sprintf("FLANNEL_IMAGE_TAG=v%s", flannel.Version)}
|
||||
|
||||
return assembleUnit("/usr/lib/coreos/flannel-wrapper $FLANNEL_OPTS", args, vars, platform)
|
||||
}
|
||||
|
||||
// Flannel0_7 represents flannel options for version 0.7.x. Don't embed Flannel0_6 because
|
||||
// the yaml parser doesn't handle embedded structs
|
||||
type Flannel0_7 struct {
|
||||
EtcdUsername string `yaml:"etcd_username" cli:"etcd-username"`
|
||||
EtcdPassword string `yaml:"etcd_password" cli:"etcd-password"`
|
||||
EtcdEndpoints string `yaml:"etcd_endpoints" cli:"etcd-endpoints"`
|
||||
EtcdCAFile string `yaml:"etcd_cafile" cli:"etcd-cafile"`
|
||||
EtcdCertFile string `yaml:"etcd_certfile" cli:"etcd-certfile"`
|
||||
EtcdKeyFile string `yaml:"etcd_keyfile" cli:"etcd-keyfile"`
|
||||
EtcdPrefix string `yaml:"etcd_prefix" cli:"etcd-prefix"`
|
||||
IPMasq string `yaml:"ip_masq" cli:"ip-masq"`
|
||||
SubnetFile string `yaml:"subnet_file" cli:"subnet-file"`
|
||||
Iface string `yaml:"interface" cli:"iface"`
|
||||
PublicIP string `yaml:"public_ip" cli:"public-ip"`
|
||||
KubeSubnetMgr bool `yaml:"kube_subnet_mgr" cli:"kube-subnet-mgr"`
|
||||
}
|
||||
|
||||
type Flannel0_6 struct {
|
||||
EtcdUsername string `yaml:"etcd_username" cli:"etcd-username"`
|
||||
EtcdPassword string `yaml:"etcd_password" cli:"etcd-password"`
|
||||
EtcdEndpoints string `yaml:"etcd_endpoints" cli:"etcd-endpoints"`
|
||||
EtcdCAFile string `yaml:"etcd_cafile" cli:"etcd-cafile"`
|
||||
EtcdCertFile string `yaml:"etcd_certfile" cli:"etcd-certfile"`
|
||||
EtcdKeyFile string `yaml:"etcd_keyfile" cli:"etcd-keyfile"`
|
||||
EtcdPrefix string `yaml:"etcd_prefix" cli:"etcd-prefix"`
|
||||
IPMasq string `yaml:"ip_masq" cli:"ip-masq"`
|
||||
SubnetFile string `yaml:"subnet_file" cli:"subnet-file"`
|
||||
Iface string `yaml:"interface" cli:"iface"`
|
||||
PublicIP string `yaml:"public_ip" cli:"public-ip"`
|
||||
}
|
||||
|
||||
type Flannel0_5 struct {
|
||||
EtcdEndpoints string `yaml:"etcd_endpoints" cli:"etcd-endpoints"`
|
||||
EtcdCAFile string `yaml:"etcd_cafile" cli:"etcd-cafile"`
|
||||
EtcdCertFile string `yaml:"etcd_certfile" cli:"etcd-certfile"`
|
||||
EtcdKeyFile string `yaml:"etcd_keyfile" cli:"etcd-keyfile"`
|
||||
EtcdPrefix string `yaml:"etcd_prefix" cli:"etcd-prefix"`
|
||||
IPMasq string `yaml:"ip_masq" cli:"ip-masq"`
|
||||
SubnetFile string `yaml:"subnet_file" cli:"subnet-file"`
|
||||
Iface string `yaml:"interface" cli:"iface"`
|
||||
PublicIP string `yaml:"public_ip" cli:"public-ip"`
|
||||
}
|
||||
41
vendor/github.com/coreos/container-linux-config-transpiler/config/types/locksmith.go
generated
vendored
Normal file
41
vendor/github.com/coreos/container-linux-config-transpiler/config/types/locksmith.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnknownStrategy = errors.New("unknown reboot strategy")
|
||||
)
|
||||
|
||||
type Locksmith struct {
|
||||
RebootStrategy RebootStrategy `yaml:"reboot_strategy"`
|
||||
}
|
||||
|
||||
type RebootStrategy string
|
||||
|
||||
func (r RebootStrategy) Validate() report.Report {
|
||||
switch strings.ToLower(string(r)) {
|
||||
case "reboot", "etcd-lock", "off":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(ErrUnknownStrategy, report.EntryError)
|
||||
}
|
||||
}
|
||||
41
vendor/github.com/coreos/container-linux-config-transpiler/config/types/networkd.go
generated
vendored
Normal file
41
vendor/github.com/coreos/container-linux-config-transpiler/config/types/networkd.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Networkd struct {
|
||||
Units []NetworkdUnit `yaml:"units"`
|
||||
}
|
||||
|
||||
type NetworkdUnit struct {
|
||||
Name string `yaml:"name"`
|
||||
Contents string `yaml:"contents"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, unit := range in.Networkd.Units {
|
||||
out.Networkd.Units = append(out.Networkd.Units, ignTypes.NetworkdUnit{
|
||||
Name: ignTypes.NetworkdUnitName(unit.Name),
|
||||
Contents: unit.Contents,
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
@@ -14,6 +14,11 @@
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Passwd struct {
|
||||
Users []User `yaml:"users"`
|
||||
Groups []Group `yaml:"groups"`
|
||||
@@ -45,3 +50,42 @@ type Group struct {
|
||||
PasswordHash string `yaml:"password_hash"`
|
||||
System bool `yaml:"system"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, user := range in.Passwd.Users {
|
||||
newUser := ignTypes.User{
|
||||
Name: user.Name,
|
||||
PasswordHash: user.PasswordHash,
|
||||
SSHAuthorizedKeys: user.SSHAuthorizedKeys,
|
||||
}
|
||||
|
||||
if user.Create != nil {
|
||||
newUser.Create = &ignTypes.UserCreate{
|
||||
Uid: user.Create.Uid,
|
||||
GECOS: user.Create.GECOS,
|
||||
Homedir: user.Create.Homedir,
|
||||
NoCreateHome: user.Create.NoCreateHome,
|
||||
PrimaryGroup: user.Create.PrimaryGroup,
|
||||
Groups: user.Create.Groups,
|
||||
NoUserGroup: user.Create.NoUserGroup,
|
||||
System: user.Create.System,
|
||||
NoLogInit: user.Create.NoLogInit,
|
||||
Shell: user.Create.Shell,
|
||||
}
|
||||
}
|
||||
|
||||
out.Passwd.Users = append(out.Passwd.Users, newUser)
|
||||
}
|
||||
|
||||
for _, group := range in.Passwd.Groups {
|
||||
out.Passwd.Groups = append(out.Passwd.Groups, ignTypes.Group{
|
||||
Name: group.Name,
|
||||
Gid: group.Gid,
|
||||
PasswordHash: group.PasswordHash,
|
||||
System: group.System,
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
46
vendor/github.com/coreos/container-linux-config-transpiler/config/types/raid.go
generated
vendored
Normal file
46
vendor/github.com/coreos/container-linux-config-transpiler/config/types/raid.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Raid struct {
|
||||
Name string `yaml:"name"`
|
||||
Level string `yaml:"level"`
|
||||
Devices []string `yaml:"devices"`
|
||||
Spares int `yaml:"spares"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, array := range in.Storage.Arrays {
|
||||
newArray := ignTypes.Raid{
|
||||
Name: array.Name,
|
||||
Level: array.Level,
|
||||
Spares: array.Spares,
|
||||
}
|
||||
|
||||
for _, device := range array.Devices {
|
||||
newArray.Devices = append(newArray.Devices, ignTypes.Path(device))
|
||||
}
|
||||
|
||||
out.Storage.Arrays = append(out.Storage.Arrays, newArray)
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
60
vendor/github.com/coreos/container-linux-config-transpiler/config/types/systemd.go
generated
vendored
Normal file
60
vendor/github.com/coreos/container-linux-config-transpiler/config/types/systemd.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Systemd struct {
|
||||
Units []SystemdUnit `yaml:"units"`
|
||||
}
|
||||
|
||||
type SystemdUnit struct {
|
||||
Name string `yaml:"name"`
|
||||
Enable bool `yaml:"enable"`
|
||||
Mask bool `yaml:"mask"`
|
||||
Contents string `yaml:"contents"`
|
||||
DropIns []SystemdUnitDropIn `yaml:"dropins"`
|
||||
}
|
||||
|
||||
type SystemdUnitDropIn struct {
|
||||
Name string `yaml:"name"`
|
||||
Contents string `yaml:"contents"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
for _, unit := range in.Systemd.Units {
|
||||
newUnit := ignTypes.SystemdUnit{
|
||||
Name: ignTypes.SystemdUnitName(unit.Name),
|
||||
Enable: unit.Enable,
|
||||
Mask: unit.Mask,
|
||||
Contents: unit.Contents,
|
||||
}
|
||||
|
||||
for _, dropIn := range unit.DropIns {
|
||||
newUnit.DropIns = append(newUnit.DropIns, ignTypes.SystemdUnitDropIn{
|
||||
Name: ignTypes.SystemdUnitDropInName(dropIn.Name),
|
||||
Contents: dropIn.Contents,
|
||||
})
|
||||
}
|
||||
|
||||
out.Systemd.Units = append(out.Systemd.Units, newUnit)
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
91
vendor/github.com/coreos/container-linux-config-transpiler/config/types/update.go
generated
vendored
Normal file
91
vendor/github.com/coreos/container-linux-config-transpiler/config/types/update.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2017 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
ignTypes "github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnknownGroup = errors.New("unknown update group")
|
||||
)
|
||||
|
||||
type Update struct {
|
||||
Group UpdateGroup `yaml:"group"`
|
||||
Server UpdateServer `yaml:"server"`
|
||||
}
|
||||
|
||||
type UpdateGroup string
|
||||
type UpdateServer string
|
||||
|
||||
func (u Update) Validate() report.Report {
|
||||
switch strings.ToLower(string(u.Group)) {
|
||||
case "stable", "beta", "alpha":
|
||||
return report.Report{}
|
||||
default:
|
||||
if u.Server == "" {
|
||||
return report.ReportFromError(ErrUnknownGroup, report.EntryWarning)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
}
|
||||
|
||||
func (s UpdateServer) Validate() report.Report {
|
||||
_, err := url.Parse(string(s))
|
||||
if err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
register2_0(func(in Config, out ignTypes.Config, platform string) (ignTypes.Config, report.Report) {
|
||||
var contents string
|
||||
if in.Update != nil {
|
||||
if in.Update.Group != "" {
|
||||
contents += fmt.Sprintf("GROUP=%s", strings.ToLower(string(in.Update.Group)))
|
||||
}
|
||||
if in.Update.Server != "" {
|
||||
contents += fmt.Sprintf("\nSERVER=%s", in.Update.Server)
|
||||
}
|
||||
}
|
||||
if in.Locksmith != nil {
|
||||
if in.Locksmith.RebootStrategy != "" {
|
||||
contents += fmt.Sprintf("\nREBOOT_STRATEGY=%s", strings.ToLower(string(in.Locksmith.RebootStrategy)))
|
||||
}
|
||||
}
|
||||
if contents != "" {
|
||||
out.Storage.Files = append(out.Storage.Files, ignTypes.File{
|
||||
Filesystem: "root",
|
||||
Path: "/etc/coreos/update.conf",
|
||||
Mode: 0644,
|
||||
Contents: ignTypes.FileContents{
|
||||
Source: ignTypes.Url{
|
||||
Scheme: "data",
|
||||
Opaque: "," + dataurl.EscapeString(contents),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return out, report.Report{}
|
||||
})
|
||||
}
|
||||
2
vendor/github.com/coreos/coreos-cloudinit/config/flannel.go
generated
vendored
2
vendor/github.com/coreos/coreos-cloudinit/config/flannel.go
generated
vendored
@@ -20,6 +20,8 @@ type Flannel struct {
|
||||
EtcdCertFile string `yaml:"etcd_certfile" env:"FLANNELD_ETCD_CERTFILE"`
|
||||
EtcdKeyFile string `yaml:"etcd_keyfile" env:"FLANNELD_ETCD_KEYFILE"`
|
||||
EtcdPrefix string `yaml:"etcd_prefix" env:"FLANNELD_ETCD_PREFIX"`
|
||||
EtcdUsername string `yaml:"etcd_username" env:"FLANNELD_ETCD_USERNAME"`
|
||||
EtcdPassword string `yaml:"etcd_password" env:"FLANNELD_ETCD_PASSWORD"`
|
||||
IPMasq string `yaml:"ip_masq" env:"FLANNELD_IP_MASQ"`
|
||||
SubnetFile string `yaml:"subnet_file" env:"FLANNELD_SUBNET_FILE"`
|
||||
Iface string `yaml:"interface" env:"FLANNELD_IFACE"`
|
||||
|
||||
2
vendor/github.com/coreos/coreos-cloudinit/config/fleet.go
generated
vendored
2
vendor/github.com/coreos/coreos-cloudinit/config/fleet.go
generated
vendored
@@ -25,6 +25,8 @@ type Fleet struct {
|
||||
EtcdKeyPrefix string `yaml:"etcd_key_prefix" env:"FLEET_ETCD_KEY_PREFIX"`
|
||||
EtcdRequestTimeout float64 `yaml:"etcd_request_timeout" env:"FLEET_ETCD_REQUEST_TIMEOUT"`
|
||||
EtcdServers string `yaml:"etcd_servers" env:"FLEET_ETCD_SERVERS"`
|
||||
EtcdUsername string `yaml:"etcd_username" env:"FLEET_ETCD_USERNAME"`
|
||||
EtcdPassword string `yaml:"etcd_password" env:"FLEET_ETCD_PASSWORD"`
|
||||
Metadata string `yaml:"metadata" env:"FLEET_METADATA"`
|
||||
PublicIP string `yaml:"public_ip" env:"FLEET_PUBLIC_IP"`
|
||||
TokenLimit int `yaml:"token_limit" env:"FLEET_TOKEN_LIMIT"`
|
||||
|
||||
2
vendor/github.com/coreos/coreos-cloudinit/config/locksmith.go
generated
vendored
2
vendor/github.com/coreos/coreos-cloudinit/config/locksmith.go
generated
vendored
@@ -19,6 +19,8 @@ type Locksmith struct {
|
||||
EtcdCAFile string `yaml:"etcd_cafile" env:"LOCKSMITHD_ETCD_CAFILE"`
|
||||
EtcdCertFile string `yaml:"etcd_certfile" env:"LOCKSMITHD_ETCD_CERTFILE"`
|
||||
EtcdKeyFile string `yaml:"etcd_keyfile" env:"LOCKSMITHD_ETCD_KEYFILE"`
|
||||
EtcdUsername string `yaml:"etcd_username" env:"LOCKSMITHD_ETCD_USERNAME"`
|
||||
EtcdPassword string `yaml:"etcd_password" env:"LOCKSMITHD_ETCD_PASSWORD"`
|
||||
Group string `yaml:"group" env:"LOCKSMITHD_GROUP"`
|
||||
RebootWindowStart string `yaml:"window_start" env:"REBOOT_WINDOW_START" valid:"^((?i:sun|mon|tue|wed|thu|fri|sat|sun) )?0*([0-9]|1[0-9]|2[0-3]):0*([0-9]|[1-5][0-9])$"`
|
||||
RebootWindowLength string `yaml:"window_length" env:"REBOOT_WINDOW_LENGTH" valid:"^[-+]?([0-9]*(\\.[0-9]*)?[a-z]+)+$"`
|
||||
|
||||
6
vendor/github.com/coreos/coreos-cloudinit/coreos-cloudinit.go
generated
vendored
6
vendor/github.com/coreos/coreos-cloudinit/coreos-cloudinit.go
generated
vendored
@@ -109,7 +109,6 @@ var (
|
||||
oemConfigs = map[string]oemConfig{
|
||||
"digitalocean": {
|
||||
"from-digitalocean-metadata": "http://169.254.169.254/",
|
||||
"convert-netconf": "digitalocean",
|
||||
},
|
||||
"ec2-compat": {
|
||||
"from-ec2-metadata": "http://169.254.169.254/",
|
||||
@@ -170,11 +169,10 @@ func main() {
|
||||
switch flags.convertNetconf {
|
||||
case "":
|
||||
case "debian":
|
||||
case "digitalocean":
|
||||
case "packet":
|
||||
case "vmware":
|
||||
default:
|
||||
fmt.Printf("Invalid option to -convert-netconf: '%s'. Supported options: 'debian, digitalocean, packet, vmware'\n", flags.convertNetconf)
|
||||
fmt.Printf("Invalid option to -convert-netconf: '%s'. Supported options: 'debian, packet, vmware'\n", flags.convertNetconf)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
@@ -256,8 +254,6 @@ func main() {
|
||||
switch flags.convertNetconf {
|
||||
case "debian":
|
||||
ifaces, err = network.ProcessDebianNetconf(metadata.NetworkConfig.([]byte))
|
||||
case "digitalocean":
|
||||
ifaces, err = network.ProcessDigitalOceanNetconf(metadata.NetworkConfig.(digitalocean.Metadata))
|
||||
case "packet":
|
||||
ifaces, err = network.ProcessPacketNetconf(metadata.NetworkConfig.(packet.NetworkData))
|
||||
case "vmware":
|
||||
|
||||
281
vendor/github.com/coreos/fuze/config/convert.go
generated
vendored
281
vendor/github.com/coreos/fuze/config/convert.go
generated
vendored
@@ -1,281 +0,0 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
||||
"github.com/alecthomas/units"
|
||||
fuzeTypes "github.com/coreos/fuze/config/types"
|
||||
"github.com/coreos/ignition/config/types"
|
||||
"github.com/coreos/ignition/config/validate"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
const (
|
||||
BYTES_PER_SECTOR = 512
|
||||
)
|
||||
|
||||
func ConvertAs2_0_0(in fuzeTypes.Config) (types.Config, report.Report) {
|
||||
out := types.Config{
|
||||
Ignition: types.Ignition{
|
||||
Version: types.IgnitionVersion{Major: 2, Minor: 0},
|
||||
},
|
||||
}
|
||||
|
||||
for _, ref := range in.Ignition.Config.Append {
|
||||
newRef, err := convertConfigReference(ref)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Ignition.Config.Append = append(out.Ignition.Config.Append, newRef)
|
||||
}
|
||||
|
||||
if in.Ignition.Config.Replace != nil {
|
||||
newRef, err := convertConfigReference(*in.Ignition.Config.Replace)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
out.Ignition.Config.Replace = &newRef
|
||||
}
|
||||
|
||||
for _, disk := range in.Storage.Disks {
|
||||
newDisk := types.Disk{
|
||||
Device: types.Path(disk.Device),
|
||||
WipeTable: disk.WipeTable,
|
||||
}
|
||||
|
||||
for _, partition := range disk.Partitions {
|
||||
size, err := convertPartitionDimension(partition.Size)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
start, err := convertPartitionDimension(partition.Start)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
newDisk.Partitions = append(newDisk.Partitions, types.Partition{
|
||||
Label: types.PartitionLabel(partition.Label),
|
||||
Number: partition.Number,
|
||||
Size: size,
|
||||
Start: start,
|
||||
TypeGUID: types.PartitionTypeGUID(partition.TypeGUID),
|
||||
})
|
||||
}
|
||||
|
||||
out.Storage.Disks = append(out.Storage.Disks, newDisk)
|
||||
}
|
||||
|
||||
for _, array := range in.Storage.Arrays {
|
||||
newArray := types.Raid{
|
||||
Name: array.Name,
|
||||
Level: array.Level,
|
||||
Spares: array.Spares,
|
||||
}
|
||||
|
||||
for _, device := range array.Devices {
|
||||
newArray.Devices = append(newArray.Devices, types.Path(device))
|
||||
}
|
||||
|
||||
out.Storage.Arrays = append(out.Storage.Arrays, newArray)
|
||||
}
|
||||
|
||||
for _, filesystem := range in.Storage.Filesystems {
|
||||
newFilesystem := types.Filesystem{
|
||||
Name: filesystem.Name,
|
||||
Path: func(p types.Path) *types.Path {
|
||||
if p == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &p
|
||||
}(types.Path(filesystem.Path)),
|
||||
}
|
||||
|
||||
if filesystem.Mount != nil {
|
||||
newFilesystem.Mount = &types.FilesystemMount{
|
||||
Device: types.Path(filesystem.Mount.Device),
|
||||
Format: types.FilesystemFormat(filesystem.Mount.Format),
|
||||
}
|
||||
|
||||
if filesystem.Mount.Create != nil {
|
||||
newFilesystem.Mount.Create = &types.FilesystemCreate{
|
||||
Force: filesystem.Mount.Create.Force,
|
||||
Options: types.MkfsOptions(filesystem.Mount.Create.Options),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.Storage.Filesystems = append(out.Storage.Filesystems, newFilesystem)
|
||||
}
|
||||
|
||||
for _, file := range in.Storage.Files {
|
||||
newFile := types.File{
|
||||
Filesystem: file.Filesystem,
|
||||
Path: types.Path(file.Path),
|
||||
Mode: types.FileMode(file.Mode),
|
||||
User: types.FileUser{Id: file.User.Id},
|
||||
Group: types.FileGroup{Id: file.Group.Id},
|
||||
}
|
||||
|
||||
if file.Contents.Inline != "" {
|
||||
newFile.Contents = types.FileContents{
|
||||
Source: types.Url{
|
||||
Scheme: "data",
|
||||
Opaque: "," + dataurl.EscapeString(file.Contents.Inline),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if file.Contents.Remote.Url != "" {
|
||||
source, err := url.Parse(file.Contents.Remote.Url)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
newFile.Contents = types.FileContents{Source: types.Url(*source)}
|
||||
}
|
||||
|
||||
if newFile.Contents == (types.FileContents{}) {
|
||||
newFile.Contents = types.FileContents{
|
||||
Source: types.Url{
|
||||
Scheme: "data",
|
||||
Opaque: ",",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
newFile.Contents.Compression = types.Compression(file.Contents.Remote.Compression)
|
||||
newFile.Contents.Verification = convertVerification(file.Contents.Remote.Verification)
|
||||
|
||||
out.Storage.Files = append(out.Storage.Files, newFile)
|
||||
}
|
||||
|
||||
for _, unit := range in.Systemd.Units {
|
||||
newUnit := types.SystemdUnit{
|
||||
Name: types.SystemdUnitName(unit.Name),
|
||||
Enable: unit.Enable,
|
||||
Mask: unit.Mask,
|
||||
Contents: unit.Contents,
|
||||
}
|
||||
|
||||
for _, dropIn := range unit.DropIns {
|
||||
newUnit.DropIns = append(newUnit.DropIns, types.SystemdUnitDropIn{
|
||||
Name: types.SystemdUnitDropInName(dropIn.Name),
|
||||
Contents: dropIn.Contents,
|
||||
})
|
||||
}
|
||||
|
||||
out.Systemd.Units = append(out.Systemd.Units, newUnit)
|
||||
}
|
||||
|
||||
for _, unit := range in.Networkd.Units {
|
||||
out.Networkd.Units = append(out.Networkd.Units, types.NetworkdUnit{
|
||||
Name: types.NetworkdUnitName(unit.Name),
|
||||
Contents: unit.Contents,
|
||||
})
|
||||
}
|
||||
|
||||
for _, user := range in.Passwd.Users {
|
||||
newUser := types.User{
|
||||
Name: user.Name,
|
||||
PasswordHash: user.PasswordHash,
|
||||
SSHAuthorizedKeys: user.SSHAuthorizedKeys,
|
||||
}
|
||||
|
||||
if user.Create != nil {
|
||||
newUser.Create = &types.UserCreate{
|
||||
Uid: user.Create.Uid,
|
||||
GECOS: user.Create.GECOS,
|
||||
Homedir: user.Create.Homedir,
|
||||
NoCreateHome: user.Create.NoCreateHome,
|
||||
PrimaryGroup: user.Create.PrimaryGroup,
|
||||
Groups: user.Create.Groups,
|
||||
NoUserGroup: user.Create.NoUserGroup,
|
||||
System: user.Create.System,
|
||||
NoLogInit: user.Create.NoLogInit,
|
||||
Shell: user.Create.Shell,
|
||||
}
|
||||
}
|
||||
|
||||
out.Passwd.Users = append(out.Passwd.Users, newUser)
|
||||
}
|
||||
|
||||
for _, group := range in.Passwd.Groups {
|
||||
out.Passwd.Groups = append(out.Passwd.Groups, types.Group{
|
||||
Name: group.Name,
|
||||
Gid: group.Gid,
|
||||
PasswordHash: group.PasswordHash,
|
||||
System: group.System,
|
||||
})
|
||||
}
|
||||
|
||||
r := validate.ValidateWithoutSource(reflect.ValueOf(out))
|
||||
if r.IsFatal() {
|
||||
return types.Config{}, r
|
||||
}
|
||||
|
||||
return out, r
|
||||
}
|
||||
|
||||
func convertConfigReference(in fuzeTypes.ConfigReference) (types.ConfigReference, error) {
|
||||
source, err := url.Parse(in.Source)
|
||||
if err != nil {
|
||||
return types.ConfigReference{}, err
|
||||
}
|
||||
|
||||
return types.ConfigReference{
|
||||
Source: types.Url(*source),
|
||||
Verification: convertVerification(in.Verification),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertVerification(in fuzeTypes.Verification) types.Verification {
|
||||
if in.Hash.Function == "" || in.Hash.Sum == "" {
|
||||
return types.Verification{}
|
||||
}
|
||||
|
||||
return types.Verification{
|
||||
&types.Hash{
|
||||
Function: in.Hash.Function,
|
||||
Sum: in.Hash.Sum,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func convertPartitionDimension(in string) (types.PartitionDimension, error) {
|
||||
if in == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
b, err := units.ParseBase2Bytes(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if b < 0 {
|
||||
return 0, fmt.Errorf("invalid dimension (negative): %q", in)
|
||||
}
|
||||
|
||||
// Translate bytes into sectors
|
||||
sectors := (b / BYTES_PER_SECTOR)
|
||||
if b%BYTES_PER_SECTOR != 0 {
|
||||
sectors++
|
||||
}
|
||||
return types.PartitionDimension(uint64(sectors)), nil
|
||||
}
|
||||
37
vendor/github.com/coreos/fuze/config/types/config.go
generated
vendored
37
vendor/github.com/coreos/fuze/config/types/config.go
generated
vendored
@@ -1,37 +0,0 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Config struct {
|
||||
Ignition Ignition `yaml:"ignition"`
|
||||
Storage Storage `yaml:"storage"`
|
||||
Systemd Systemd `yaml:"systemd"`
|
||||
Networkd Networkd `yaml:"networkd"`
|
||||
Passwd Passwd `yaml:"passwd"`
|
||||
}
|
||||
|
||||
type Ignition struct {
|
||||
Config IgnitionConfig `yaml:"config"`
|
||||
}
|
||||
|
||||
type IgnitionConfig struct {
|
||||
Append []ConfigReference `yaml:"append"`
|
||||
Replace *ConfigReference `yaml:"replace"`
|
||||
}
|
||||
|
||||
type ConfigReference struct {
|
||||
Source string `yaml:"source"`
|
||||
Verification Verification `yaml:"verification"`
|
||||
}
|
||||
43
vendor/github.com/coreos/fuze/config/types/files.go
generated
vendored
43
vendor/github.com/coreos/fuze/config/types/files.go
generated
vendored
@@ -1,43 +0,0 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type File struct {
|
||||
Filesystem string `yaml:"filesystem"`
|
||||
Path string `yaml:"path"`
|
||||
Mode int `yaml:"mode"`
|
||||
Contents FileContents `yaml:"contents"`
|
||||
User FileUser `yaml:"user"`
|
||||
Group FileGroup `yaml:"group"`
|
||||
}
|
||||
|
||||
type FileContents struct {
|
||||
Remote Remote `yaml:"remote"`
|
||||
Inline string `yaml:"inline"`
|
||||
}
|
||||
|
||||
type Remote struct {
|
||||
Url string `yaml:"url"`
|
||||
Compression string `yaml:"compression"`
|
||||
Verification Verification `yaml:"verification"`
|
||||
}
|
||||
|
||||
type FileUser struct {
|
||||
Id int `yaml:"id"`
|
||||
}
|
||||
|
||||
type FileGroup struct {
|
||||
Id int `yaml:"id"`
|
||||
}
|
||||
100
vendor/github.com/coreos/go-semver/semver/semver.go
generated
vendored
100
vendor/github.com/coreos/go-semver/semver/semver.go
generated
vendored
@@ -44,16 +44,36 @@ func splitOff(input *string, delim string) (val string) {
|
||||
return val
|
||||
}
|
||||
|
||||
func New(version string) *Version {
|
||||
return Must(NewVersion(version))
|
||||
}
|
||||
|
||||
func NewVersion(version string) (*Version, error) {
|
||||
v := Version{}
|
||||
|
||||
v.Metadata = splitOff(&version, "+")
|
||||
v.PreRelease = PreRelease(splitOff(&version, "-"))
|
||||
if err := v.Set(version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
// Must is a helper for wrapping NewVersion and will panic if err is not nil.
|
||||
func Must(v *Version, err error) *Version {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Set parses and updates v from the given version string. Implements flag.Value
|
||||
func (v *Version) Set(version string) error {
|
||||
metadata := splitOff(&version, "+")
|
||||
preRelease := PreRelease(splitOff(&version, "-"))
|
||||
dotParts := strings.SplitN(version, ".", 3)
|
||||
|
||||
if len(dotParts) != 3 {
|
||||
return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version))
|
||||
return fmt.Errorf("%s is not in dotted-tri format", version)
|
||||
}
|
||||
|
||||
parsed := make([]int64, 3, 3)
|
||||
@@ -62,22 +82,16 @@ func NewVersion(version string) (*Version, error) {
|
||||
val, err := strconv.ParseInt(v, 10, 64)
|
||||
parsed[i] = val
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
v.Metadata = metadata
|
||||
v.PreRelease = preRelease
|
||||
v.Major = parsed[0]
|
||||
v.Minor = parsed[1]
|
||||
v.Patch = parsed[2]
|
||||
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func Must(v *Version, err error) *Version {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
@@ -101,12 +115,7 @@ func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
if err := unmarshal(&data); err != nil {
|
||||
return err
|
||||
}
|
||||
vv, err := NewVersion(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = *vv
|
||||
return nil
|
||||
return v.Set(data)
|
||||
}
|
||||
|
||||
func (v Version) MarshalJSON() ([]byte, error) {
|
||||
@@ -121,30 +130,29 @@ func (v *Version) UnmarshalJSON(data []byte) error {
|
||||
if l < 2 || data[0] != '"' || data[l-1] != '"' {
|
||||
return errors.New("invalid semver string")
|
||||
}
|
||||
vv, err := NewVersion(string(data[1 : l-1]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = *vv
|
||||
return nil
|
||||
return v.Set(string(data[1 : l-1]))
|
||||
}
|
||||
|
||||
// Compare tests if v is less than, equal to, or greater than versionB,
|
||||
// returning -1, 0, or +1 respectively.
|
||||
func (v Version) Compare(versionB Version) int {
|
||||
if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 {
|
||||
return cmp
|
||||
}
|
||||
return preReleaseCompare(v, versionB)
|
||||
}
|
||||
|
||||
// Equal tests if v is equal to versionB.
|
||||
func (v Version) Equal(versionB Version) bool {
|
||||
return v.Compare(versionB) == 0
|
||||
}
|
||||
|
||||
// LessThan tests if v is less than versionB.
|
||||
func (v Version) LessThan(versionB Version) bool {
|
||||
versionA := v
|
||||
cmp := recursiveCompare(versionA.Slice(), versionB.Slice())
|
||||
|
||||
if cmp == 0 {
|
||||
cmp = preReleaseCompare(versionA, versionB)
|
||||
}
|
||||
|
||||
if cmp == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return v.Compare(versionB) < 0
|
||||
}
|
||||
|
||||
/* Slice converts the comparable parts of the semver into a slice of strings */
|
||||
// Slice converts the comparable parts of the semver into a slice of integers.
|
||||
func (v Version) Slice() []int64 {
|
||||
return []int64{v.Major, v.Minor, v.Patch}
|
||||
}
|
||||
@@ -166,7 +174,7 @@ func preReleaseCompare(versionA Version, versionB Version) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// If there is a prelease, check and compare each part.
|
||||
// If there is a prerelease, check and compare each part.
|
||||
return recursivePreReleaseCompare(a.Slice(), b.Slice())
|
||||
}
|
||||
|
||||
@@ -188,9 +196,12 @@ func recursiveCompare(versionA []int64, versionB []int64) int {
|
||||
}
|
||||
|
||||
func recursivePreReleaseCompare(versionA []string, versionB []string) int {
|
||||
// Handle slice length disparity.
|
||||
// A larger set of pre-release fields has a higher precedence than a smaller set,
|
||||
// if all of the preceding identifiers are equal.
|
||||
if len(versionA) == 0 {
|
||||
// Nothing to compare too, so we return 0
|
||||
if len(versionB) > 0 {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
} else if len(versionB) == 0 {
|
||||
// We're longer than versionB so return 1.
|
||||
@@ -213,6 +224,13 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int {
|
||||
bInt = true
|
||||
}
|
||||
|
||||
// Numeric identifiers always have lower precedence than non-numeric identifiers.
|
||||
if aInt && !bInt {
|
||||
return -1
|
||||
} else if !aInt && bInt {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Handle Integer Comparison
|
||||
if aInt && bInt {
|
||||
if aI > bI {
|
||||
|
||||
276
vendor/github.com/coreos/go-systemd/unit/deserialize.go
generated
vendored
Normal file
276
vendor/github.com/coreos/go-systemd/unit/deserialize.go
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package unit
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
// SYSTEMD_LINE_MAX mimics the maximum line length that systemd can use.
|
||||
// On typical systemd platforms (i.e. modern Linux), this will most
|
||||
// commonly be 2048, so let's use that as a sanity check.
|
||||
// Technically, we should probably pull this at runtime:
|
||||
// SYSTEMD_LINE_MAX = int(C.sysconf(C.__SC_LINE_MAX))
|
||||
// but this would introduce an (unfortunate) dependency on cgo
|
||||
SYSTEMD_LINE_MAX = 2048
|
||||
|
||||
// characters that systemd considers indicate a newline
|
||||
SYSTEMD_NEWLINE = "\r\n"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrLineTooLong = fmt.Errorf("line too long (max %d bytes)", SYSTEMD_LINE_MAX)
|
||||
)
|
||||
|
||||
// Deserialize parses a systemd unit file into a list of UnitOption objects.
|
||||
func Deserialize(f io.Reader) (opts []*UnitOption, err error) {
|
||||
lexer, optchan, errchan := newLexer(f)
|
||||
go lexer.lex()
|
||||
|
||||
for opt := range optchan {
|
||||
opts = append(opts, &(*opt))
|
||||
}
|
||||
|
||||
err = <-errchan
|
||||
return opts, err
|
||||
}
|
||||
|
||||
func newLexer(f io.Reader) (*lexer, <-chan *UnitOption, <-chan error) {
|
||||
optchan := make(chan *UnitOption)
|
||||
errchan := make(chan error, 1)
|
||||
buf := bufio.NewReader(f)
|
||||
|
||||
return &lexer{buf, optchan, errchan, ""}, optchan, errchan
|
||||
}
|
||||
|
||||
type lexer struct {
|
||||
buf *bufio.Reader
|
||||
optchan chan *UnitOption
|
||||
errchan chan error
|
||||
section string
|
||||
}
|
||||
|
||||
func (l *lexer) lex() {
|
||||
var err error
|
||||
defer func() {
|
||||
close(l.optchan)
|
||||
close(l.errchan)
|
||||
}()
|
||||
next := l.lexNextSection
|
||||
for next != nil {
|
||||
if l.buf.Buffered() >= SYSTEMD_LINE_MAX {
|
||||
// systemd truncates lines longer than LINE_MAX
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=85308
|
||||
// Rather than allowing this to pass silently, let's
|
||||
// explicitly gate people from encountering this
|
||||
line, err := l.buf.Peek(SYSTEMD_LINE_MAX)
|
||||
if err != nil {
|
||||
l.errchan <- err
|
||||
return
|
||||
}
|
||||
if bytes.IndexAny(line, SYSTEMD_NEWLINE) == -1 {
|
||||
l.errchan <- ErrLineTooLong
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
next, err = next()
|
||||
if err != nil {
|
||||
l.errchan <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type lexStep func() (lexStep, error)
|
||||
|
||||
func (l *lexer) lexSectionName() (lexStep, error) {
|
||||
sec, err := l.buf.ReadBytes(']')
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to find end of section")
|
||||
}
|
||||
|
||||
return l.lexSectionSuffixFunc(string(sec[:len(sec)-1])), nil
|
||||
}
|
||||
|
||||
func (l *lexer) lexSectionSuffixFunc(section string) lexStep {
|
||||
return func() (lexStep, error) {
|
||||
garbage, _, err := l.toEOL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
garbage = bytes.TrimSpace(garbage)
|
||||
if len(garbage) > 0 {
|
||||
return nil, fmt.Errorf("found garbage after section name %s: %v", l.section, garbage)
|
||||
}
|
||||
|
||||
return l.lexNextSectionOrOptionFunc(section), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *lexer) ignoreLineFunc(next lexStep) lexStep {
|
||||
return func() (lexStep, error) {
|
||||
for {
|
||||
line, _, err := l.toEOL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
line = bytes.TrimSuffix(line, []byte{' '})
|
||||
|
||||
// lack of continuation means this line has been exhausted
|
||||
if !bytes.HasSuffix(line, []byte{'\\'}) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// reached end of buffer, safe to exit
|
||||
return next, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *lexer) lexNextSection() (lexStep, error) {
|
||||
r, _, err := l.buf.ReadRune()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r == '[' {
|
||||
return l.lexSectionName, nil
|
||||
} else if isComment(r) {
|
||||
return l.ignoreLineFunc(l.lexNextSection), nil
|
||||
}
|
||||
|
||||
return l.lexNextSection, nil
|
||||
}
|
||||
|
||||
func (l *lexer) lexNextSectionOrOptionFunc(section string) lexStep {
|
||||
return func() (lexStep, error) {
|
||||
r, _, err := l.buf.ReadRune()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if unicode.IsSpace(r) {
|
||||
return l.lexNextSectionOrOptionFunc(section), nil
|
||||
} else if r == '[' {
|
||||
return l.lexSectionName, nil
|
||||
} else if isComment(r) {
|
||||
return l.ignoreLineFunc(l.lexNextSectionOrOptionFunc(section)), nil
|
||||
}
|
||||
|
||||
l.buf.UnreadRune()
|
||||
return l.lexOptionNameFunc(section), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *lexer) lexOptionNameFunc(section string) lexStep {
|
||||
return func() (lexStep, error) {
|
||||
var partial bytes.Buffer
|
||||
for {
|
||||
r, _, err := l.buf.ReadRune()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r == '\n' || r == '\r' {
|
||||
return nil, errors.New("unexpected newline encountered while parsing option name")
|
||||
}
|
||||
|
||||
if r == '=' {
|
||||
break
|
||||
}
|
||||
|
||||
partial.WriteRune(r)
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(partial.String())
|
||||
return l.lexOptionValueFunc(section, name, bytes.Buffer{}), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *lexer) lexOptionValueFunc(section, name string, partial bytes.Buffer) lexStep {
|
||||
return func() (lexStep, error) {
|
||||
for {
|
||||
line, eof, err := l.toEOL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(bytes.TrimSpace(line)) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
partial.Write(line)
|
||||
|
||||
// lack of continuation means this value has been exhausted
|
||||
idx := bytes.LastIndex(line, []byte{'\\'})
|
||||
if idx == -1 || idx != (len(line)-1) {
|
||||
break
|
||||
}
|
||||
|
||||
if !eof {
|
||||
partial.WriteRune('\n')
|
||||
}
|
||||
|
||||
return l.lexOptionValueFunc(section, name, partial), nil
|
||||
}
|
||||
|
||||
val := partial.String()
|
||||
if strings.HasSuffix(val, "\n") {
|
||||
// A newline was added to the end, so the file didn't end with a backslash.
|
||||
// => Keep the newline
|
||||
val = strings.TrimSpace(val) + "\n"
|
||||
} else {
|
||||
val = strings.TrimSpace(val)
|
||||
}
|
||||
l.optchan <- &UnitOption{Section: section, Name: name, Value: val}
|
||||
|
||||
return l.lexNextSectionOrOptionFunc(section), nil
|
||||
}
|
||||
}
|
||||
|
||||
// toEOL reads until the end-of-line or end-of-file.
|
||||
// Returns (data, EOFfound, error)
|
||||
func (l *lexer) toEOL() ([]byte, bool, error) {
|
||||
line, err := l.buf.ReadBytes('\n')
|
||||
// ignore EOF here since it's roughly equivalent to EOL
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
line = bytes.TrimSuffix(line, []byte{'\r'})
|
||||
line = bytes.TrimSuffix(line, []byte{'\n'})
|
||||
|
||||
return line, err == io.EOF, nil
|
||||
}
|
||||
|
||||
func isComment(r rune) bool {
|
||||
return r == '#' || r == ';'
|
||||
}
|
||||
116
vendor/github.com/coreos/go-systemd/unit/escape.go
generated
vendored
Normal file
116
vendor/github.com/coreos/go-systemd/unit/escape.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Implements systemd-escape [--unescape] [--path]
|
||||
|
||||
package unit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
allowed = `:_.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`
|
||||
)
|
||||
|
||||
// If isPath is true:
|
||||
// We remove redundant '/'s, the leading '/', and trailing '/'.
|
||||
// If the result is empty, a '/' is inserted.
|
||||
//
|
||||
// We always:
|
||||
// Replace the following characters with `\x%x`:
|
||||
// Leading `.`
|
||||
// `-`, `\`, and anything not in this set: `:-_.\[0-9a-zA-Z]`
|
||||
// Replace '/' with '-'.
|
||||
func escape(unescaped string, isPath bool) string {
|
||||
e := []byte{}
|
||||
inSlashes := false
|
||||
start := true
|
||||
for i := 0; i < len(unescaped); i++ {
|
||||
c := unescaped[i]
|
||||
if isPath {
|
||||
if c == '/' {
|
||||
inSlashes = true
|
||||
continue
|
||||
} else if inSlashes {
|
||||
inSlashes = false
|
||||
if !start {
|
||||
e = append(e, '-')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c == '/' {
|
||||
e = append(e, '-')
|
||||
} else if start && c == '.' || strings.IndexByte(allowed, c) == -1 {
|
||||
e = append(e, []byte(fmt.Sprintf(`\x%x`, c))...)
|
||||
} else {
|
||||
e = append(e, c)
|
||||
}
|
||||
start = false
|
||||
}
|
||||
if isPath && len(e) == 0 {
|
||||
e = append(e, '-')
|
||||
}
|
||||
return string(e)
|
||||
}
|
||||
|
||||
// If isPath is true:
|
||||
// We always return a string beginning with '/'.
|
||||
//
|
||||
// We always:
|
||||
// Replace '-' with '/'.
|
||||
// Replace `\x%x` with the value represented in hex.
|
||||
func unescape(escaped string, isPath bool) string {
|
||||
u := []byte{}
|
||||
for i := 0; i < len(escaped); i++ {
|
||||
c := escaped[i]
|
||||
if c == '-' {
|
||||
c = '/'
|
||||
} else if c == '\\' && len(escaped)-i >= 4 && escaped[i+1] == 'x' {
|
||||
n, err := strconv.ParseInt(escaped[i+2:i+4], 16, 8)
|
||||
if err == nil {
|
||||
c = byte(n)
|
||||
i += 3
|
||||
}
|
||||
}
|
||||
u = append(u, c)
|
||||
}
|
||||
if isPath && (len(u) == 0 || u[0] != '/') {
|
||||
u = append([]byte("/"), u...)
|
||||
}
|
||||
return string(u)
|
||||
}
|
||||
|
||||
// UnitNameEscape escapes a string as `systemd-escape` would
|
||||
func UnitNameEscape(unescaped string) string {
|
||||
return escape(unescaped, false)
|
||||
}
|
||||
|
||||
// UnitNameUnescape unescapes a string as `systemd-escape --unescape` would
|
||||
func UnitNameUnescape(escaped string) string {
|
||||
return unescape(escaped, false)
|
||||
}
|
||||
|
||||
// UnitNamePathEscape escapes a string as `systemd-escape --path` would
|
||||
func UnitNamePathEscape(unescaped string) string {
|
||||
return escape(unescaped, true)
|
||||
}
|
||||
|
||||
// UnitNamePathUnescape unescapes a string as `systemd-escape --path --unescape` would
|
||||
func UnitNamePathUnescape(escaped string) string {
|
||||
return unescape(escaped, true)
|
||||
}
|
||||
54
vendor/github.com/coreos/go-systemd/unit/option.go
generated
vendored
Normal file
54
vendor/github.com/coreos/go-systemd/unit/option.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package unit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type UnitOption struct {
|
||||
Section string
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
func NewUnitOption(section, name, value string) *UnitOption {
|
||||
return &UnitOption{Section: section, Name: name, Value: value}
|
||||
}
|
||||
|
||||
func (uo *UnitOption) String() string {
|
||||
return fmt.Sprintf("{Section: %q, Name: %q, Value: %q}", uo.Section, uo.Name, uo.Value)
|
||||
}
|
||||
|
||||
func (uo *UnitOption) Match(other *UnitOption) bool {
|
||||
return uo.Section == other.Section &&
|
||||
uo.Name == other.Name &&
|
||||
uo.Value == other.Value
|
||||
}
|
||||
|
||||
func AllMatch(u1 []*UnitOption, u2 []*UnitOption) bool {
|
||||
length := len(u1)
|
||||
if length != len(u2) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
if !u1[i].Match(u2[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
75
vendor/github.com/coreos/go-systemd/unit/serialize.go
generated
vendored
Normal file
75
vendor/github.com/coreos/go-systemd/unit/serialize.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package unit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Serialize encodes all of the given UnitOption objects into a
|
||||
// unit file. When serialized the options are sorted in their
|
||||
// supplied order but grouped by section.
|
||||
func Serialize(opts []*UnitOption) io.Reader {
|
||||
var buf bytes.Buffer
|
||||
|
||||
if len(opts) == 0 {
|
||||
return &buf
|
||||
}
|
||||
|
||||
// Index of sections -> ordered options
|
||||
idx := map[string][]*UnitOption{}
|
||||
// Separately preserve order in which sections were seen
|
||||
sections := []string{}
|
||||
for _, opt := range opts {
|
||||
sec := opt.Section
|
||||
if _, ok := idx[sec]; !ok {
|
||||
sections = append(sections, sec)
|
||||
}
|
||||
idx[sec] = append(idx[sec], opt)
|
||||
}
|
||||
|
||||
for i, sect := range sections {
|
||||
writeSectionHeader(&buf, sect)
|
||||
writeNewline(&buf)
|
||||
|
||||
opts := idx[sect]
|
||||
for _, opt := range opts {
|
||||
writeOption(&buf, opt)
|
||||
writeNewline(&buf)
|
||||
}
|
||||
if i < len(sections)-1 {
|
||||
writeNewline(&buf)
|
||||
}
|
||||
}
|
||||
|
||||
return &buf
|
||||
}
|
||||
|
||||
func writeNewline(buf *bytes.Buffer) {
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
|
||||
func writeSectionHeader(buf *bytes.Buffer, section string) {
|
||||
buf.WriteRune('[')
|
||||
buf.WriteString(section)
|
||||
buf.WriteRune(']')
|
||||
}
|
||||
|
||||
func writeOption(buf *bytes.Buffer, opt *UnitOption) {
|
||||
buf.WriteString(opt.Name)
|
||||
buf.WriteRune('=')
|
||||
buf.WriteString(opt.Value)
|
||||
}
|
||||
37
vendor/github.com/coreos/ignition/config/config.go
generated
vendored
37
vendor/github.com/coreos/ignition/config/config.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/coreos/ignition/config/types"
|
||||
"github.com/coreos/ignition/config/v1"
|
||||
"github.com/coreos/ignition/config/v2_0"
|
||||
"github.com/coreos/ignition/config/validate"
|
||||
astjson "github.com/coreos/ignition/config/validate/astjson"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
@@ -40,14 +41,16 @@ var (
|
||||
// Parse parses the raw config into a types.Config struct and generates a report of any
|
||||
// errors, warnings, info, and deprecations it encountered
|
||||
func Parse(rawConfig []byte) (types.Config, report.Report, error) {
|
||||
switch majorVersion(rawConfig) {
|
||||
case 1:
|
||||
switch version(rawConfig) {
|
||||
case types.IgnitionVersion{Major: 1}:
|
||||
config, err := ParseFromV1(rawConfig)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError), err
|
||||
}
|
||||
|
||||
return config, report.ReportFromError(ErrDeprecated, report.EntryDeprecated), nil
|
||||
case types.IgnitionVersion{Major: 2, Minor: 0}:
|
||||
return ParseFromV2_0(rawConfig)
|
||||
default:
|
||||
return ParseFromLatest(rawConfig)
|
||||
}
|
||||
@@ -136,10 +139,19 @@ func ParseFromV1(rawConfig []byte) (types.Config, error) {
|
||||
return types.Config{}, err
|
||||
}
|
||||
|
||||
return TranslateFromV1(config)
|
||||
return TranslateFromV1(config), nil
|
||||
}
|
||||
|
||||
func majorVersion(rawConfig []byte) int64 {
|
||||
func ParseFromV2_0(rawConfig []byte) (types.Config, report.Report, error) {
|
||||
cfg, report, err := v2_0.Parse(rawConfig)
|
||||
if err != nil {
|
||||
return types.Config{}, report, err
|
||||
}
|
||||
|
||||
return TranslateFromV2_0(cfg), report, err
|
||||
}
|
||||
|
||||
func version(rawConfig []byte) types.IgnitionVersion {
|
||||
var composite struct {
|
||||
Version *int `json:"ignitionVersion"`
|
||||
Ignition struct {
|
||||
@@ -147,18 +159,15 @@ func majorVersion(rawConfig []byte) int64 {
|
||||
} `json:"ignition"`
|
||||
}
|
||||
|
||||
if json.Unmarshal(rawConfig, &composite) != nil {
|
||||
return 0
|
||||
if json.Unmarshal(rawConfig, &composite) == nil {
|
||||
if composite.Ignition.Version != nil {
|
||||
return *composite.Ignition.Version
|
||||
} else if composite.Version != nil {
|
||||
return types.IgnitionVersion{Major: int64(*composite.Version)}
|
||||
}
|
||||
}
|
||||
|
||||
var major int64
|
||||
if composite.Ignition.Version != nil {
|
||||
major = composite.Ignition.Version.Major
|
||||
} else if composite.Version != nil {
|
||||
major = int64(*composite.Version)
|
||||
}
|
||||
|
||||
return major
|
||||
return types.IgnitionVersion{}
|
||||
}
|
||||
|
||||
func isEmpty(userdata []byte) bool {
|
||||
|
||||
192
vendor/github.com/coreos/ignition/config/translate.go
generated
vendored
192
vendor/github.com/coreos/ignition/config/translate.go
generated
vendored
@@ -19,14 +19,15 @@ import (
|
||||
|
||||
"github.com/coreos/ignition/config/types"
|
||||
v1 "github.com/coreos/ignition/config/v1/types"
|
||||
v2_0 "github.com/coreos/ignition/config/v2_0/types"
|
||||
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
func TranslateFromV1(old v1.Config) (types.Config, error) {
|
||||
func TranslateFromV1(old v1.Config) types.Config {
|
||||
config := types.Config{
|
||||
Ignition: types.Ignition{
|
||||
Version: types.IgnitionVersion{Major: 2},
|
||||
Version: types.IgnitionVersion(v2_0.MaxVersion),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -83,17 +84,19 @@ func TranslateFromV1(old v1.Config) (types.Config, error) {
|
||||
|
||||
for _, oldFile := range oldFilesystem.Files {
|
||||
file := types.File{
|
||||
Filesystem: filesystem.Name,
|
||||
Path: types.Path(oldFile.Path),
|
||||
Node: types.Node{
|
||||
Filesystem: filesystem.Name,
|
||||
Path: types.Path(oldFile.Path),
|
||||
Mode: types.NodeMode(oldFile.Mode),
|
||||
User: types.NodeUser{Id: oldFile.Uid},
|
||||
Group: types.NodeGroup{Id: oldFile.Gid},
|
||||
},
|
||||
Contents: types.FileContents{
|
||||
Source: types.Url{
|
||||
Scheme: "data",
|
||||
Opaque: "," + dataurl.EscapeString(oldFile.Contents),
|
||||
},
|
||||
},
|
||||
Mode: types.FileMode(oldFile.Mode),
|
||||
User: types.FileUser{Id: oldFile.Uid},
|
||||
Group: types.FileGroup{Id: oldFile.Gid},
|
||||
}
|
||||
|
||||
config.Storage.Files = append(config.Storage.Files, file)
|
||||
@@ -159,5 +162,178 @@ func TranslateFromV1(old v1.Config) (types.Config, error) {
|
||||
})
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return config
|
||||
}
|
||||
|
||||
func TranslateFromV2_0(old v2_0.Config) types.Config {
|
||||
translateVerification := func(old v2_0.Verification) types.Verification {
|
||||
var ver types.Verification
|
||||
if old.Hash != nil {
|
||||
h := types.Hash(*old.Hash)
|
||||
ver.Hash = &h
|
||||
}
|
||||
return ver
|
||||
}
|
||||
translateConfigReference := func(old v2_0.ConfigReference) types.ConfigReference {
|
||||
return types.ConfigReference{
|
||||
Source: types.Url(old.Source),
|
||||
Verification: translateVerification(old.Verification),
|
||||
}
|
||||
}
|
||||
|
||||
config := types.Config{
|
||||
Ignition: types.Ignition{
|
||||
Version: types.IgnitionVersion(types.MaxVersion),
|
||||
},
|
||||
}
|
||||
|
||||
if old.Ignition.Config.Replace != nil {
|
||||
ref := translateConfigReference(*old.Ignition.Config.Replace)
|
||||
config.Ignition.Config.Replace = &ref
|
||||
}
|
||||
|
||||
for _, oldAppend := range old.Ignition.Config.Append {
|
||||
config.Ignition.Config.Append =
|
||||
append(config.Ignition.Config.Append, translateConfigReference(oldAppend))
|
||||
}
|
||||
|
||||
for _, oldDisk := range old.Storage.Disks {
|
||||
disk := types.Disk{
|
||||
Device: types.Path(oldDisk.Device),
|
||||
WipeTable: oldDisk.WipeTable,
|
||||
}
|
||||
|
||||
for _, oldPartition := range oldDisk.Partitions {
|
||||
disk.Partitions = append(disk.Partitions, types.Partition{
|
||||
Label: types.PartitionLabel(oldPartition.Label),
|
||||
Number: oldPartition.Number,
|
||||
Size: types.PartitionDimension(oldPartition.Size),
|
||||
Start: types.PartitionDimension(oldPartition.Start),
|
||||
TypeGUID: types.PartitionTypeGUID(oldPartition.TypeGUID),
|
||||
})
|
||||
}
|
||||
|
||||
config.Storage.Disks = append(config.Storage.Disks, disk)
|
||||
}
|
||||
|
||||
for _, oldArray := range old.Storage.Arrays {
|
||||
array := types.Raid{
|
||||
Name: oldArray.Name,
|
||||
Level: oldArray.Level,
|
||||
Spares: oldArray.Spares,
|
||||
}
|
||||
|
||||
for _, oldDevice := range oldArray.Devices {
|
||||
array.Devices = append(array.Devices, types.Path(oldDevice))
|
||||
}
|
||||
|
||||
config.Storage.Arrays = append(config.Storage.Arrays, array)
|
||||
}
|
||||
|
||||
for _, oldFilesystem := range old.Storage.Filesystems {
|
||||
filesystem := types.Filesystem{
|
||||
Name: oldFilesystem.Name,
|
||||
}
|
||||
|
||||
if oldFilesystem.Mount != nil {
|
||||
filesystem.Mount = &types.FilesystemMount{
|
||||
Device: types.Path(oldFilesystem.Mount.Device),
|
||||
Format: types.FilesystemFormat(oldFilesystem.Mount.Format),
|
||||
}
|
||||
|
||||
if oldFilesystem.Mount.Create != nil {
|
||||
filesystem.Mount.Create = &types.FilesystemCreate{
|
||||
Force: oldFilesystem.Mount.Create.Force,
|
||||
Options: types.MkfsOptions(oldFilesystem.Mount.Create.Options),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if oldFilesystem.Path != nil {
|
||||
path := types.Path(*oldFilesystem.Path)
|
||||
filesystem.Path = &path
|
||||
}
|
||||
|
||||
config.Storage.Filesystems = append(config.Storage.Filesystems, filesystem)
|
||||
}
|
||||
|
||||
for _, oldFile := range old.Storage.Files {
|
||||
file := types.File{
|
||||
Node: types.Node{
|
||||
Filesystem: oldFile.Filesystem,
|
||||
Path: types.Path(oldFile.Path),
|
||||
Mode: types.NodeMode(oldFile.Mode),
|
||||
User: types.NodeUser{Id: oldFile.User.Id},
|
||||
Group: types.NodeGroup{Id: oldFile.Group.Id},
|
||||
},
|
||||
Contents: types.FileContents{
|
||||
Compression: types.Compression(oldFile.Contents.Compression),
|
||||
Source: types.Url(oldFile.Contents.Source),
|
||||
Verification: translateVerification(oldFile.Contents.Verification),
|
||||
},
|
||||
}
|
||||
|
||||
config.Storage.Files = append(config.Storage.Files, file)
|
||||
}
|
||||
|
||||
for _, oldUnit := range old.Systemd.Units {
|
||||
unit := types.SystemdUnit{
|
||||
Name: types.SystemdUnitName(oldUnit.Name),
|
||||
Enable: oldUnit.Enable,
|
||||
Mask: oldUnit.Mask,
|
||||
Contents: oldUnit.Contents,
|
||||
}
|
||||
|
||||
for _, oldDropIn := range oldUnit.DropIns {
|
||||
unit.DropIns = append(unit.DropIns, types.SystemdUnitDropIn{
|
||||
Name: types.SystemdUnitDropInName(oldDropIn.Name),
|
||||
Contents: oldDropIn.Contents,
|
||||
})
|
||||
}
|
||||
|
||||
config.Systemd.Units = append(config.Systemd.Units, unit)
|
||||
}
|
||||
|
||||
for _, oldUnit := range old.Networkd.Units {
|
||||
config.Networkd.Units = append(config.Networkd.Units, types.NetworkdUnit{
|
||||
Name: types.NetworkdUnitName(oldUnit.Name),
|
||||
Contents: oldUnit.Contents,
|
||||
})
|
||||
}
|
||||
|
||||
for _, oldUser := range old.Passwd.Users {
|
||||
user := types.User{
|
||||
Name: oldUser.Name,
|
||||
PasswordHash: oldUser.PasswordHash,
|
||||
SSHAuthorizedKeys: oldUser.SSHAuthorizedKeys,
|
||||
}
|
||||
|
||||
if oldUser.Create != nil {
|
||||
user.Create = &types.UserCreate{
|
||||
Uid: oldUser.Create.Uid,
|
||||
GECOS: oldUser.Create.GECOS,
|
||||
Homedir: oldUser.Create.Homedir,
|
||||
NoCreateHome: oldUser.Create.NoCreateHome,
|
||||
PrimaryGroup: oldUser.Create.PrimaryGroup,
|
||||
Groups: oldUser.Create.Groups,
|
||||
NoUserGroup: oldUser.Create.NoUserGroup,
|
||||
System: oldUser.Create.System,
|
||||
NoLogInit: oldUser.Create.NoLogInit,
|
||||
Shell: oldUser.Create.Shell,
|
||||
}
|
||||
}
|
||||
|
||||
config.Passwd.Users = append(config.Passwd.Users, user)
|
||||
}
|
||||
|
||||
for _, oldGroup := range old.Passwd.Groups {
|
||||
config.Passwd.Groups = append(config.Passwd.Groups, types.Group{
|
||||
Name: oldGroup.Name,
|
||||
Gid: oldGroup.Gid,
|
||||
PasswordHash: oldGroup.PasswordHash,
|
||||
System: oldGroup.System,
|
||||
})
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
5
vendor/github.com/coreos/ignition/config/types/config.go
generated
vendored
5
vendor/github.com/coreos/ignition/config/types/config.go
generated
vendored
@@ -24,8 +24,9 @@ import (
|
||||
|
||||
var (
|
||||
MaxVersion = semver.Version{
|
||||
Major: 2,
|
||||
Minor: 0,
|
||||
Major: 2,
|
||||
Minor: 1,
|
||||
PreRelease: "experimental",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -14,19 +14,16 @@
|
||||
|
||||
package types
|
||||
|
||||
type Filesystem struct {
|
||||
Name string `yaml:"name"`
|
||||
Mount *Mount `yaml:"mount"`
|
||||
Path string `yaml:"path"`
|
||||
}
|
||||
import (
|
||||
"path"
|
||||
)
|
||||
|
||||
type Mount struct {
|
||||
Device string `yaml:"device"`
|
||||
Format string `yaml:"format"`
|
||||
Create *Create `yaml:"create"`
|
||||
}
|
||||
type Directory Node
|
||||
|
||||
type Create struct {
|
||||
Force bool `yaml:"force"`
|
||||
Options []string `yaml:"options"`
|
||||
func (d *Directory) Depth() int {
|
||||
count := 0
|
||||
for p := path.Clean(string(d.Path)); p != "/"; count++ {
|
||||
p = path.Dir(p)
|
||||
}
|
||||
return count
|
||||
}
|
||||
45
vendor/github.com/coreos/ignition/config/types/file.go
generated
vendored
45
vendor/github.com/coreos/ignition/config/types/file.go
generated
vendored
@@ -14,40 +14,10 @@
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileIllegalMode = errors.New("illegal file mode")
|
||||
ErrNoFilesystem = errors.New("no filesystem specified")
|
||||
)
|
||||
|
||||
// File represents regular files
|
||||
type File struct {
|
||||
Filesystem string `json:"filesystem,omitempty"`
|
||||
Path Path `json:"path,omitempty"`
|
||||
Contents FileContents `json:"contents,omitempty"`
|
||||
Mode FileMode `json:"mode,omitempty"`
|
||||
User FileUser `json:"user,omitempty"`
|
||||
Group FileGroup `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
func (f File) Validate() report.Report {
|
||||
if f.Filesystem == "" {
|
||||
return report.ReportFromError(ErrNoFilesystem, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type FileUser struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type FileGroup struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Node
|
||||
Contents FileContents `json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
type FileContents struct {
|
||||
@@ -55,12 +25,3 @@ type FileContents struct {
|
||||
Source Url `json:"source,omitempty"`
|
||||
Verification Verification `json:"verification,omitempty"`
|
||||
}
|
||||
|
||||
type FileMode os.FileMode
|
||||
|
||||
func (m FileMode) Validate() report.Report {
|
||||
if (m &^ 07777) != 0 {
|
||||
return report.ReportFromError(ErrFileIllegalMode, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
5
vendor/github.com/coreos/ignition/config/types/ignition.go
generated
vendored
5
vendor/github.com/coreos/ignition/config/types/ignition.go
generated
vendored
@@ -29,8 +29,9 @@ var (
|
||||
)
|
||||
|
||||
type Ignition struct {
|
||||
Version IgnitionVersion `json:"version,omitempty" merge:"old"`
|
||||
Config IgnitionConfig `json:"config,omitempty" merge:"new"`
|
||||
Version IgnitionVersion `json:"version,omitempty" merge:"old"`
|
||||
Config IgnitionConfig `json:"config,omitempty" merge:"new"`
|
||||
Timeouts Timeouts `json:"timeouts,omitempty" merge:"new"`
|
||||
}
|
||||
|
||||
type IgnitionConfig struct {
|
||||
|
||||
60
vendor/github.com/coreos/ignition/config/types/node.go
generated
vendored
Normal file
60
vendor/github.com/coreos/ignition/config/types/node.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoFilesystem = errors.New("no filesystem specified")
|
||||
ErrFileIllegalMode = errors.New("illegal file mode")
|
||||
)
|
||||
|
||||
// Node represents all common info for files (special types, e.g. directories, included).
|
||||
type Node struct {
|
||||
Filesystem string `json:"filesystem,omitempty"`
|
||||
Path Path `json:"path,omitempty"`
|
||||
Mode NodeMode `json:"mode,omitempty"`
|
||||
User NodeUser `json:"user,omitempty"`
|
||||
Group NodeGroup `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type NodeUser struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type NodeGroup struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func (n Node) Validate() report.Report {
|
||||
if n.Filesystem == "" {
|
||||
return report.ReportFromError(ErrNoFilesystem, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type NodeMode os.FileMode
|
||||
|
||||
func (m NodeMode) Validate() report.Report {
|
||||
if (m &^ 07777) != 0 {
|
||||
return report.ReportFromError(ErrFileIllegalMode, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
4
vendor/github.com/coreos/ignition/config/types/path.go
generated
vendored
4
vendor/github.com/coreos/ignition/config/types/path.go
generated
vendored
@@ -16,7 +16,7 @@ package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ func (p Path) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (p Path) Validate() report.Report {
|
||||
if !filepath.IsAbs(string(p)) {
|
||||
if !path.IsAbs(string(p)) {
|
||||
return report.ReportFromError(ErrPathRelative, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
|
||||
1
vendor/github.com/coreos/ignition/config/types/storage.go
generated
vendored
1
vendor/github.com/coreos/ignition/config/types/storage.go
generated
vendored
@@ -19,4 +19,5 @@ type Storage struct {
|
||||
Arrays []Raid `json:"raid,omitempty"`
|
||||
Filesystems []Filesystem `json:"filesystems,omitempty"`
|
||||
Files []File `json:"files,omitempty"`
|
||||
Directories []Directory `json:"directories,omitempty"`
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
package types
|
||||
|
||||
type Raid struct {
|
||||
Name string `yaml:"name"`
|
||||
Level string `yaml:"level"`
|
||||
Devices []string `yaml:"devices"`
|
||||
Spares int `yaml:"spares"`
|
||||
type Timeouts struct {
|
||||
HttpResponseHeaders *int `json:"httpResponseHeaders,omitempty"`
|
||||
HttpTotal *int `json:"httpTotal,omitempty"`
|
||||
}
|
||||
46
vendor/github.com/coreos/ignition/config/types/unit.go
generated
vendored
46
vendor/github.com/coreos/ignition/config/types/unit.go
generated
vendored
@@ -15,8 +15,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/coreos/go-systemd/unit"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
@@ -29,15 +33,31 @@ type SystemdUnit struct {
|
||||
DropIns []SystemdUnitDropIn `json:"dropins,omitempty"`
|
||||
}
|
||||
|
||||
func (u SystemdUnit) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type SystemdUnitDropIn struct {
|
||||
Name SystemdUnitDropInName `json:"name,omitempty"`
|
||||
Contents string `json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
func (u SystemdUnitDropIn) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type SystemdUnitName string
|
||||
|
||||
func (n SystemdUnitName) Validate() report.Report {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope":
|
||||
return report.Report{}
|
||||
default:
|
||||
@@ -48,7 +68,7 @@ func (n SystemdUnitName) Validate() report.Report {
|
||||
type SystemdUnitDropInName string
|
||||
|
||||
func (n SystemdUnitDropInName) Validate() report.Report {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".conf":
|
||||
return report.Report{}
|
||||
default:
|
||||
@@ -61,13 +81,31 @@ type NetworkdUnit struct {
|
||||
Contents string `json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
func (u NetworkdUnit) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type NetworkdUnitName string
|
||||
|
||||
func (n NetworkdUnitName) Validate() report.Report {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".link", ".netdev", ".network":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(errors.New("invalid networkd unit extension"), report.EntryError)
|
||||
}
|
||||
}
|
||||
|
||||
func validateUnitContent(content string) error {
|
||||
c := bytes.NewBufferString(content)
|
||||
_, err := unit.Deserialize(c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid unit content: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
12
vendor/github.com/coreos/ignition/config/types/url.go
generated
vendored
12
vendor/github.com/coreos/ignition/config/types/url.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"net/url"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -58,9 +59,14 @@ func (u Url) Validate() report.Report {
|
||||
return report.Report{}
|
||||
}
|
||||
switch url.URL(u).Scheme {
|
||||
case "http", "https", "oem", "data":
|
||||
case "http", "https", "oem":
|
||||
return report.Report{}
|
||||
case "data":
|
||||
if _, err := dataurl.DecodeString(u.String()); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(ErrInvalidScheme, report.EntryError)
|
||||
}
|
||||
|
||||
return report.ReportFromError(ErrInvalidScheme, report.EntryError)
|
||||
}
|
||||
|
||||
11
vendor/github.com/coreos/ignition/config/v1/types/path.go
generated
vendored
11
vendor/github.com/coreos/ignition/config/v1/types/path.go
generated
vendored
@@ -17,7 +17,7 @@ package types
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"path"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -25,19 +25,18 @@ var (
|
||||
)
|
||||
|
||||
type Path string
|
||||
type path Path
|
||||
|
||||
func (d *Path) UnmarshalJSON(data []byte) error {
|
||||
td := path(*d)
|
||||
if err := json.Unmarshal(data, &td); err != nil {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
*d = Path(td)
|
||||
*d = Path(s)
|
||||
return d.AssertValid()
|
||||
}
|
||||
|
||||
func (d Path) AssertValid() error {
|
||||
if !filepath.IsAbs(string(d)) {
|
||||
if !path.IsAbs(string(d)) {
|
||||
return ErrPathRelative
|
||||
}
|
||||
return nil
|
||||
|
||||
8
vendor/github.com/coreos/ignition/config/v1/types/unit.go
generated
vendored
8
vendor/github.com/coreos/ignition/config/v1/types/unit.go
generated
vendored
@@ -17,7 +17,7 @@ package types
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"path"
|
||||
)
|
||||
|
||||
type SystemdUnit struct {
|
||||
@@ -46,7 +46,7 @@ func (n *SystemdUnitName) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
func (n SystemdUnitName) AssertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope":
|
||||
return nil
|
||||
default:
|
||||
@@ -67,7 +67,7 @@ func (n *SystemdUnitDropInName) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
func (n SystemdUnitDropInName) AssertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".conf":
|
||||
return nil
|
||||
default:
|
||||
@@ -93,7 +93,7 @@ func (n *NetworkdUnitName) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
func (n NetworkdUnitName) AssertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".link", ".netdev", ".network":
|
||||
return nil
|
||||
default:
|
||||
|
||||
73
vendor/github.com/coreos/ignition/config/v2_0/append.go
generated
vendored
Normal file
73
vendor/github.com/coreos/ignition/config/v2_0/append.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v2_0
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/coreos/ignition/config/v2_0/types"
|
||||
)
|
||||
|
||||
// Append appends newConfig to oldConfig and returns the result. Appending one
|
||||
// config to another is accomplished by iterating over every field in the
|
||||
// config structure, appending slices, recursively appending structs, and
|
||||
// overwriting old values with new values for all other types.
|
||||
func Append(oldConfig, newConfig types.Config) types.Config {
|
||||
vOld := reflect.ValueOf(oldConfig)
|
||||
vNew := reflect.ValueOf(newConfig)
|
||||
|
||||
vResult := appendStruct(vOld, vNew)
|
||||
|
||||
return vResult.Interface().(types.Config)
|
||||
}
|
||||
|
||||
// appendStruct is an internal helper function to AppendConfig. Given two values
|
||||
// of structures (assumed to be the same type), recursively iterate over every
|
||||
// field in the struct, appending slices, recursively appending structs, and
|
||||
// overwriting old values with the new for all other types. Individual fields
|
||||
// are able to override their merge strategy using the "merge" tag. Accepted
|
||||
// values are "new" or "old": "new" uses the new value, "old" uses the old
|
||||
// value. These are currently only used for "ignition.config" and
|
||||
// "ignition.version".
|
||||
func appendStruct(vOld, vNew reflect.Value) reflect.Value {
|
||||
tOld := vOld.Type()
|
||||
vRes := reflect.New(tOld)
|
||||
|
||||
for i := 0; i < tOld.NumField(); i++ {
|
||||
vfOld := vOld.Field(i)
|
||||
vfNew := vNew.Field(i)
|
||||
vfRes := vRes.Elem().Field(i)
|
||||
|
||||
switch tOld.Field(i).Tag.Get("merge") {
|
||||
case "old":
|
||||
vfRes.Set(vfOld)
|
||||
continue
|
||||
case "new":
|
||||
vfRes.Set(vfNew)
|
||||
continue
|
||||
}
|
||||
|
||||
switch vfOld.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
vfRes.Set(appendStruct(vfOld, vfNew))
|
||||
case reflect.Slice:
|
||||
vfRes.Set(reflect.AppendSlice(vfOld, vfNew))
|
||||
default:
|
||||
vfRes.Set(vfNew)
|
||||
}
|
||||
}
|
||||
|
||||
return vRes.Elem()
|
||||
}
|
||||
53
vendor/github.com/coreos/ignition/config/v2_0/cloudinit.go
generated
vendored
Normal file
53
vendor/github.com/coreos/ignition/config/v2_0/cloudinit.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// These functions are copied from github.com/coreos/coreos-cloudinit/config.
|
||||
|
||||
package v2_0
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func isCloudConfig(userdata []byte) bool {
|
||||
header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
|
||||
|
||||
// Trim trailing whitespaces
|
||||
header = strings.TrimRightFunc(header, unicode.IsSpace)
|
||||
|
||||
return (header == "#cloud-config")
|
||||
}
|
||||
|
||||
func isScript(userdata []byte) bool {
|
||||
header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
|
||||
return strings.HasPrefix(header, "#!")
|
||||
}
|
||||
|
||||
func decompressIfGzipped(data []byte) []byte {
|
||||
if reader, err := gzip.NewReader(bytes.NewReader(data)); err == nil {
|
||||
uncompressedData, err := ioutil.ReadAll(reader)
|
||||
reader.Close()
|
||||
if err == nil {
|
||||
return uncompressedData
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
120
vendor/github.com/coreos/ignition/config/v2_0/config.go
generated
vendored
Normal file
120
vendor/github.com/coreos/ignition/config/v2_0/config.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v2_0
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/coreos/ignition/config/v2_0/types"
|
||||
"github.com/coreos/ignition/config/validate"
|
||||
astjson "github.com/coreos/ignition/config/validate/astjson"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
|
||||
json "github.com/ajeddeloh/go-json"
|
||||
"go4.org/errorutil"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCloudConfig = errors.New("not a config (found coreos-cloudconfig)")
|
||||
ErrEmpty = errors.New("not a config (empty)")
|
||||
ErrScript = errors.New("not a config (found coreos-cloudinit script)")
|
||||
ErrDeprecated = errors.New("config format deprecated")
|
||||
ErrInvalid = errors.New("config is not valid")
|
||||
)
|
||||
|
||||
// Parse parses the raw config into a types.Config struct and generates a report of any
|
||||
// errors, warnings, info, and deprecations it encountered
|
||||
func Parse(rawConfig []byte) (types.Config, report.Report, error) {
|
||||
if isEmpty(rawConfig) {
|
||||
return types.Config{}, report.Report{}, ErrEmpty
|
||||
} else if isCloudConfig(rawConfig) {
|
||||
return types.Config{}, report.Report{}, ErrCloudConfig
|
||||
} else if isScript(rawConfig) {
|
||||
return types.Config{}, report.Report{}, ErrScript
|
||||
}
|
||||
|
||||
var err error
|
||||
var config types.Config
|
||||
|
||||
// These errors are fatal and the config should not be further validated
|
||||
if err = json.Unmarshal(rawConfig, &config); err == nil {
|
||||
versionReport := config.Ignition.Version.Validate()
|
||||
if versionReport.IsFatal() {
|
||||
return types.Config{}, versionReport, ErrInvalid
|
||||
}
|
||||
}
|
||||
|
||||
// Handle json syntax and type errors first, since they are fatal but have offset info
|
||||
if serr, ok := err.(*json.SyntaxError); ok {
|
||||
line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(rawConfig), serr.Offset)
|
||||
return types.Config{},
|
||||
report.Report{
|
||||
Entries: []report.Entry{{
|
||||
Kind: report.EntryError,
|
||||
Message: serr.Error(),
|
||||
Line: line,
|
||||
Column: col,
|
||||
Highlight: highlight,
|
||||
}},
|
||||
},
|
||||
ErrInvalid
|
||||
}
|
||||
|
||||
if terr, ok := err.(*json.UnmarshalTypeError); ok {
|
||||
line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(rawConfig), terr.Offset)
|
||||
return types.Config{},
|
||||
report.Report{
|
||||
Entries: []report.Entry{{
|
||||
Kind: report.EntryError,
|
||||
Message: terr.Error(),
|
||||
Line: line,
|
||||
Column: col,
|
||||
Highlight: highlight,
|
||||
}},
|
||||
},
|
||||
ErrInvalid
|
||||
}
|
||||
|
||||
// Handle other fatal errors (i.e. invalid version)
|
||||
if err != nil {
|
||||
return types.Config{}, report.ReportFromError(err, report.EntryError), err
|
||||
}
|
||||
|
||||
// Unmarshal again to a json.Node to get offset information for building a report
|
||||
var ast json.Node
|
||||
var r report.Report
|
||||
configValue := reflect.ValueOf(config)
|
||||
if err := json.Unmarshal(rawConfig, &ast); err != nil {
|
||||
r.Add(report.Entry{
|
||||
Kind: report.EntryWarning,
|
||||
Message: "Ignition could not unmarshal your config for reporting line numbers. This should never happen. Please file a bug.",
|
||||
})
|
||||
r.Merge(validate.ValidateWithoutSource(configValue))
|
||||
} else {
|
||||
r.Merge(validate.Validate(configValue, astjson.FromJsonRoot(ast), bytes.NewReader(rawConfig)))
|
||||
}
|
||||
|
||||
if r.IsFatal() {
|
||||
return types.Config{}, r, ErrInvalid
|
||||
}
|
||||
|
||||
return config, r, nil
|
||||
}
|
||||
|
||||
func isEmpty(userdata []byte) bool {
|
||||
return len(userdata) == 0
|
||||
}
|
||||
36
vendor/github.com/coreos/ignition/config/v2_0/types/compression.go
generated
vendored
Normal file
36
vendor/github.com/coreos/ignition/config/v2_0/types/compression.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCompressionInvalid = errors.New("invalid compression method")
|
||||
)
|
||||
|
||||
type Compression string
|
||||
|
||||
func (c Compression) Validate() report.Report {
|
||||
switch c {
|
||||
case "", "gzip":
|
||||
default:
|
||||
return report.ReportFromError(ErrCompressionInvalid, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
87
vendor/github.com/coreos/ignition/config/v2_0/types/config.go
generated
vendored
Normal file
87
vendor/github.com/coreos/ignition/config/v2_0/types/config.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
MaxVersion = semver.Version{
|
||||
Major: 2,
|
||||
Minor: 0,
|
||||
}
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Ignition Ignition `json:"ignition"`
|
||||
Storage Storage `json:"storage,omitempty"`
|
||||
Systemd Systemd `json:"systemd,omitempty"`
|
||||
Networkd Networkd `json:"networkd,omitempty"`
|
||||
Passwd Passwd `json:"passwd,omitempty"`
|
||||
}
|
||||
|
||||
func (c Config) Validate() report.Report {
|
||||
r := report.Report{}
|
||||
rules := []rule{
|
||||
checkFilesFilesystems,
|
||||
checkDuplicateFilesystems,
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
rule(c, &r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type rule func(cfg Config, report *report.Report)
|
||||
|
||||
func checkFilesFilesystems(cfg Config, r *report.Report) {
|
||||
filesystems := map[string]struct{}{"root": {}}
|
||||
for _, filesystem := range cfg.Storage.Filesystems {
|
||||
filesystems[filesystem.Name] = struct{}{}
|
||||
}
|
||||
for _, file := range cfg.Storage.Files {
|
||||
if file.Filesystem == "" {
|
||||
// Filesystem was not specified. This is an error, but its handled in types.File's Validate, not here
|
||||
continue
|
||||
}
|
||||
_, ok := filesystems[file.Filesystem]
|
||||
if !ok {
|
||||
r.Add(report.Entry{
|
||||
Kind: report.EntryWarning,
|
||||
Message: fmt.Sprintf("File %q references nonexistent filesystem %q. (This is ok if it is defined in a referenced config)",
|
||||
file.Path, file.Filesystem),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkDuplicateFilesystems(cfg Config, r *report.Report) {
|
||||
filesystems := map[string]struct{}{"root": {}}
|
||||
for _, filesystem := range cfg.Storage.Filesystems {
|
||||
if _, ok := filesystems[filesystem.Name]; ok {
|
||||
r.Add(report.Entry{
|
||||
Kind: report.EntryWarning,
|
||||
Message: fmt.Sprintf("Filesystem %q shadows exising filesystem definition", filesystem.Name),
|
||||
})
|
||||
}
|
||||
filesystems[filesystem.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
124
vendor/github.com/coreos/ignition/config/v2_0/types/disk.go
generated
vendored
Normal file
124
vendor/github.com/coreos/ignition/config/v2_0/types/disk.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Disk struct {
|
||||
Device Path `json:"device,omitempty"`
|
||||
WipeTable bool `json:"wipeTable,omitempty"`
|
||||
Partitions []Partition `json:"partitions,omitempty"`
|
||||
}
|
||||
|
||||
func (n Disk) Validate() report.Report {
|
||||
r := report.Report{}
|
||||
if len(n.Device) == 0 {
|
||||
r.Add(report.Entry{
|
||||
Message: "disk device is required",
|
||||
Kind: report.EntryError,
|
||||
})
|
||||
}
|
||||
if n.partitionNumbersCollide() {
|
||||
r.Add(report.Entry{
|
||||
Message: fmt.Sprintf("disk %q: partition numbers collide", n.Device),
|
||||
Kind: report.EntryError,
|
||||
})
|
||||
}
|
||||
if n.partitionsOverlap() {
|
||||
r.Add(report.Entry{
|
||||
Message: fmt.Sprintf("disk %q: partitions overlap", n.Device),
|
||||
Kind: report.EntryError,
|
||||
})
|
||||
}
|
||||
if n.partitionsMisaligned() {
|
||||
r.Add(report.Entry{
|
||||
Message: fmt.Sprintf("disk %q: partitions misaligned", n.Device),
|
||||
Kind: report.EntryError,
|
||||
})
|
||||
}
|
||||
// Disks which have no errors at this point will likely succeed in sgdisk
|
||||
return r
|
||||
}
|
||||
|
||||
// partitionNumbersCollide returns true if partition numbers in n.Partitions are not unique.
|
||||
func (n Disk) partitionNumbersCollide() bool {
|
||||
m := map[int][]Partition{}
|
||||
for _, p := range n.Partitions {
|
||||
m[p.Number] = append(m[p.Number], p)
|
||||
}
|
||||
for _, n := range m {
|
||||
if len(n) > 1 {
|
||||
// TODO(vc): return information describing the collision for logging
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// end returns the last sector of a partition.
|
||||
func (p Partition) end() PartitionDimension {
|
||||
if p.Size == 0 {
|
||||
// a size of 0 means "fill available", just return the start as the end for those.
|
||||
return p.Start
|
||||
}
|
||||
return p.Start + p.Size - 1
|
||||
}
|
||||
|
||||
// partitionsOverlap returns true if any explicitly dimensioned partitions overlap
|
||||
func (n Disk) partitionsOverlap() bool {
|
||||
for _, p := range n.Partitions {
|
||||
// Starts of 0 are placed by sgdisk into the "largest available block" at that time.
|
||||
// We aren't going to check those for overlap since we don't have the disk geometry.
|
||||
if p.Start == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, o := range n.Partitions {
|
||||
if p == o || o.Start == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// is p.Start within o?
|
||||
if p.Start >= o.Start && p.Start <= o.end() {
|
||||
return true
|
||||
}
|
||||
|
||||
// is p.end() within o?
|
||||
if p.end() >= o.Start && p.end() <= o.end() {
|
||||
return true
|
||||
}
|
||||
|
||||
// do p.Start and p.end() straddle o?
|
||||
if p.Start < o.Start && p.end() > o.end() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// partitionsMisaligned returns true if any of the partitions don't start on a 2048-sector (1MiB) boundary.
|
||||
func (n Disk) partitionsMisaligned() bool {
|
||||
for _, p := range n.Partitions {
|
||||
if (p.Start & (2048 - 1)) != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
66
vendor/github.com/coreos/ignition/config/v2_0/types/file.go
generated
vendored
Normal file
66
vendor/github.com/coreos/ignition/config/v2_0/types/file.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileIllegalMode = errors.New("illegal file mode")
|
||||
ErrNoFilesystem = errors.New("no filesystem specified")
|
||||
)
|
||||
|
||||
type File struct {
|
||||
Filesystem string `json:"filesystem,omitempty"`
|
||||
Path Path `json:"path,omitempty"`
|
||||
Contents FileContents `json:"contents,omitempty"`
|
||||
Mode FileMode `json:"mode,omitempty"`
|
||||
User FileUser `json:"user,omitempty"`
|
||||
Group FileGroup `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
func (f File) Validate() report.Report {
|
||||
if f.Filesystem == "" {
|
||||
return report.ReportFromError(ErrNoFilesystem, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type FileUser struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type FileGroup struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type FileContents struct {
|
||||
Compression Compression `json:"compression,omitempty"`
|
||||
Source Url `json:"source,omitempty"`
|
||||
Verification Verification `json:"verification,omitempty"`
|
||||
}
|
||||
|
||||
type FileMode os.FileMode
|
||||
|
||||
func (m FileMode) Validate() report.Report {
|
||||
if (m &^ 07777) != 0 {
|
||||
return report.ReportFromError(ErrFileIllegalMode, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
67
vendor/github.com/coreos/ignition/config/v2_0/types/filesystem.go
generated
vendored
Normal file
67
vendor/github.com/coreos/ignition/config/v2_0/types/filesystem.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFilesystemInvalidFormat = errors.New("invalid filesystem format")
|
||||
ErrFilesystemNoMountPath = errors.New("filesystem is missing mount or path")
|
||||
ErrFilesystemMountAndPath = errors.New("filesystem has both mount and path defined")
|
||||
)
|
||||
|
||||
type Filesystem struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Mount *FilesystemMount `json:"mount,omitempty"`
|
||||
Path *Path `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
type FilesystemMount struct {
|
||||
Device Path `json:"device,omitempty"`
|
||||
Format FilesystemFormat `json:"format,omitempty"`
|
||||
Create *FilesystemCreate `json:"create,omitempty"`
|
||||
}
|
||||
|
||||
type FilesystemCreate struct {
|
||||
Force bool `json:"force,omitempty"`
|
||||
Options MkfsOptions `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (f Filesystem) Validate() report.Report {
|
||||
if f.Mount == nil && f.Path == nil {
|
||||
return report.ReportFromError(ErrFilesystemNoMountPath, report.EntryError)
|
||||
}
|
||||
if f.Mount != nil && f.Path != nil {
|
||||
return report.ReportFromError(ErrFilesystemMountAndPath, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type FilesystemFormat string
|
||||
|
||||
func (f FilesystemFormat) Validate() report.Report {
|
||||
switch f {
|
||||
case "ext4", "btrfs", "xfs":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(ErrFilesystemInvalidFormat, report.EntryError)
|
||||
}
|
||||
}
|
||||
|
||||
type MkfsOptions []string
|
||||
@@ -14,16 +14,9 @@
|
||||
|
||||
package types
|
||||
|
||||
type Disk struct {
|
||||
Device string `yaml:"device"`
|
||||
WipeTable bool `yaml:"wipe_table"`
|
||||
Partitions []Partition `yaml:"partitions"`
|
||||
}
|
||||
|
||||
type Partition struct {
|
||||
Label string `yaml:"label"`
|
||||
Number int `yaml:"number"`
|
||||
Size string `yaml:"size"`
|
||||
Start string `yaml:"start"`
|
||||
TypeGUID string `yaml:"type_guid"`
|
||||
type Group struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Gid *uint `json:"gid,omitempty"`
|
||||
PasswordHash string `json:"passwordHash,omitempty"`
|
||||
System bool `json:"system,omitempty"`
|
||||
}
|
||||
73
vendor/github.com/coreos/ignition/config/v2_0/types/hash.go
generated
vendored
Normal file
73
vendor/github.com/coreos/ignition/config/v2_0/types/hash.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHashMalformed = errors.New("malformed hash specifier")
|
||||
ErrHashWrongSize = errors.New("incorrect size for hash sum")
|
||||
ErrHashUnrecognized = errors.New("unrecognized hash function")
|
||||
)
|
||||
|
||||
type Hash struct {
|
||||
Function string
|
||||
Sum string
|
||||
}
|
||||
|
||||
func (h *Hash) UnmarshalJSON(data []byte) error {
|
||||
var th string
|
||||
if err := json.Unmarshal(data, &th); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parts := strings.SplitN(th, "-", 2)
|
||||
if len(parts) != 2 {
|
||||
return ErrHashMalformed
|
||||
}
|
||||
|
||||
h.Function = parts[0]
|
||||
h.Sum = parts[1]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Hash) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + h.Function + "-" + h.Sum + `"`), nil
|
||||
}
|
||||
|
||||
func (h Hash) Validate() report.Report {
|
||||
var hash crypto.Hash
|
||||
switch h.Function {
|
||||
case "sha512":
|
||||
hash = crypto.SHA512
|
||||
default:
|
||||
return report.ReportFromError(ErrHashUnrecognized, report.EntryError)
|
||||
}
|
||||
|
||||
if len(h.Sum) != hex.EncodedLen(hash.Size()) {
|
||||
return report.ReportFromError(ErrHashWrongSize, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
69
vendor/github.com/coreos/ignition/config/v2_0/types/ignition.go
generated
vendored
Normal file
69
vendor/github.com/coreos/ignition/config/v2_0/types/ignition.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrOldVersion = errors.New("incorrect config version (too old)")
|
||||
ErrNewVersion = errors.New("incorrect config version (too new)")
|
||||
)
|
||||
|
||||
type Ignition struct {
|
||||
Version IgnitionVersion `json:"version,omitempty" merge:"old"`
|
||||
Config IgnitionConfig `json:"config,omitempty" merge:"new"`
|
||||
}
|
||||
|
||||
type IgnitionConfig struct {
|
||||
Append []ConfigReference `json:"append,omitempty"`
|
||||
Replace *ConfigReference `json:"replace,omitempty"`
|
||||
}
|
||||
|
||||
type ConfigReference struct {
|
||||
Source Url `json:"source,omitempty"`
|
||||
Verification Verification `json:"verification,omitempty"`
|
||||
}
|
||||
|
||||
type IgnitionVersion semver.Version
|
||||
|
||||
func (v *IgnitionVersion) UnmarshalJSON(data []byte) error {
|
||||
tv := semver.Version(*v)
|
||||
if err := json.Unmarshal(data, &tv); err != nil {
|
||||
return err
|
||||
}
|
||||
*v = IgnitionVersion(tv)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v IgnitionVersion) MarshalJSON() ([]byte, error) {
|
||||
return semver.Version(v).MarshalJSON()
|
||||
}
|
||||
|
||||
func (v IgnitionVersion) Validate() report.Report {
|
||||
if MaxVersion.Major > v.Major {
|
||||
return report.ReportFromError(ErrOldVersion, report.EntryError)
|
||||
}
|
||||
if MaxVersion.LessThan(semver.Version(v)) {
|
||||
return report.ReportFromError(ErrNewVersion, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
@@ -15,10 +15,5 @@
|
||||
package types
|
||||
|
||||
type Networkd struct {
|
||||
Units []NetworkdUnit `yaml:"units"`
|
||||
}
|
||||
|
||||
type NetworkdUnit struct {
|
||||
Name string `yaml:"name"`
|
||||
Contents string `yaml:"contents"`
|
||||
Units []NetworkdUnit `json:"units,omitempty"`
|
||||
}
|
||||
59
vendor/github.com/coreos/ignition/config/v2_0/types/partition.go
generated
vendored
Normal file
59
vendor/github.com/coreos/ignition/config/v2_0/types/partition.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Partition struct {
|
||||
Label PartitionLabel `json:"label,omitempty"`
|
||||
Number int `json:"number"`
|
||||
Size PartitionDimension `json:"size"`
|
||||
Start PartitionDimension `json:"start"`
|
||||
TypeGUID PartitionTypeGUID `json:"typeGuid,omitempty"`
|
||||
}
|
||||
|
||||
type PartitionLabel string
|
||||
|
||||
func (n PartitionLabel) Validate() report.Report {
|
||||
// http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries:
|
||||
// 56 (0x38) 72 bytes Partition name (36 UTF-16LE code units)
|
||||
|
||||
// XXX(vc): note GPT calls it a name, we're using label for consistency
|
||||
// with udev naming /dev/disk/by-partlabel/*.
|
||||
if len(string(n)) > 36 {
|
||||
return report.ReportFromError(fmt.Errorf("partition labels may not exceed 36 characters"), report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type PartitionDimension uint64
|
||||
|
||||
type PartitionTypeGUID string
|
||||
|
||||
func (d PartitionTypeGUID) Validate() report.Report {
|
||||
ok, err := regexp.MatchString("^(|[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12})$", string(d))
|
||||
if err != nil {
|
||||
return report.ReportFromError(fmt.Errorf("error matching type-guid regexp: %v", err), report.EntryError)
|
||||
}
|
||||
if !ok {
|
||||
return report.ReportFromError(fmt.Errorf(`partition type-guid must have the form "01234567-89AB-CDEF-EDCB-A98765432101", got: %q`, string(d)), report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
20
vendor/github.com/coreos/ignition/config/v2_0/types/passwd.go
generated
vendored
Normal file
20
vendor/github.com/coreos/ignition/config/v2_0/types/passwd.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Passwd struct {
|
||||
Users []User `json:"users,omitempty"`
|
||||
Groups []Group `json:"groups,omitempty"`
|
||||
}
|
||||
@@ -14,19 +14,26 @@
|
||||
|
||||
package types
|
||||
|
||||
type Systemd struct {
|
||||
Units []SystemdUnit `yaml:"units"`
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrPathRelative = errors.New("path not absolute")
|
||||
)
|
||||
|
||||
type Path string
|
||||
|
||||
func (p Path) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + string(p) + `"`), nil
|
||||
}
|
||||
|
||||
type SystemdUnit struct {
|
||||
Name string `yaml:"name"`
|
||||
Enable bool `yaml:"enable"`
|
||||
Mask bool `yaml:"mask"`
|
||||
Contents string `yaml:"contents"`
|
||||
DropIns []SystemdUnitDropIn `yaml:"dropins"`
|
||||
}
|
||||
|
||||
type SystemdUnitDropIn struct {
|
||||
Name string `yaml:"name"`
|
||||
Contents string `yaml:"contents"`
|
||||
func (p Path) Validate() report.Report {
|
||||
if !path.IsAbs(string(p)) {
|
||||
return report.ReportFromError(ErrPathRelative, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
45
vendor/github.com/coreos/ignition/config/v2_0/types/raid.go
generated
vendored
Normal file
45
vendor/github.com/coreos/ignition/config/v2_0/types/raid.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type Raid struct {
|
||||
Name string `json:"name"`
|
||||
Level string `json:"level"`
|
||||
Devices []Path `json:"devices,omitempty"`
|
||||
Spares int `json:"spares,omitempty"`
|
||||
}
|
||||
|
||||
func (n Raid) Validate() report.Report {
|
||||
switch n.Level {
|
||||
case "linear", "raid0", "0", "stripe":
|
||||
if n.Spares != 0 {
|
||||
return report.ReportFromError(fmt.Errorf("spares unsupported for %q arrays", n.Level), report.EntryError)
|
||||
}
|
||||
case "raid1", "1", "mirror":
|
||||
case "raid4", "4":
|
||||
case "raid5", "5":
|
||||
case "raid6", "6":
|
||||
case "raid10", "10":
|
||||
default:
|
||||
return report.ReportFromError(fmt.Errorf("unrecognized raid level: %q", n.Level), report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
}
|
||||
22
vendor/github.com/coreos/ignition/config/v2_0/types/storage.go
generated
vendored
Normal file
22
vendor/github.com/coreos/ignition/config/v2_0/types/storage.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Storage struct {
|
||||
Disks []Disk `json:"disks,omitempty"`
|
||||
Arrays []Raid `json:"raid,omitempty"`
|
||||
Filesystems []Filesystem `json:"filesystems,omitempty"`
|
||||
Files []File `json:"files,omitempty"`
|
||||
}
|
||||
19
vendor/github.com/coreos/ignition/config/v2_0/types/systemd.go
generated
vendored
Normal file
19
vendor/github.com/coreos/ignition/config/v2_0/types/systemd.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Systemd struct {
|
||||
Units []SystemdUnit `json:"units,omitempty"`
|
||||
}
|
||||
111
vendor/github.com/coreos/ignition/config/v2_0/types/unit.go
generated
vendored
Normal file
111
vendor/github.com/coreos/ignition/config/v2_0/types/unit.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/coreos/go-systemd/unit"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
type SystemdUnit struct {
|
||||
Name SystemdUnitName `json:"name,omitempty"`
|
||||
Enable bool `json:"enable,omitempty"`
|
||||
Mask bool `json:"mask,omitempty"`
|
||||
Contents string `json:"contents,omitempty"`
|
||||
DropIns []SystemdUnitDropIn `json:"dropins,omitempty"`
|
||||
}
|
||||
|
||||
func (u SystemdUnit) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type SystemdUnitDropIn struct {
|
||||
Name SystemdUnitDropInName `json:"name,omitempty"`
|
||||
Contents string `json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
func (u SystemdUnitDropIn) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type SystemdUnitName string
|
||||
|
||||
func (n SystemdUnitName) Validate() report.Report {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(errors.New("invalid systemd unit extension"), report.EntryError)
|
||||
}
|
||||
}
|
||||
|
||||
type SystemdUnitDropInName string
|
||||
|
||||
func (n SystemdUnitDropInName) Validate() report.Report {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".conf":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(errors.New("invalid systemd unit drop-in extension"), report.EntryError)
|
||||
}
|
||||
}
|
||||
|
||||
type NetworkdUnit struct {
|
||||
Name NetworkdUnitName `json:"name,omitempty"`
|
||||
Contents string `json:"contents,omitempty"`
|
||||
}
|
||||
|
||||
func (u NetworkdUnit) Validate() report.Report {
|
||||
if err := validateUnitContent(u.Contents); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
|
||||
return report.Report{}
|
||||
}
|
||||
|
||||
type NetworkdUnitName string
|
||||
|
||||
func (n NetworkdUnitName) Validate() report.Report {
|
||||
switch path.Ext(string(n)) {
|
||||
case ".link", ".netdev", ".network":
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(errors.New("invalid networkd unit extension"), report.EntryError)
|
||||
}
|
||||
}
|
||||
|
||||
func validateUnitContent(content string) error {
|
||||
c := bytes.NewBufferString(content)
|
||||
_, err := unit.Deserialize(c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid unit content: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
72
vendor/github.com/coreos/ignition/config/v2_0/types/url.go
generated
vendored
Normal file
72
vendor/github.com/coreos/ignition/config/v2_0/types/url.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
"github.com/vincent-petithory/dataurl"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidScheme = errors.New("invalid url scheme")
|
||||
)
|
||||
|
||||
type Url url.URL
|
||||
|
||||
func (u *Url) UnmarshalJSON(data []byte) error {
|
||||
var tu string
|
||||
if err := json.Unmarshal(data, &tu); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pu, err := url.Parse(tu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*u = Url(*pu)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u Url) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + u.String() + `"`), nil
|
||||
}
|
||||
|
||||
func (u Url) String() string {
|
||||
tu := url.URL(u)
|
||||
return (&tu).String()
|
||||
}
|
||||
|
||||
func (u Url) Validate() report.Report {
|
||||
// Empty url is valid, indicates an empty file
|
||||
if u.String() == "" {
|
||||
return report.Report{}
|
||||
}
|
||||
switch url.URL(u).Scheme {
|
||||
case "http", "https", "oem":
|
||||
return report.Report{}
|
||||
case "data":
|
||||
if _, err := dataurl.DecodeString(u.String()); err != nil {
|
||||
return report.ReportFromError(err, report.EntryError)
|
||||
}
|
||||
return report.Report{}
|
||||
default:
|
||||
return report.ReportFromError(ErrInvalidScheme, report.EntryError)
|
||||
}
|
||||
}
|
||||
35
vendor/github.com/coreos/ignition/config/v2_0/types/user.go
generated
vendored
Normal file
35
vendor/github.com/coreos/ignition/config/v2_0/types/user.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
PasswordHash string `json:"passwordHash,omitempty"`
|
||||
SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty"`
|
||||
Create *UserCreate `json:"create,omitempty"`
|
||||
}
|
||||
|
||||
type UserCreate struct {
|
||||
Uid *uint `json:"uid,omitempty"`
|
||||
GECOS string `json:"gecos,omitempty"`
|
||||
Homedir string `json:"homeDir,omitempty"`
|
||||
NoCreateHome bool `json:"noCreateHome,omitempty"`
|
||||
PrimaryGroup string `json:"primaryGroup,omitempty"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
NoUserGroup bool `json:"noUserGroup,omitempty"`
|
||||
System bool `json:"system,omitempty"`
|
||||
NoLogInit bool `json:"noLogInit,omitempty"`
|
||||
Shell string `json:"shell,omitempty"`
|
||||
}
|
||||
19
vendor/github.com/coreos/ignition/config/v2_0/types/verification.go
generated
vendored
Normal file
19
vendor/github.com/coreos/ignition/config/v2_0/types/verification.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
type Verification struct {
|
||||
Hash *Hash `json:"hash,omitempty"`
|
||||
}
|
||||
16
vendor/github.com/coreos/ignition/config/validate/validate.go
generated
vendored
16
vendor/github.com/coreos/ignition/config/validate/validate.go
generated
vendored
@@ -20,7 +20,6 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/ignition/config/types"
|
||||
"github.com/coreos/ignition/config/validate/report"
|
||||
)
|
||||
|
||||
@@ -75,10 +74,7 @@ func Validate(vObj reflect.Value, ast AstNode, source io.ReadSeeker) (r report.R
|
||||
((vObj.Kind() != reflect.Ptr) ||
|
||||
(!vObj.IsNil() && !vObj.Elem().Type().Implements(reflect.TypeOf((*validator)(nil)).Elem()))) {
|
||||
sub_r := obj.Validate()
|
||||
if vObj.Type() != reflect.TypeOf(types.Config{}) {
|
||||
// Config checks are done on the config as a whole and shouldn't get line numbers
|
||||
sub_r.AddPosition(line, col, highlight)
|
||||
}
|
||||
sub_r.AddPosition(line, col, highlight)
|
||||
r.Merge(sub_r)
|
||||
|
||||
// Dont recurse on invalid inner nodes, it mostly leads to bogus messages
|
||||
@@ -122,12 +118,18 @@ type field struct {
|
||||
}
|
||||
|
||||
// getFields returns a field of all the fields in the struct, including the fields of
|
||||
// embedded structs.
|
||||
// embedded structs and structs inside interface{}'s
|
||||
func getFields(vObj reflect.Value) []field {
|
||||
if vObj.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
ret := []field{}
|
||||
for i := 0; i < vObj.Type().NumField(); i++ {
|
||||
if vObj.Type().Field(i).Anonymous {
|
||||
ret = append(ret, getFields(vObj.Field(i))...)
|
||||
// in the case of an embedded type that is an alias to interface, extract the
|
||||
// real type contained by the interface
|
||||
realObj := reflect.ValueOf(vObj.Field(i).Interface())
|
||||
ret = append(ret, getFields(realObj)...)
|
||||
} else {
|
||||
ret = append(ret, field{Type: vObj.Type().Field(i), Value: vObj.Field(i)})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user