@@ -14,6 +14,7 @@ import (
14
14
"github.com/openshift/installer/pkg/asset/installconfig"
15
15
"github.com/openshift/installer/pkg/asset/machines/aws"
16
16
"github.com/openshift/installer/pkg/asset/machines/libvirt"
17
+ "github.com/openshift/installer/pkg/asset/machines/machineconfig"
17
18
"github.com/openshift/installer/pkg/asset/machines/openstack"
18
19
"github.com/openshift/installer/pkg/asset/rhcos"
19
20
awstypes "github.com/openshift/installer/pkg/types/aws"
@@ -22,6 +23,7 @@ import (
22
23
nonetypes "github.com/openshift/installer/pkg/types/none"
23
24
openstacktypes "github.com/openshift/installer/pkg/types/openstack"
24
25
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
26
+ mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
25
27
"github.com/pkg/errors"
26
28
"k8s.io/apimachinery/pkg/runtime"
27
29
"k8s.io/apimachinery/pkg/runtime/serializer"
@@ -33,17 +35,23 @@ import (
33
35
34
36
// Master generates the machines for the `master` machine pool.
35
37
type Master struct {
36
- FileList []* asset.File
38
+ UserDataFile * asset.File
39
+ MachineConfigFiles []* asset.File
40
+ MachineFiles []* asset.File
37
41
}
38
42
39
- var (
43
+ const (
40
44
directory = "openshift"
41
45
42
- // MasterMachineFileName is the format string for constucting the master Machine filenames.
43
- MasterMachineFileName = "99_openshift-cluster-api_master-machines-%s.yaml"
46
+ // masterMachineFileName is the format string for constucting the master Machine filenames.
47
+ masterMachineFileName = "99_openshift-cluster-api_master-machines-%s.yaml"
48
+
49
+ // masterUserDataFileName is the filename used for the master user-data secret.
50
+ masterUserDataFileName = "99_openshift-cluster-api_master-user-data-secret.yaml"
51
+ )
44
52
45
- // MasterUserDataFileName is the filename used for the master user-data secret.
46
- MasterUserDataFileName = "99_openshift-cluster-api_master-user-data-secret.yaml"
53
+ var (
54
+ masterMachineFileNamePattern = fmt . Sprintf ( masterMachineFileName , "*" )
47
55
48
56
_ asset.WritableAsset = (* Master )(nil )
49
57
)
@@ -82,10 +90,10 @@ func (m *Master) Generate(dependencies asset.Parents) error {
82
90
mign := & machine.Master {}
83
91
dependencies .Get (clusterID , installconfig , rhcosImage , mign )
84
92
85
- var err error
86
- machines := []machineapi.Machine {}
87
93
ic := installconfig .Config
88
94
pool := ic .ControlPlane
95
+ var err error
96
+ machines := []machineapi.Machine {}
89
97
switch ic .Platform .Name () {
90
98
case awstypes .Name :
91
99
mpool := defaultAWSMachinePoolPlatform ()
@@ -138,71 +146,80 @@ func (m *Master) Generate(dependencies asset.Parents) error {
138
146
return errors .Wrap (err , "failed to create user-data secret for master machines" )
139
147
}
140
148
141
- m .FileList = [] * asset.File { {
142
- Filename : filepath .Join (directory , MasterUserDataFileName ),
149
+ m .UserDataFile = & asset.File {
150
+ Filename : filepath .Join (directory , masterUserDataFileName ),
143
151
Data : data ,
144
- }}
152
+ }
145
153
146
- count := len (machines )
147
- if count == 0 {
148
- return errors .New ("at least one master machine must be configured" )
154
+ machineConfigs := []* mcfgv1.MachineConfig {}
155
+ m .MachineConfigFiles , err = machineconfig .Manifests (machineConfigs , "master" , directory )
156
+ if err != nil {
157
+ return errors .Wrap (err , "failed to create MachineConfig manifests for master machines" )
149
158
}
150
159
151
- padFormat := fmt .Sprintf ("%%0%dd" , len (fmt .Sprintf ("%d" , count )))
160
+ m .MachineFiles = make ([]* asset.File , len (machines ))
161
+ padFormat := fmt .Sprintf ("%%0%dd" , len (fmt .Sprintf ("%d" , len (machines ))))
152
162
for i , machine := range machines {
153
163
data , err := yaml .Marshal (machine )
154
164
if err != nil {
155
165
return errors .Wrapf (err , "marshal master %d" , i )
156
166
}
157
167
158
168
padded := fmt .Sprintf (padFormat , i )
159
- m .FileList = append ( m . FileList , & asset.File {
160
- Filename : filepath .Join (directory , fmt .Sprintf (MasterMachineFileName , padded )),
169
+ m .MachineFiles [ i ] = & asset.File {
170
+ Filename : filepath .Join (directory , fmt .Sprintf (masterMachineFileName , padded )),
161
171
Data : data ,
162
- })
172
+ }
163
173
}
164
174
165
175
return nil
166
176
}
167
177
168
178
// Files returns the files generated by the asset.
169
179
func (m * Master ) Files () []* asset.File {
170
- return m .FileList
180
+ files := make ([]* asset.File , 0 , 1 + len (m .MachineConfigFiles )+ len (m .MachineFiles ))
181
+ if m .UserDataFile != nil {
182
+ files = append (files , m .UserDataFile )
183
+ }
184
+ files = append (files , m .MachineConfigFiles ... )
185
+ files = append (files , m .MachineFiles ... )
186
+ return files
171
187
}
172
188
173
189
// Load reads the asset files from disk.
174
190
func (m * Master ) Load (f asset.FileFetcher ) (found bool , err error ) {
175
- file , err := f .FetchByName (filepath .Join (directory , MasterUserDataFileName ))
191
+ file , err := f .FetchByName (filepath .Join (directory , masterUserDataFileName ))
176
192
if err != nil {
177
193
if os .IsNotExist (err ) {
178
194
return false , nil
179
195
}
180
196
return false , err
181
197
}
182
- m .FileList = [] * asset. File { file }
198
+ m .UserDataFile = file
183
199
184
- fileList , err := f .FetchByPattern (filepath .Join (directory , fmt .Sprintf (MasterMachineFileName , "*" )))
200
+ m .MachineConfigFiles , err = machineconfig .Load (f , "master" , directory )
201
+ if err != nil {
202
+ return true , err
203
+ }
204
+
205
+ fileList , err := f .FetchByPattern (filepath .Join (directory , masterMachineFileNamePattern ))
185
206
if err != nil {
186
207
return true , err
187
208
}
188
209
189
210
if len (fileList ) == 0 {
190
- return true , errors .Errorf ("master machine manifests are required if you also provide %s" , file .Filename )
211
+ return true , errors .Errorf ("master machine manifests are required if you also provide %s" , m . UserDataFile .Filename )
191
212
}
192
213
193
- m .FileList = append ( m . FileList , fileList ... )
214
+ m .MachineFiles = fileList
194
215
return true , nil
195
216
}
196
217
197
218
// Machines returns master Machine manifest YAML.
198
219
func (m * Master ) Machines () [][]byte {
199
- machines := [][]byte {}
200
- userData := filepath .Join (directory , MasterUserDataFileName )
201
- for _ , file := range m .FileList {
202
- if file .Filename == userData {
203
- continue
204
- }
205
- machines = append (machines , file .Data )
220
+ machines := make ([][]byte , len (m .MachineFiles ))
221
+ for i , file := range m .MachineFiles {
222
+ machines [i ] = file .Data
206
223
}
207
224
return machines
208
225
}
@@ -220,9 +237,9 @@ func (m *Master) StructuredMachines() ([]machineapi.Machine, error) {
220
237
)
221
238
222
239
machines := []machineapi.Machine {}
223
- for i , data := range m .Machines () {
240
+ for i , file := range m .MachineFiles {
224
241
machine := & machineapi.Machine {}
225
- err := yaml .Unmarshal (data , & machine )
242
+ err := yaml .Unmarshal (file . Data , & machine )
226
243
if err != nil {
227
244
return machines , errors .Wrapf (err , "unmarshal master %d" , i )
228
245
}
@@ -238,3 +255,23 @@ func (m *Master) StructuredMachines() ([]machineapi.Machine, error) {
238
255
239
256
return machines , nil
240
257
}
258
+
259
+ // IsMasterManifest tests whether a file is a manifest that belongs to the
260
+ // Master Machines asset.
261
+ func IsMasterManifest (file * asset.File ) bool {
262
+ if filepath .Dir (file .Filename ) != directory {
263
+ return false
264
+ }
265
+ filename := filepath .Base (file .Filename )
266
+ if filename == masterUserDataFileName {
267
+ return true
268
+ }
269
+ if machineconfig .IsManifest ("master" , filename ) {
270
+ return true
271
+ }
272
+ if matched , err := filepath .Match (masterMachineFileNamePattern , filename ); err != nil {
273
+ panic ("bad format for master machine file name pattern" )
274
+ } else {
275
+ return matched
276
+ }
277
+ }
0 commit comments