Skip to content

Commit 03e0448

Browse files
Merge pull request openshift#7186 from rwsu/AGENT-558
AGENT-558 Generate unconfigured agent ignition
2 parents de6e407 + ef45b34 commit 03e0448

File tree

15 files changed

+1039
-126
lines changed

15 files changed

+1039
-126
lines changed

cmd/openshift-install/agent.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,20 @@ var (
100100
},
101101
}
102102

103-
agentTargets = []target{agentConfigTarget, agentManifestsTarget, agentImageTarget, agentPXEFilesTarget, agentConfigImageTarget}
103+
agentUnconfiguredIgnitionTarget = target{
104+
name: "Agent unconfigured ignition",
105+
command: &cobra.Command{
106+
Use: "unconfigured-ignition",
107+
Short: "Generates an agent ignition that excludes cluster configuration",
108+
Args: cobra.ExactArgs(0),
109+
Hidden: true,
110+
},
111+
assets: []asset.WritableAsset{
112+
&image.UnconfiguredIgnition{},
113+
},
114+
}
115+
116+
agentTargets = []target{agentConfigTarget, agentManifestsTarget, agentImageTarget, agentPXEFilesTarget, agentConfigImageTarget, agentUnconfiguredIgnitionTarget}
104117
)
105118

106119
func newAgentCreateCmd() *cobra.Command {

cmd/openshift-install/agent_internal_integration_test.go

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,12 @@ func runIntegrationTest(t *testing.T, testFolder string) {
105105
},
106106

107107
Cmds: map[string]func(*testscript.TestScript, bool, []string){
108-
"isocmp": isoCmp,
109-
"ignitionImgContains": ignitionImgContains,
110-
"configImgContains": configImgContains,
111-
"initrdImgContains": initrdImgContains,
108+
"isocmp": isoCmp,
109+
"ignitionImgContains": ignitionImgContains,
110+
"configImgContains": configImgContains,
111+
"initrdImgContains": initrdImgContains,
112+
"unconfiguredIgnContains": unconfiguredIgnContains,
113+
"unconfiguredIgnCmp": unconfiguredIgnCmp,
112114
},
113115
})
114116
}
@@ -155,6 +157,46 @@ func archiveFileNames(isoPath string) (string, string, error) {
155157
return "", "", errors.NotFound(fmt.Sprintf("ISO %s has unrecognized prefix", isoPath))
156158
}
157159

160+
// [!] ignitionContains `isoPath` `file` check if the specified file `file`
161+
// [!] unconfiguredIgnContains `file` check if the specified file `file`
162+
// is stored within the unconfigured ignition Storage Files.
163+
func unconfiguredIgnContains(ts *testscript.TestScript, neg bool, args []string) {
164+
if len(args) != 1 {
165+
ts.Fatalf("usage: unconfiguredIgnContains file")
166+
}
167+
ignitionStorageContains(ts, neg, []string{"unconfigured-agent.ign", args[0]})
168+
}
169+
170+
// [!] ignitionStorageContains `ignPath` `file` check if the specified file `file`
171+
// is stored within the ignition Storage Files.
172+
func ignitionStorageContains(ts *testscript.TestScript, neg bool, args []string) {
173+
if len(args) != 2 {
174+
ts.Fatalf("usage: ignitionStorageContains ignPath file")
175+
}
176+
177+
workDir := ts.Getenv("WORK")
178+
ignPath, eFilePath := args[0], args[1]
179+
ignPathAbs := filepath.Join(workDir, ignPath)
180+
181+
config, err := readIgnition(ts, ignPathAbs)
182+
ts.Check(err)
183+
184+
found := false
185+
for _, f := range config.Storage.Files {
186+
if f.Path == eFilePath {
187+
found = true
188+
}
189+
}
190+
191+
if !found && !neg {
192+
ts.Fatalf("%s does not contain %s", ignPath, eFilePath)
193+
}
194+
195+
if neg && found {
196+
ts.Fatalf("%s should not contain %s", ignPath, eFilePath)
197+
}
198+
}
199+
158200
// [!] isoCmp `isoPath` `isoFile` `expectedFile` check that the content of the file
159201
// `isoFile` - extracted from the ISO embedded configuration file referenced
160202
// by `isoPath` - matches the content of the local file `expectedFile`.
@@ -179,6 +221,53 @@ func isoCmp(ts *testscript.TestScript, neg bool, args []string) {
179221
eData, err := os.ReadFile(eFilePathAbs)
180222
ts.Check(err)
181223

224+
byteCompare(ts, neg, aData, eData, aFilePath, eFilePath)
225+
}
226+
227+
// [!] unconfiguredIgnCmp `fileInIgn` `expectedFile` check that the content
228+
// of the file `fileInIgn` extracted from the unconfigured ignition
229+
// configuration file matches the content of the local file `expectedFile`.
230+
func unconfiguredIgnCmp(ts *testscript.TestScript, neg bool, args []string) {
231+
if len(args) != 2 {
232+
ts.Fatalf("usage: iunconfiguredIgnCmp file1 file2")
233+
}
234+
argsNext := []string{"unconfigured-agent.ign", args[0], args[1]}
235+
ignitionStorageCmp(ts, neg, argsNext)
236+
}
237+
238+
// [!] ignitionStorageCmp `ignPath` `ignFile` `expectedFile` check that the content of the file
239+
// `ignFile` - extracted from the ignition configuration file referenced
240+
// by `ignPath` - matches the content of the local file `expectedFile`.
241+
func ignitionStorageCmp(ts *testscript.TestScript, neg bool, args []string) {
242+
if len(args) != 3 {
243+
ts.Fatalf("usage: ignitionStorageCmp ignPath file1 file2")
244+
}
245+
246+
workDir := ts.Getenv("WORK")
247+
ignPath, aFilePath, eFilePath := args[0], args[1], args[2]
248+
ignPathAbs := filepath.Join(workDir, ignPath)
249+
250+
config, err := readIgnition(ts, ignPathAbs)
251+
ts.Check(err)
252+
253+
aData, err := readFileFromIgnitionCfg(&config, aFilePath)
254+
ts.Check(err)
255+
256+
eFilePathAbs := filepath.Join(workDir, eFilePath)
257+
eData, err := os.ReadFile(eFilePathAbs)
258+
ts.Check(err)
259+
260+
byteCompare(ts, neg, aData, eData, aFilePath, eFilePath)
261+
}
262+
263+
func readIgnition(ts *testscript.TestScript, ignPath string) (config igntypes.Config, err error) {
264+
rawIgn, err := os.ReadFile(ignPath)
265+
ts.Check(err)
266+
err = json.Unmarshal(rawIgn, &config)
267+
return config, err
268+
}
269+
270+
func byteCompare(ts *testscript.TestScript, neg bool, aData, eData []byte, aFilePath, eFilePath string) {
182271
aText := string(aData)
183272
eText := string(eData)
184273

@@ -213,6 +302,20 @@ func readFileFromISO(isoPath, archiveFile, ignitionFile, nodePath string) ([]byt
213302
return config, nil
214303
}
215304

305+
func readFileFromIgnitionCfg(config *igntypes.Config, nodePath string) ([]byte, error) {
306+
for _, f := range config.Storage.Files {
307+
if f.Node.Path == nodePath {
308+
actualData, err := dataurl.DecodeString(*f.FileEmbedded1.Contents.Source)
309+
if err != nil {
310+
return nil, err
311+
}
312+
return actualData.Data, nil
313+
}
314+
}
315+
316+
return nil, errors.NotFound(nodePath)
317+
}
318+
216319
func extractArchiveFile(isoPath, archive, fileName string) ([]byte, error) {
217320
disk, err := diskfs.OpenWithMode(isoPath, diskfs.ReadOnly)
218321
if err != nil {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Verify a default configuration for the compact topology
2+
3+
exec openshift-install agent create unconfigured-ignition --dir $WORK
4+
5+
! stderr 'The rendezvous host IP \(node0 IP\) is 192.168.111.20'
6+
7+
exists $WORK/unconfigured-agent.ign
8+
! exists $WORK/auth/kubeconfig
9+
! exists $WORK/auth/kubeadmin-password
10+
! unconfiguredIgnContains /etc/assisted/manifests/agent-cluster-install.yaml
11+
! unconfiguredIgnContains /etc/assisted/manifests/cluster-deployment.yaml
12+
13+
-- install-config.yaml --
14+
apiVersion: v1
15+
baseDomain: test.metalkube.org
16+
controlPlane:
17+
name: master
18+
replicas: 3
19+
compute:
20+
- name: worker
21+
replicas: 0
22+
metadata:
23+
namespace: cluster0
24+
name: ostest
25+
networking:
26+
clusterNetwork:
27+
- cidr: 10.128.0.0/14
28+
hostPrefix: 23
29+
networkType: OVNKubernetes
30+
machineNetwork:
31+
- cidr: 192.168.111.0/24
32+
serviceNetwork:
33+
- 172.30.0.0/16
34+
platform:
35+
baremetal:
36+
apiVips:
37+
- 192.168.111.5
38+
ingressVips:
39+
- 192.168.111.4
40+
sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0=
41+
pullSecret: '{"auths": {"quay.io": {"auth": "c3VwZXItc2VjcmV0Cg=="}}}'
42+
43+
-- agent-config.yaml --
44+
apiVersion: v1alpha1
45+
metadata:
46+
name: ostest
47+
namespace: cluster0
48+
rendezvousIP: 192.168.111.20
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# The unconfigured ignition can be generated using
2+
# infraenv.yaml, pull-secret.yaml, cluster-image-set.yaml
3+
# and not using
4+
# install-config.yaml and agent-config.yaml.
5+
6+
exec openshift-install agent create unconfigured-ignition --dir $WORK
7+
8+
exists $WORK/unconfigured-agent.ign
9+
! exists $WORK/auth/kubeconfig
10+
! exists $WORK/auth/kubeadmin-password
11+
! unconfiguredIgnContains /etc/assisted/manifests/agent-cluster-install.yaml
12+
! unconfiguredIgnContains /etc/assisted/manifests/cluster-deployment.yaml
13+
unconfiguredIgnCmp /etc/assisted/manifests/cluster-image-set.yaml expected/cluster-image-set.yaml
14+
unconfiguredIgnCmp /etc/assisted/manifests/infraenv.yaml expected/infraenv.yaml
15+
unconfiguredIgnCmp /etc/assisted/manifests/pull-secret.yaml expected/pull-secret.yaml
16+
17+
-- cluster-manifests/infraenv.yaml --
18+
metadata:
19+
name: ostest
20+
namespace: cluster0
21+
spec:
22+
cpuArchitecture: x86_64
23+
pullSecretRef:
24+
name: ostest-pull-secret
25+
sshAuthorizedKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0=
26+
27+
-- cluster-manifests/pull-secret.yaml --
28+
apiVersion: v1
29+
kind: Secret
30+
metadata:
31+
name: ostest-pull-secret
32+
namespace: cluster0
33+
stringData:
34+
.dockerconfigjson: |-
35+
{
36+
"auths": {
37+
"quay.io": {
38+
"auth": "c3VwZXItc2VjcmV0Cg=="
39+
}
40+
}
41+
}
42+
43+
-- cluster-manifests/cluster-image-set.yaml --
44+
metadata:
45+
name: cluster0-image-set
46+
namespace: cluster0
47+
spec:
48+
releaseImage: registry.ci.openshift.org/origin/release:4.14
49+
50+
-- expected/cluster-image-set.yaml --
51+
metadata:
52+
name: cluster0-image-set
53+
namespace: cluster0
54+
spec:
55+
releaseImage: registry.ci.openshift.org/origin/release:4.14
56+
57+
-- expected/infraenv.yaml --
58+
metadata:
59+
name: ostest
60+
namespace: cluster0
61+
spec:
62+
cpuArchitecture: x86_64
63+
pullSecretRef:
64+
name: ostest-pull-secret
65+
sshAuthorizedKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0=
66+
67+
-- expected/pull-secret.yaml --
68+
apiVersion: v1
69+
kind: Secret
70+
metadata:
71+
creationTimestamp: null
72+
name: ostest-pull-secret
73+
namespace: cluster0
74+
stringData:
75+
.dockerconfigjson: |-
76+
{
77+
"auths": {
78+
"quay.io": {
79+
"auth": "c3VwZXItc2VjcmV0Cg=="
80+
}
81+
}
82+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Verify a default configuration for the compact topology
2+
3+
exec openshift-install agent create unconfigured-ignition --dir $WORK
4+
5+
! stderr 'The rendezvous host IP \(node0 IP\) is 192.168.111.20'
6+
7+
exists $WORK/unconfigured-agent.ign
8+
! exists $WORK/auth/kubeconfig
9+
! exists $WORK/auth/kubeadmin-password
10+
11+
! unconfiguredIgnContains /etc/assisted/manifests/agent-cluster-install.yaml
12+
! unconfiguredIgnContains /etc/assisted/manifests/cluster-deployment.yaml
13+
unconfiguredIgnCmp /etc/assisted/manifests/cluster-image-set.yaml expected/cluster-image-set.yaml
14+
unconfiguredIgnCmp /etc/assisted/manifests/infraenv.yaml expected/infraenv.yaml
15+
unconfiguredIgnCmp /etc/assisted/manifests/pull-secret.yaml expected/pull-secret.yaml
16+
17+
-- install-config.yaml --
18+
apiVersion: v1
19+
baseDomain: test.metalkube.org
20+
controlPlane:
21+
name: master
22+
replicas: 1
23+
compute:
24+
- name: worker
25+
replicas: 0
26+
metadata:
27+
namespace: cluster0
28+
name: ostest
29+
networking:
30+
clusterNetwork:
31+
- cidr: 10.128.0.0/14
32+
hostPrefix: 23
33+
networkType: OVNKubernetes
34+
machineNetwork:
35+
- cidr: 192.168.111.0/24
36+
serviceNetwork:
37+
- 172.30.0.0/16
38+
platform:
39+
none: {}
40+
sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0=
41+
pullSecret: '{"auths": {"quay.io": {"auth": "c3VwZXItc2VjcmV0Cg=="}}}'
42+
43+
-- agent-config.yaml --
44+
apiVersion: v1alpha1
45+
metadata:
46+
name: ostest
47+
namespace: cluster0
48+
rendezvousIP: 192.168.111.20
49+
50+
-- expected/cluster-image-set.yaml --
51+
metadata:
52+
creationTimestamp: null
53+
name: openshift-was not built correctly
54+
namespace: cluster0
55+
spec:
56+
releaseImage: registry.ci.openshift.org/origin/release:4.14
57+
status: {}
58+
-- expected/infraenv.yaml --
59+
metadata:
60+
creationTimestamp: null
61+
name: ostest
62+
namespace: cluster0
63+
spec:
64+
clusterRef:
65+
name: ostest
66+
namespace: cluster0
67+
cpuArchitecture: x86_64
68+
ipxeScriptType: ""
69+
nmStateConfigLabelSelector:
70+
matchLabels:
71+
infraenvs.agent-install.openshift.io: ostest
72+
pullSecretRef:
73+
name: ostest-pull-secret
74+
sshAuthorizedKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0=
75+
status:
76+
agentLabelSelector: {}
77+
bootArtifacts:
78+
initrd: ""
79+
ipxeScript: ""
80+
kernel: ""
81+
rootfs: ""
82+
debugInfo:
83+
eventsURL: ""
84+
-- expected/pull-secret.yaml --
85+
apiVersion: v1
86+
kind: Secret
87+
metadata:
88+
creationTimestamp: null
89+
name: ostest-pull-secret
90+
namespace: cluster0
91+
stringData:
92+
.dockerconfigjson: |-
93+
{
94+
"auths": {
95+
"quay.io": {
96+
"auth": "c3VwZXItc2VjcmV0Cg=="
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)