mirror of
https://github.com/outbackdingo/matchbox.git
synced 2026-01-27 18:19:36 +00:00
Godeps: Add coreos/ignition to godeps
This commit is contained in:
36
Godeps/_workspace/src/github.com/coreos/ignition/src/config/cloudinit.go
generated
vendored
Normal file
36
Godeps/_workspace/src/github.com/coreos/ignition/src/config/cloudinit.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func isCloudConfig(userdata []byte) bool {
|
||||
header := strings.SplitN(string(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(userdata), "\n", 2)[0]
|
||||
return strings.HasPrefix(header, "#!")
|
||||
}
|
||||
83
Godeps/_workspace/src/github.com/coreos/ignition/src/config/config.go
generated
vendored
Normal file
83
Godeps/_workspace/src/github.com/coreos/ignition/src/config/config.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Version int `json:"ignitionVersion" yaml:"ignition_version"`
|
||||
Storage Storage `json:"storage,omitempty" yaml:"storage"`
|
||||
Systemd Systemd `json:"systemd,omitempty" yaml:"systemd"`
|
||||
Networkd Networkd `json:"networkd,omitempty" yaml:"networkd"`
|
||||
Passwd Passwd `json:"passwd,omitempty" yaml:"passwd"`
|
||||
}
|
||||
|
||||
const (
|
||||
Version = 1
|
||||
)
|
||||
|
||||
var (
|
||||
ErrVersion = errors.New("incorrect config version")
|
||||
ErrCloudConfig = errors.New("not a config (found coreos-cloudconfig)")
|
||||
ErrScript = errors.New("not a config (found coreos-cloudinit script)")
|
||||
ErrEmpty = errors.New("not a config (empty)")
|
||||
)
|
||||
|
||||
func Parse(config []byte) (cfg Config, err error) {
|
||||
if err = json.Unmarshal(config, &cfg); err == nil {
|
||||
if cfg.Version != Version {
|
||||
err = ErrVersion
|
||||
}
|
||||
} else if isCloudConfig(decompressIfGzipped(config)) {
|
||||
err = ErrCloudConfig
|
||||
} else if isScript(decompressIfGzipped(config)) {
|
||||
err = ErrScript
|
||||
} else if isEmpty(config) {
|
||||
err = ErrEmpty
|
||||
}
|
||||
if serr, ok := err.(*json.SyntaxError); ok {
|
||||
line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(config), serr.Offset)
|
||||
err = fmt.Errorf("error at line %d, column %d\n%s%v", line, col, highlight, err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func isEmpty(userdata []byte) bool {
|
||||
return len(userdata) == 0
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
87
Godeps/_workspace/src/github.com/coreos/ignition/src/config/config_test.go
generated
vendored
Normal file
87
Godeps/_workspace/src/github.com/coreos/ignition/src/config/config_test.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 config
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
type in struct {
|
||||
config []byte
|
||||
}
|
||||
type out struct {
|
||||
config Config
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{config: []byte(`{"ignitionVersion": 1}`)},
|
||||
out: out{config: Config{Version: 1}},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte(`{}`)},
|
||||
out: out{err: ErrVersion},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte{}},
|
||||
out: out{err: ErrEmpty},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte("#cloud-config")},
|
||||
out: out{err: ErrCloudConfig},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte("#cloud-config ")},
|
||||
out: out{err: ErrCloudConfig},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte("#cloud-config\n\r")},
|
||||
out: out{err: ErrCloudConfig},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte{0x1f, 0x8b, 0x08, 0x00, 0x03, 0xd6, 0x79, 0x56,
|
||||
0x00, 0x03, 0x53, 0x4e, 0xce, 0xc9, 0x2f, 0x4d, 0xd1, 0x4d, 0xce,
|
||||
0xcf, 0x4b, 0xcb, 0x4c, 0xe7, 0x02, 0x00, 0x05, 0x56, 0xb3, 0xb8,
|
||||
0x0e, 0x00, 0x00, 0x00}},
|
||||
out: out{err: ErrCloudConfig},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte("#!/bin/sh")},
|
||||
out: out{err: ErrScript},
|
||||
},
|
||||
{
|
||||
in: in{config: []byte{0x1f, 0x8b, 0x08, 0x00, 0x48, 0xda, 0x79, 0x56,
|
||||
0x00, 0x03, 0x53, 0x56, 0xd4, 0x4f, 0xca, 0xcc, 0xd3, 0x2f, 0xce,
|
||||
0xe0, 0x02, 0x00, 0x1d, 0x9d, 0xfb, 0x04, 0x0a, 0x00, 0x00, 0x00}},
|
||||
out: out{err: ErrScript},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
config, err := Parse(test.in.config)
|
||||
if !reflect.DeepEqual(test.out.config, config) {
|
||||
t.Errorf("#%d: bad config: want %+v, got %+v", i, test.out.config, config)
|
||||
}
|
||||
if test.out.err != err {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Godeps/_workspace/src/github.com/coreos/ignition/src/config/devicepath.go
generated
vendored
Normal file
50
Godeps/_workspace/src/github.com/coreos/ignition/src/config/devicepath.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type DevicePath string
|
||||
|
||||
func (d *DevicePath) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return d.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (d *DevicePath) UnmarshalJSON(data []byte) error {
|
||||
return d.unmarshal(func(td interface{}) error {
|
||||
return json.Unmarshal(data, td)
|
||||
})
|
||||
}
|
||||
|
||||
type devicePath DevicePath
|
||||
|
||||
func (d *DevicePath) unmarshal(unmarshal func(interface{}) error) error {
|
||||
td := devicePath(*d)
|
||||
if err := unmarshal(&td); err != nil {
|
||||
return err
|
||||
}
|
||||
*d = DevicePath(td)
|
||||
return d.assertValid()
|
||||
}
|
||||
|
||||
func (d DevicePath) assertValid() error {
|
||||
if !filepath.IsAbs(string(d)) {
|
||||
return ErrFilesystemRelativePath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
167
Godeps/_workspace/src/github.com/coreos/ignition/src/config/disk.go
generated
vendored
Normal file
167
Godeps/_workspace/src/github.com/coreos/ignition/src/config/disk.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Disk struct {
|
||||
Device DevicePath `json:"device,omitempty" yaml:"device"`
|
||||
WipeTable bool `json:"wipeTable,omitempty" yaml:"wipe_table"`
|
||||
Partitions []Partition `json:"partitions,omitempty" yaml:"partitions"`
|
||||
}
|
||||
|
||||
func (n *Disk) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
if err := n.unmarshal(unmarshal); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := n.preparePartitions(); err != nil {
|
||||
return err
|
||||
}
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n *Disk) UnmarshalJSON(data []byte) error {
|
||||
err := n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
type disk Disk
|
||||
|
||||
func (n *Disk) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := disk(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = Disk(tn)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n Disk) assertValid() error {
|
||||
// This applies to YAML (post-prepare) and JSON unmarshals equally:
|
||||
if len(n.Device) == 0 {
|
||||
return fmt.Errorf("disk device is required")
|
||||
}
|
||||
if n.partitionNumbersCollide() {
|
||||
return fmt.Errorf("disk %q: partition numbers collide", n.Device)
|
||||
}
|
||||
if n.partitionsOverlap() {
|
||||
return fmt.Errorf("disk %q: partitions overlap", n.Device)
|
||||
}
|
||||
if n.partitionsMisaligned() {
|
||||
return fmt.Errorf("disk %q: partitions misaligned", n.Device)
|
||||
}
|
||||
// Disks which get to this point will likely succeed in sgdisk
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// preparePartitions performs some checks and potentially adjusts the partitions for alignment.
|
||||
// This is only invoked when unmarshalling YAML, since there we parse human-friendly units.
|
||||
func (n *Disk) preparePartitions() error {
|
||||
// On the YAML side we accept human-friendly units which may require massaging.
|
||||
|
||||
// align partition starts
|
||||
for i := range n.Partitions {
|
||||
// skip automatically placed partitions
|
||||
if n.Partitions[i].Start == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// keep partitions out of the first 2048 sectors
|
||||
if n.Partitions[i].Start < 2048 {
|
||||
n.Partitions[i].Start = 2048
|
||||
}
|
||||
|
||||
// toss the bottom 11 bits
|
||||
n.Partitions[i].Start &= ^PartitionDimension(2048 - 1)
|
||||
}
|
||||
|
||||
// TODO(vc): may be interesting to do something about potentially overlapping partitions
|
||||
return nil
|
||||
}
|
||||
63
Godeps/_workspace/src/github.com/coreos/ignition/src/config/file.go
generated
vendored
Normal file
63
Godeps/_workspace/src/github.com/coreos/ignition/src/config/file.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileIllegalMode = errors.New("illegal file mode")
|
||||
)
|
||||
|
||||
type FileMode os.FileMode
|
||||
|
||||
type File struct {
|
||||
Path string `json:"path,omitempty" yaml:"path"`
|
||||
Contents string `json:"contents,omitempty" yaml:"contents"`
|
||||
Mode FileMode `json:"mode,omitempty" yaml:"mode"`
|
||||
Uid int `json:"uid,omitempty" yaml:"uid"`
|
||||
Gid int `json:"gid,omitempty" yaml:"gid"`
|
||||
}
|
||||
|
||||
func (m *FileMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return m.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (m *FileMode) UnmarshalJSON(data []byte) error {
|
||||
return m.unmarshal(func(tm interface{}) error {
|
||||
return json.Unmarshal(data, tm)
|
||||
})
|
||||
}
|
||||
|
||||
type fileMode FileMode
|
||||
|
||||
func (m *FileMode) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tm := fileMode(*m)
|
||||
if err := unmarshal(&tm); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = FileMode(tm)
|
||||
return m.assertValid()
|
||||
}
|
||||
|
||||
func (m FileMode) assertValid() error {
|
||||
if (m &^ 07777) != 0 {
|
||||
return ErrFileIllegalMode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
139
Godeps/_workspace/src/github.com/coreos/ignition/src/config/file_test.go
generated
vendored
Normal file
139
Godeps/_workspace/src/github.com/coreos/ignition/src/config/file_test.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
|
||||
)
|
||||
|
||||
func TestFileModeUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
mode FileMode
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `420`},
|
||||
out: out{mode: FileMode(420)},
|
||||
},
|
||||
{
|
||||
in: in{data: `9999`},
|
||||
out: out{mode: FileMode(9999), err: ErrFileIllegalMode},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var mode FileMode
|
||||
err := json.Unmarshal([]byte(test.in.data), &mode)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.mode, mode) {
|
||||
t.Errorf("#%d: bad mode: want %#o, got %#o", i, test.out.mode, mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileModeUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
mode FileMode
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `0644`},
|
||||
out: out{mode: FileMode(0644)},
|
||||
},
|
||||
{
|
||||
in: in{data: `0420`},
|
||||
out: out{mode: FileMode(0420)},
|
||||
},
|
||||
{
|
||||
in: in{data: `017777`},
|
||||
out: out{mode: FileMode(017777), err: ErrFileIllegalMode},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var mode FileMode
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &mode)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.mode, mode) {
|
||||
t.Errorf("#%d: bad mode: want %#o, got %#o", i, test.out.mode, mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileAssertValid(t *testing.T) {
|
||||
type in struct {
|
||||
mode FileMode
|
||||
}
|
||||
type out struct {
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{mode: FileMode(0)},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{mode: FileMode(0644)},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{mode: FileMode(01755)},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{mode: FileMode(07777)},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{mode: FileMode(010000)},
|
||||
out: out{err: ErrFileIllegalMode},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
err := test.in.mode.assertValid()
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
96
Godeps/_workspace/src/github.com/coreos/ignition/src/config/filesystem.go
generated
vendored
Normal file
96
Godeps/_workspace/src/github.com/coreos/ignition/src/config/filesystem.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFilesystemRelativePath = errors.New("device path not absolute")
|
||||
ErrFilesystemInvalidFormat = errors.New("invalid filesystem format")
|
||||
)
|
||||
|
||||
type Filesystem struct {
|
||||
Device DevicePath `json:"device,omitempty" yaml:"device"`
|
||||
Format FilesystemFormat `json:"format,omitempty" yaml:"format"`
|
||||
Create *FilesystemCreate `json:"create,omitempty" yaml:"create"`
|
||||
Files []File `json:"files,omitempty" yaml:"files"`
|
||||
}
|
||||
|
||||
type FilesystemCreate struct {
|
||||
Force bool `json:"force,omitempty" yaml:"force"`
|
||||
Options MkfsOptions `json:"options,omitempty" yaml:"options"`
|
||||
}
|
||||
|
||||
type FilesystemFormat string
|
||||
|
||||
func (f *FilesystemFormat) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return f.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (f *FilesystemFormat) UnmarshalJSON(data []byte) error {
|
||||
return f.unmarshal(func(tf interface{}) error {
|
||||
return json.Unmarshal(data, tf)
|
||||
})
|
||||
}
|
||||
|
||||
type filesystemFormat FilesystemFormat
|
||||
|
||||
func (f *FilesystemFormat) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tf := filesystemFormat(*f)
|
||||
if err := unmarshal(&tf); err != nil {
|
||||
return err
|
||||
}
|
||||
*f = FilesystemFormat(tf)
|
||||
return f.assertValid()
|
||||
}
|
||||
|
||||
func (f FilesystemFormat) assertValid() error {
|
||||
switch f {
|
||||
case "ext4", "btrfs", "xfs":
|
||||
return nil
|
||||
default:
|
||||
return ErrFilesystemInvalidFormat
|
||||
}
|
||||
}
|
||||
|
||||
type MkfsOptions []string
|
||||
|
||||
func (o *MkfsOptions) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return o.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (o *MkfsOptions) UnmarshalJSON(data []byte) error {
|
||||
return o.unmarshal(func(to interface{}) error {
|
||||
return json.Unmarshal(data, to)
|
||||
})
|
||||
}
|
||||
|
||||
type mkfsOptions MkfsOptions
|
||||
|
||||
func (o *MkfsOptions) unmarshal(unmarshal func(interface{}) error) error {
|
||||
to := mkfsOptions(*o)
|
||||
if err := unmarshal(&to); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = MkfsOptions(to)
|
||||
return o.assertValid()
|
||||
}
|
||||
|
||||
func (o MkfsOptions) assertValid() error {
|
||||
return nil
|
||||
}
|
||||
302
Godeps/_workspace/src/github.com/coreos/ignition/src/config/filesystem_test.go
generated
vendored
Normal file
302
Godeps/_workspace/src/github.com/coreos/ignition/src/config/filesystem_test.go
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
|
||||
)
|
||||
|
||||
func TestDevicePathUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
device DevicePath
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"/path"`},
|
||||
out: out{device: DevicePath("/path")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"bad"`},
|
||||
out: out{device: DevicePath("bad"), err: errors.New("device path not absolute")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var device DevicePath
|
||||
err := json.Unmarshal([]byte(test.in.data), &device)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.device, device) {
|
||||
t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevicePathUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
device DevicePath
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"/path"`},
|
||||
out: out{device: DevicePath("/path")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"bad"`},
|
||||
out: out{device: DevicePath("bad"), err: errors.New("device path not absolute")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var device DevicePath
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &device)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.device, device) {
|
||||
t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevicePathAssertValid(t *testing.T) {
|
||||
type in struct {
|
||||
device DevicePath
|
||||
}
|
||||
type out struct {
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{device: DevicePath("/good/path")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{device: DevicePath("/name")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{device: DevicePath("/this/is/a/fairly/long/path/to/a/device.")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{device: DevicePath("/this one has spaces")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{device: DevicePath("relative/path")},
|
||||
out: out{err: errors.New("device path not absolute")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
err := test.in.device.assertValid()
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilesystemFormatUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
format FilesystemFormat
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"ext4"`},
|
||||
out: out{format: FilesystemFormat("ext4")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"bad"`},
|
||||
out: out{format: FilesystemFormat("bad"), err: errors.New("invalid filesystem format")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var format FilesystemFormat
|
||||
err := json.Unmarshal([]byte(test.in.data), &format)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.format, format) {
|
||||
t.Errorf("#%d: bad format: want %#v, got %#v", i, test.out.format, format)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilesystemFormatUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
format FilesystemFormat
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"ext4"`},
|
||||
out: out{format: FilesystemFormat("ext4")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"bad"`},
|
||||
out: out{format: FilesystemFormat("bad"), err: errors.New("invalid filesystem format")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var format FilesystemFormat
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &format)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.format, format) {
|
||||
t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.format, format)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilesystemFormatAssertValid(t *testing.T) {
|
||||
type in struct {
|
||||
format FilesystemFormat
|
||||
}
|
||||
type out struct {
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{format: FilesystemFormat("ext4")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{format: FilesystemFormat("btrfs")},
|
||||
out: out{},
|
||||
},
|
||||
{
|
||||
in: in{format: FilesystemFormat("")},
|
||||
out: out{err: errors.New("invalid filesystem format")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
err := test.in.format.assertValid()
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMkfsOptionsUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
options MkfsOptions
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `["--label=ROOT"]`},
|
||||
out: out{options: MkfsOptions([]string{"--label=ROOT"})},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var options MkfsOptions
|
||||
err := json.Unmarshal([]byte(test.in.data), &options)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.options, options) {
|
||||
t.Errorf("#%d: bad format: want %#v, got %#v", i, test.out.options, options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMkfsOptionsUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
options MkfsOptions
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `["--label=ROOT"]`},
|
||||
out: out{options: MkfsOptions([]string{"--label=ROOT"})},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var options MkfsOptions
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &options)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.out.options, options) {
|
||||
t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.options, options)
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Godeps/_workspace/src/github.com/coreos/ignition/src/config/group.go
generated
vendored
Normal file
22
Godeps/_workspace/src/github.com/coreos/ignition/src/config/group.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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 config
|
||||
|
||||
type Group struct {
|
||||
Name string `json:"name,omitempty" yaml:"name"`
|
||||
Gid *uint `json:"gid,omitempty" yaml:"gid"`
|
||||
PasswordHash string `json:"passwordHash,omitempty" yaml:"password_hash"`
|
||||
System bool `json:"system,omitempty" yaml:"system"`
|
||||
}
|
||||
19
Godeps/_workspace/src/github.com/coreos/ignition/src/config/networkd.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/coreos/ignition/src/config/networkd.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// 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 config
|
||||
|
||||
type Networkd struct {
|
||||
Units []NetworkdUnit `json:"units,omitempty" yaml:"units"`
|
||||
}
|
||||
137
Godeps/_workspace/src/github.com/coreos/ignition/src/config/partition.go
generated
vendored
Normal file
137
Godeps/_workspace/src/github.com/coreos/ignition/src/config/partition.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/coreos/ignition/third_party/github.com/alecthomas/units"
|
||||
)
|
||||
|
||||
type Partition struct {
|
||||
Label PartitionLabel `json:"label,omitempty" yaml:"label"`
|
||||
Number int `json:"number" yaml:"number"`
|
||||
Size PartitionDimension `json:"size" yaml:"size"`
|
||||
Start PartitionDimension `json:"start" yaml:"start"`
|
||||
TypeGUID PartitionTypeGUID `json:"typeGuid,omitempty" yaml:"type_guid"`
|
||||
}
|
||||
|
||||
type PartitionLabel string
|
||||
|
||||
func (n *PartitionLabel) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return n.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (n *PartitionLabel) UnmarshalJSON(data []byte) error {
|
||||
return n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
}
|
||||
|
||||
type partitionLabel PartitionLabel
|
||||
|
||||
func (n *PartitionLabel) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := partitionLabel(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = PartitionLabel(tn)
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n PartitionLabel) assertValid() error {
|
||||
// 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 fmt.Errorf("partition labels may not exceed 36 characters")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PartitionDimension uint64
|
||||
|
||||
func (n *PartitionDimension) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
// In YAML we allow human-readable dimensions like GiB/TiB etc.
|
||||
var str string
|
||||
if err := unmarshal(&str); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b2b, err := units.ParseBase2Bytes(str) // TODO(vc): replace the units package
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b2b < 0 {
|
||||
return fmt.Errorf("negative value inappropriate: %q", str)
|
||||
}
|
||||
|
||||
// Translate bytes into sectors
|
||||
sectors := (b2b / 512)
|
||||
if b2b%512 != 0 {
|
||||
sectors++
|
||||
}
|
||||
*n = PartitionDimension(uint64(sectors))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *PartitionDimension) UnmarshalJSON(data []byte) error {
|
||||
// In JSON we expect plain integral sectors.
|
||||
// The YAML->JSON conversion is responsible for normalizing human units to sectors.
|
||||
var pd uint64
|
||||
if err := json.Unmarshal(data, &pd); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = PartitionDimension(pd)
|
||||
return nil
|
||||
}
|
||||
|
||||
type PartitionTypeGUID string
|
||||
|
||||
func (d *PartitionTypeGUID) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return d.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (d *PartitionTypeGUID) UnmarshalJSON(data []byte) error {
|
||||
return d.unmarshal(func(td interface{}) error {
|
||||
return json.Unmarshal(data, td)
|
||||
})
|
||||
}
|
||||
|
||||
type partitionTypeGUID PartitionTypeGUID
|
||||
|
||||
func (d *PartitionTypeGUID) unmarshal(unmarshal func(interface{}) error) error {
|
||||
td := partitionTypeGUID(*d)
|
||||
if err := unmarshal(&td); err != nil {
|
||||
return err
|
||||
}
|
||||
*d = PartitionTypeGUID(td)
|
||||
return d.assertValid()
|
||||
}
|
||||
|
||||
func (d PartitionTypeGUID) assertValid() error {
|
||||
ok, err := regexp.MatchString("[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}", string(d))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error matching type-guid regexp: %v", err)
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf(`partition type-guid must have the form "01234567-89AB-CDEF-EDCB-A98765432101", got: %q`, string(d))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
20
Godeps/_workspace/src/github.com/coreos/ignition/src/config/passwd.go
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/coreos/ignition/src/config/passwd.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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 config
|
||||
|
||||
type Passwd struct {
|
||||
Users []User `json:"users,omitempty" yaml:"users"`
|
||||
Groups []Group `json:"groups,omitempty" yaml:"groups"`
|
||||
}
|
||||
65
Godeps/_workspace/src/github.com/coreos/ignition/src/config/raid.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/coreos/ignition/src/config/raid.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Raid struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Level string `json:"level" yaml:"level"`
|
||||
Devices []DevicePath `json:"devices,omitempty" yaml:"devices"`
|
||||
Spares int `json:"spares,omitempty" yaml:"spares"`
|
||||
}
|
||||
|
||||
func (n *Raid) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return n.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (n *Raid) UnmarshalJSON(data []byte) error {
|
||||
return n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
}
|
||||
|
||||
type raid Raid
|
||||
|
||||
func (n *Raid) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := raid(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = Raid(tn)
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n Raid) assertValid() error {
|
||||
switch n.Level {
|
||||
case "linear", "raid0", "0", "stripe":
|
||||
if n.Spares != 0 {
|
||||
return fmt.Errorf("spares unsupported for %q arrays", n.Level)
|
||||
}
|
||||
case "raid1", "1", "mirror":
|
||||
case "raid4", "4":
|
||||
case "raid5", "5":
|
||||
case "raid6", "6":
|
||||
case "raid10", "10":
|
||||
default:
|
||||
return fmt.Errorf("unrecognized raid level: %q", n.Level)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
21
Godeps/_workspace/src/github.com/coreos/ignition/src/config/storage.go
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/coreos/ignition/src/config/storage.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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 config
|
||||
|
||||
type Storage struct {
|
||||
Disks []Disk `json:"disks,omitempty" yaml:"disks"`
|
||||
Arrays []Raid `json:"raid,omitempty" yaml:"raid"`
|
||||
Filesystems []Filesystem `json:"filesystems,omitempty" yaml:"filesystems"`
|
||||
}
|
||||
19
Godeps/_workspace/src/github.com/coreos/ignition/src/config/systemd.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/coreos/ignition/src/config/systemd.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// 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 config
|
||||
|
||||
type Systemd struct {
|
||||
Units []SystemdUnit `json:"units,omitempty" yaml:"units"`
|
||||
}
|
||||
135
Godeps/_workspace/src/github.com/coreos/ignition/src/config/unit.go
generated
vendored
Normal file
135
Godeps/_workspace/src/github.com/coreos/ignition/src/config/unit.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type SystemdUnit struct {
|
||||
Name SystemdUnitName `json:"name,omitempty" yaml:"name"`
|
||||
Enable bool `json:"enable,omitempty" yaml:"enable"`
|
||||
Mask bool `json:"mask,omitempty" yaml:"mask"`
|
||||
Contents string `json:"contents,omitempty" yaml:"contents"`
|
||||
DropIns []SystemdUnitDropIn `json:"dropins,omitempty" yaml:"dropins"`
|
||||
}
|
||||
|
||||
type SystemdUnitDropIn struct {
|
||||
Name SystemdUnitDropInName `json:"name,omitempty" yaml:"name"`
|
||||
Contents string `json:"contents,omitempty" yaml:"contents"`
|
||||
}
|
||||
|
||||
type SystemdUnitName string
|
||||
|
||||
func (n *SystemdUnitName) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return n.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (n *SystemdUnitName) UnmarshalJSON(data []byte) error {
|
||||
return n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
}
|
||||
|
||||
type systemdUnitName SystemdUnitName
|
||||
|
||||
func (n *SystemdUnitName) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := systemdUnitName(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = SystemdUnitName(tn)
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n SystemdUnitName) assertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope":
|
||||
return nil
|
||||
default:
|
||||
return errors.New("invalid systemd unit extension")
|
||||
}
|
||||
}
|
||||
|
||||
type SystemdUnitDropInName string
|
||||
|
||||
func (n *SystemdUnitDropInName) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return n.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (n *SystemdUnitDropInName) UnmarshalJSON(data []byte) error {
|
||||
return n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
}
|
||||
|
||||
type systemdUnitDropInName SystemdUnitDropInName
|
||||
|
||||
func (n *SystemdUnitDropInName) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := systemdUnitDropInName(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = SystemdUnitDropInName(tn)
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n SystemdUnitDropInName) assertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
case ".conf":
|
||||
return nil
|
||||
default:
|
||||
return errors.New("invalid systemd unit drop-in extension")
|
||||
}
|
||||
}
|
||||
|
||||
type NetworkdUnit struct {
|
||||
Name NetworkdUnitName `json:"name,omitempty" yaml:"name"`
|
||||
Contents string `json:"contents,omitempty" yaml:"contents"`
|
||||
}
|
||||
|
||||
type NetworkdUnitName string
|
||||
|
||||
func (n *NetworkdUnitName) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
return n.unmarshal(unmarshal)
|
||||
}
|
||||
|
||||
func (n *NetworkdUnitName) UnmarshalJSON(data []byte) error {
|
||||
return n.unmarshal(func(tn interface{}) error {
|
||||
return json.Unmarshal(data, tn)
|
||||
})
|
||||
}
|
||||
|
||||
type networkdUnitName NetworkdUnitName
|
||||
|
||||
func (n *NetworkdUnitName) unmarshal(unmarshal func(interface{}) error) error {
|
||||
tn := networkdUnitName(*n)
|
||||
if err := unmarshal(&tn); err != nil {
|
||||
return err
|
||||
}
|
||||
*n = NetworkdUnitName(tn)
|
||||
return n.assertValid()
|
||||
}
|
||||
|
||||
func (n NetworkdUnitName) assertValid() error {
|
||||
switch filepath.Ext(string(n)) {
|
||||
case ".link", ".netdev", ".network":
|
||||
return nil
|
||||
default:
|
||||
return errors.New("invalid networkd unit extension")
|
||||
}
|
||||
}
|
||||
204
Godeps/_workspace/src/github.com/coreos/ignition/src/config/unit_test.go
generated
vendored
Normal file
204
Godeps/_workspace/src/github.com/coreos/ignition/src/config/unit_test.go
generated
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
|
||||
)
|
||||
|
||||
func TestSystemdUnitNameUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
unit SystemdUnitName
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"test.service"`},
|
||||
out: out{unit: SystemdUnitName("test.service")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.socket"`},
|
||||
out: out{unit: SystemdUnitName("test.socket")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.blah"`},
|
||||
out: out{err: errors.New("invalid systemd unit extension")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var unit SystemdUnitName
|
||||
err := json.Unmarshal([]byte(test.in.data), &unit)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.out.unit, unit) {
|
||||
t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSystemdUnitNameUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
unit SystemdUnitName
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"test.service"`},
|
||||
out: out{unit: SystemdUnitName("test.service")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.socket"`},
|
||||
out: out{unit: SystemdUnitName("test.socket")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.blah"`},
|
||||
out: out{err: errors.New("invalid systemd unit extension")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var unit SystemdUnitName
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &unit)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.out.unit, unit) {
|
||||
t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkdUnitNameUnmarshalJSON(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
unit NetworkdUnitName
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"test.network"`},
|
||||
out: out{unit: NetworkdUnitName("test.network")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.link"`},
|
||||
out: out{unit: NetworkdUnitName("test.link")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.netdev"`},
|
||||
out: out{unit: NetworkdUnitName("test.netdev")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.blah"`},
|
||||
out: out{err: errors.New("invalid networkd unit extension")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var unit NetworkdUnitName
|
||||
err := json.Unmarshal([]byte(test.in.data), &unit)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.out.unit, unit) {
|
||||
t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkdUnitNameUnmarshalYAML(t *testing.T) {
|
||||
type in struct {
|
||||
data string
|
||||
}
|
||||
type out struct {
|
||||
unit NetworkdUnitName
|
||||
err error
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in in
|
||||
out out
|
||||
}{
|
||||
{
|
||||
in: in{data: `"test.network"`},
|
||||
out: out{unit: NetworkdUnitName("test.network")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.link"`},
|
||||
out: out{unit: NetworkdUnitName("test.link")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.netdev"`},
|
||||
out: out{unit: NetworkdUnitName("test.netdev")},
|
||||
},
|
||||
{
|
||||
in: in{data: `"test.blah"`},
|
||||
out: out{err: errors.New("invalid networkd unit extension")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
var unit NetworkdUnitName
|
||||
err := yaml.Unmarshal([]byte(test.in.data), &unit)
|
||||
if !reflect.DeepEqual(test.out.err, err) {
|
||||
t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.out.unit, unit) {
|
||||
t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Godeps/_workspace/src/github.com/coreos/ignition/src/config/user.go
generated
vendored
Normal file
35
Godeps/_workspace/src/github.com/coreos/ignition/src/config/user.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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 config
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name,omitempty" yaml:"name"`
|
||||
PasswordHash string `json:"passwordHash,omitempty" yaml:"password_hash"`
|
||||
SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty" yaml:"ssh_authorized_keys"`
|
||||
Create *UserCreate `json:"create,omitempty" yaml:"create"`
|
||||
}
|
||||
|
||||
type UserCreate struct {
|
||||
Uid *uint `json:"uid,omitempty" yaml:"uid"`
|
||||
GECOS string `json:"gecos,omitempty" yaml:"gecos"`
|
||||
Homedir string `json:"homeDir,omitempty" yaml:"home_dir"`
|
||||
NoCreateHome bool `json:"noCreateHome,omitempty" yaml:"no_create_home"`
|
||||
PrimaryGroup string `json:"primaryGroup,omitempty" yaml:"primary_group"`
|
||||
Groups []string `json:"groups,omitempty" yaml:"groups"`
|
||||
NoUserGroup bool `json:"noUserGroup,omitempty" yaml:"no_user_group"`
|
||||
System bool `json:"system,omitempty" yaml:"system"`
|
||||
NoLogInit bool `json:"noLogInit,omitempty" yaml:"no_log_init"`
|
||||
Shell string `json:"shell,omitempty" yaml:"shell"`
|
||||
}
|
||||
19
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/COPYING
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/COPYING
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2014 Alec Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
11
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/README.md
generated
vendored
Normal file
11
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/README.md
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Units - Helpful unit multipliers and functions for Go
|
||||
|
||||
The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package.
|
||||
|
||||
It allows for code like this:
|
||||
|
||||
```go
|
||||
n, err := ParseBase2Bytes("1KB")
|
||||
// n == 1024
|
||||
n = units.Mebibyte * 512
|
||||
```
|
||||
83
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes.go
generated
vendored
Normal file
83
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package units
|
||||
|
||||
// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,
|
||||
// etc.).
|
||||
type Base2Bytes int64
|
||||
|
||||
// Base-2 byte units.
|
||||
const (
|
||||
Kibibyte Base2Bytes = 1024
|
||||
KiB = Kibibyte
|
||||
Mebibyte = Kibibyte * 1024
|
||||
MiB = Mebibyte
|
||||
Gibibyte = Mebibyte * 1024
|
||||
GiB = Gibibyte
|
||||
Tebibyte = Gibibyte * 1024
|
||||
TiB = Tebibyte
|
||||
Pebibyte = Tebibyte * 1024
|
||||
PiB = Pebibyte
|
||||
Exbibyte = Pebibyte * 1024
|
||||
EiB = Exbibyte
|
||||
)
|
||||
|
||||
var (
|
||||
bytesUnitMap = MakeUnitMap("iB", "B", 1024)
|
||||
oldBytesUnitMap = MakeUnitMap("B", "B", 1024)
|
||||
)
|
||||
|
||||
// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
|
||||
// and KiB are both 1024.
|
||||
func ParseBase2Bytes(s string) (Base2Bytes, error) {
|
||||
n, err := ParseUnit(s, bytesUnitMap)
|
||||
if err != nil {
|
||||
n, err = ParseUnit(s, oldBytesUnitMap)
|
||||
}
|
||||
return Base2Bytes(n), err
|
||||
}
|
||||
|
||||
func (b Base2Bytes) String() string {
|
||||
return ToString(int64(b), 1024, "iB", "B")
|
||||
}
|
||||
|
||||
var (
|
||||
metricBytesUnitMap = MakeUnitMap("B", "B", 1000)
|
||||
)
|
||||
|
||||
// MetricBytes are SI byte units (1000 bytes in a kilobyte).
|
||||
type MetricBytes SI
|
||||
|
||||
// SI base-10 byte units.
|
||||
const (
|
||||
Kilobyte MetricBytes = 1000
|
||||
KB = Kilobyte
|
||||
Megabyte = Kilobyte * 1000
|
||||
MB = Megabyte
|
||||
Gigabyte = Megabyte * 1000
|
||||
GB = Gigabyte
|
||||
Terabyte = Gigabyte * 1000
|
||||
TB = Terabyte
|
||||
Petabyte = Terabyte * 1000
|
||||
PB = Petabyte
|
||||
Exabyte = Petabyte * 1000
|
||||
EB = Exabyte
|
||||
)
|
||||
|
||||
// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes.
|
||||
func ParseMetricBytes(s string) (MetricBytes, error) {
|
||||
n, err := ParseUnit(s, metricBytesUnitMap)
|
||||
return MetricBytes(n), err
|
||||
}
|
||||
|
||||
func (m MetricBytes) String() string {
|
||||
return ToString(int64(m), 1000, "B", "B")
|
||||
}
|
||||
|
||||
// ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
|
||||
// respectively. That is, KiB represents 1024 and KB represents 1000.
|
||||
func ParseStrictBytes(s string) (int64, error) {
|
||||
n, err := ParseUnit(s, bytesUnitMap)
|
||||
if err != nil {
|
||||
n, err = ParseUnit(s, metricBytesUnitMap)
|
||||
}
|
||||
return int64(n), err
|
||||
}
|
||||
49
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes_test.go
generated
vendored
Normal file
49
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBase2BytesString(t *testing.T) {
|
||||
assert.Equal(t, Base2Bytes(0).String(), "0B")
|
||||
assert.Equal(t, Base2Bytes(1025).String(), "1KiB1B")
|
||||
assert.Equal(t, Base2Bytes(1048577).String(), "1MiB1B")
|
||||
}
|
||||
|
||||
func TestParseBase2Bytes(t *testing.T) {
|
||||
n, err := ParseBase2Bytes("0B")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, n)
|
||||
n, err = ParseBase2Bytes("1KB")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1024, n)
|
||||
n, err = ParseBase2Bytes("1MB1KB25B")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1049625, n)
|
||||
n, err = ParseBase2Bytes("1.5MB")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1572864, n)
|
||||
}
|
||||
|
||||
func TestMetricBytesString(t *testing.T) {
|
||||
assert.Equal(t, MetricBytes(0).String(), "0B")
|
||||
assert.Equal(t, MetricBytes(1001).String(), "1KB1B")
|
||||
assert.Equal(t, MetricBytes(1001025).String(), "1MB1KB25B")
|
||||
}
|
||||
|
||||
func TestParseMetricBytes(t *testing.T) {
|
||||
n, err := ParseMetricBytes("0B")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, n)
|
||||
n, err = ParseMetricBytes("1KB1B")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1001, n)
|
||||
n, err = ParseMetricBytes("1MB1KB25B")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1001025, n)
|
||||
n, err = ParseMetricBytes("1.5MB")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1500000, n)
|
||||
}
|
||||
13
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/doc.go
generated
vendored
Normal file
13
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/doc.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Package units provides helpful unit multipliers and functions for Go.
|
||||
//
|
||||
// The goal of this package is to have functionality similar to the time [1] package.
|
||||
//
|
||||
//
|
||||
// [1] http://golang.org/pkg/time/
|
||||
//
|
||||
// It allows for code like this:
|
||||
//
|
||||
// n, err := ParseBase2Bytes("1KB")
|
||||
// // n == 1024
|
||||
// n = units.Mebibyte * 512
|
||||
package units
|
||||
26
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/si.go
generated
vendored
Normal file
26
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/si.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package units
|
||||
|
||||
// SI units.
|
||||
type SI int64
|
||||
|
||||
// SI unit multiples.
|
||||
const (
|
||||
Kilo SI = 1000
|
||||
Mega = Kilo * 1000
|
||||
Giga = Mega * 1000
|
||||
Tera = Giga * 1000
|
||||
Peta = Tera * 1000
|
||||
Exa = Peta * 1000
|
||||
)
|
||||
|
||||
func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 {
|
||||
return map[string]float64{
|
||||
shortSuffix: 1,
|
||||
"K" + suffix: float64(scale),
|
||||
"M" + suffix: float64(scale * scale),
|
||||
"G" + suffix: float64(scale * scale * scale),
|
||||
"T" + suffix: float64(scale * scale * scale * scale),
|
||||
"P" + suffix: float64(scale * scale * scale * scale * scale),
|
||||
"E" + suffix: float64(scale * scale * scale * scale * scale * scale),
|
||||
}
|
||||
}
|
||||
138
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/util.go
generated
vendored
Normal file
138
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/alecthomas/units/util.go
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
package units
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
siUnits = []string{"", "K", "M", "G", "T", "P", "E"}
|
||||
)
|
||||
|
||||
func ToString(n int64, scale int64, suffix, baseSuffix string) string {
|
||||
mn := len(siUnits)
|
||||
out := make([]string, mn)
|
||||
for i, m := range siUnits {
|
||||
if n%scale != 0 || i == 0 && n == 0 {
|
||||
s := suffix
|
||||
if i == 0 {
|
||||
s = baseSuffix
|
||||
}
|
||||
out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s)
|
||||
}
|
||||
n /= scale
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(out, "")
|
||||
}
|
||||
|
||||
// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123
|
||||
var errLeadingInt = errors.New("units: bad [0-9]*") // never printed
|
||||
|
||||
// leadingInt consumes the leading [0-9]* from s.
|
||||
func leadingInt(s string) (x int64, rem string, err error) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
if x >= (1<<63-10)/10 {
|
||||
// overflow
|
||||
return 0, "", errLeadingInt
|
||||
}
|
||||
x = x*10 + int64(c) - '0'
|
||||
}
|
||||
return x, s[i:], nil
|
||||
}
|
||||
|
||||
func ParseUnit(s string, unitMap map[string]float64) (int64, error) {
|
||||
// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
|
||||
orig := s
|
||||
f := float64(0)
|
||||
neg := false
|
||||
|
||||
// Consume [-+]?
|
||||
if s != "" {
|
||||
c := s[0]
|
||||
if c == '-' || c == '+' {
|
||||
neg = c == '-'
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
// Special case: if all that is left is "0", this is zero.
|
||||
if s == "0" {
|
||||
return 0, nil
|
||||
}
|
||||
if s == "" {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
for s != "" {
|
||||
g := float64(0) // this element of the sequence
|
||||
|
||||
var x int64
|
||||
var err error
|
||||
|
||||
// The next character must be [0-9.]
|
||||
if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
// Consume [0-9]*
|
||||
pl := len(s)
|
||||
x, s, err = leadingInt(s)
|
||||
if err != nil {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
g = float64(x)
|
||||
pre := pl != len(s) // whether we consumed anything before a period
|
||||
|
||||
// Consume (\.[0-9]*)?
|
||||
post := false
|
||||
if s != "" && s[0] == '.' {
|
||||
s = s[1:]
|
||||
pl := len(s)
|
||||
x, s, err = leadingInt(s)
|
||||
if err != nil {
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
scale := 1.0
|
||||
for n := pl - len(s); n > 0; n-- {
|
||||
scale *= 10
|
||||
}
|
||||
g += float64(x) / scale
|
||||
post = pl != len(s)
|
||||
}
|
||||
if !pre && !post {
|
||||
// no digits (e.g. ".s" or "-.s")
|
||||
return 0, errors.New("units: invalid " + orig)
|
||||
}
|
||||
|
||||
// Consume unit.
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c == '.' || ('0' <= c && c <= '9') {
|
||||
break
|
||||
}
|
||||
}
|
||||
u := s[:i]
|
||||
s = s[i:]
|
||||
unit, ok := unitMap[u]
|
||||
if !ok {
|
||||
return 0, errors.New("units: unknown unit " + u + " in " + orig)
|
||||
}
|
||||
|
||||
f += g * unit
|
||||
}
|
||||
|
||||
if neg {
|
||||
f = -f
|
||||
}
|
||||
if f < float64(-1<<63) || f > float64(1<<63-1) {
|
||||
return 0, errors.New("units: overflow parsing unit")
|
||||
}
|
||||
return int64(f), nil
|
||||
}
|
||||
58
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
generated
vendored
Normal file
58
Godeps/_workspace/src/github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2011 Google 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 errorutil helps make better error messages.
|
||||
package errorutil
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HighlightBytePosition takes a reader and the location in bytes of a parse
|
||||
// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
|
||||
// and pretty-printed context around the error with an arrow indicating the exact
|
||||
// position of the syntax error.
|
||||
func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
|
||||
line = 1
|
||||
br := bufio.NewReader(f)
|
||||
lastLine := ""
|
||||
thisLine := new(bytes.Buffer)
|
||||
for n := int64(0); n < pos; n++ {
|
||||
b, err := br.ReadByte()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if b == '\n' {
|
||||
lastLine = thisLine.String()
|
||||
thisLine.Reset()
|
||||
line++
|
||||
col = 1
|
||||
} else {
|
||||
col++
|
||||
thisLine.WriteByte(b)
|
||||
}
|
||||
}
|
||||
if line > 1 {
|
||||
highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
|
||||
}
|
||||
highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
|
||||
highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user