-
Notifications
You must be signed in to change notification settings - Fork 407
/
bootstrap.go
150 lines (133 loc) · 3.75 KB
/
bootstrap.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package bootstrap
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/ghodss/yaml"
"github.com/golang/glog"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
kscheme "k8s.io/client-go/kubernetes/scheme"
"github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
"github.com/openshift/machine-config-operator/pkg/controller/render"
"github.com/openshift/machine-config-operator/pkg/controller/template"
"github.com/openshift/machine-config-operator/pkg/generated/clientset/versioned/scheme"
)
// Bootstrap defines boostrap mode for Machine Config Controller
type Bootstrap struct {
// dir used by template controller to render internal machineconfigs.
templatesDir string
// dir used to read pools and user defined machineconfigs.
manifestDir string
// pull secret file
pullSecretFile string
}
// New returns controller for bootstrap
func New(templatesDir, manifestDir, pullSecretFile string) *Bootstrap {
return &Bootstrap{
templatesDir: templatesDir,
manifestDir: manifestDir,
pullSecretFile: pullSecretFile,
}
}
// Run runs boostrap for Machine Config Controller
// It writes all the assets to destDir
func (b *Bootstrap) Run(destDir string) error {
infos, err := ioutil.ReadDir(b.manifestDir)
if err != nil {
return err
}
psfraw, err := ioutil.ReadFile(b.pullSecretFile)
if err != nil {
return err
}
psraw, err := getPullSecretFromSecret(psfraw)
if err != nil {
return err
}
var cconfig *v1.ControllerConfig
var pools []*v1.MachineConfigPool
var configs []*v1.MachineConfig
for _, info := range infos {
if info.IsDir() {
continue
}
path := filepath.Join(b.manifestDir, info.Name())
raw, err := ioutil.ReadFile(path)
if err != nil {
return err
}
obji, err := runtime.Decode(scheme.Codecs.UniversalDecoder(v1.SchemeGroupVersion), raw)
if err != nil {
glog.V(4).Infof("skipping path because of error: %v", err)
// don't care
continue
}
switch obj := obji.(type) {
case *v1.MachineConfigPool:
pools = append(pools, obj)
case *v1.MachineConfig:
configs = append(configs, obj)
case *v1.ControllerConfig:
cconfig = obj
default:
glog.Infof("skipping %q %T", path, obji)
}
}
if cconfig == nil {
return fmt.Errorf("error: no controllerconfig found in dir: %q", destDir)
}
iconfigs, err := template.RunBootstrap(b.templatesDir, cconfig, psraw)
if err != nil {
return err
}
configs = append(configs, iconfigs...)
fpools, gconfigs, err := render.RunBootstrap(pools, configs)
if err != nil {
return err
}
poolsdir := filepath.Join(destDir, "machine-pools")
if err := os.MkdirAll(poolsdir, 0664); err != nil {
return err
}
for _, p := range fpools {
b, err := yaml.Marshal(p)
if err != nil {
return err
}
path := filepath.Join(poolsdir, fmt.Sprintf("%s.yaml", p.Name))
if err := ioutil.WriteFile(path, b, 0664); err != nil {
return err
}
}
configdir := filepath.Join(destDir, "machine-configs")
if err := os.MkdirAll(configdir, 0664); err != nil {
return err
}
for _, c := range gconfigs {
b, err := yaml.Marshal(c)
if err != nil {
return err
}
path := filepath.Join(configdir, fmt.Sprintf("%s.yaml", c.Name))
if err := ioutil.WriteFile(path, b, 0664); err != nil {
return err
}
}
return nil
}
func getPullSecretFromSecret(sData []byte) ([]byte, error) {
obji, err := runtime.Decode(kscheme.Codecs.UniversalDecoder(corev1.SchemeGroupVersion), sData)
if err != nil {
return nil, err
}
s, ok := obji.(*corev1.Secret)
if !ok {
return nil, fmt.Errorf("expected *corev1.Secret found %T", obji)
}
if s.Type != corev1.SecretTypeDockerConfigJson {
return nil, fmt.Errorf("expected secret type %s found %s", corev1.SecretTypeDockerConfigJson, s.Type)
}
return s.Data[corev1.DockerConfigJsonKey], nil
}