This repository has been archived by the owner on Feb 24, 2020. It is now read-only.
/
stage1.go
98 lines (90 loc) · 2.82 KB
/
stage1.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2016 The rkt Authors
//
// 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"
"net/url"
"path/filepath"
"sort"
"strings"
)
type stage1V1JsonParser struct{}
type stage1V1 struct {
Name string `json:"name"`
Version string `json:"version"`
Location string `json:"location"`
}
var (
allowedSchemes = map[string]struct{}{
"file": {},
"docker": {},
"http": {},
"https": {},
}
)
func init() {
addParser("stage1", "v1", &stage1V1JsonParser{})
registerSubDir("stage1.d", []string{"stage1"})
}
func (p *stage1V1JsonParser) parse(config *Config, raw []byte) error {
var stage1 stage1V1
if err := json.Unmarshal(raw, &stage1); err != nil {
return err
}
if err := p.validateStage1V1(&stage1); err != nil {
return fmt.Errorf("invalid stage1 configuration: %v", err)
}
// At this point either both name and version are specified or
// neither. The same goes for data in Config.
if stage1.Name != "" {
if config.Stage1.Name != "" {
return fmt.Errorf("name and version of a default stage1 image are already specified")
}
config.Stage1.Name = stage1.Name
config.Stage1.Version = stage1.Version
}
if stage1.Location != "" {
if config.Stage1.Location != "" {
return fmt.Errorf("location of a default stage1 image is already specified")
}
config.Stage1.Location = stage1.Location
}
return nil
}
func (p *stage1V1JsonParser) validateStage1V1(stage1 *stage1V1) error {
if stage1.Name == "" && stage1.Version != "" {
return fmt.Errorf("default stage1 image version specified, but name is missing")
}
if stage1.Name != "" && stage1.Version == "" {
return fmt.Errorf("default stage1 image name specified, but version is missing")
}
if stage1.Location != "" {
if !filepath.IsAbs(stage1.Location) {
url, err := url.Parse(stage1.Location)
if err != nil {
return fmt.Errorf("default stage1 image location is an invalid URL: %v", err)
}
if url.Scheme == "" {
return fmt.Errorf("default stage1 image location is either a relative path or a URL without scheme")
}
if _, ok := allowedSchemes[url.Scheme]; !ok {
schemes := toArray(allowedSchemes)
sort.Strings(schemes)
return fmt.Errorf("default stage1 image location URL has invalid scheme %q, allowed schemes are %q", url.Scheme, strings.Join(schemes, `", "`))
}
}
}
return nil
}