Skip to content

Commit facb1f0

Browse files
authored
Merge pull request #1581 from Nordix/lentzi90/e2e-log-collector
🌱 E2e: Implement LogCollector interface
2 parents 3897ea2 + 2b5a51f commit facb1f0

File tree

3 files changed

+131
-5
lines changed

3 files changed

+131
-5
lines changed

scripts/ci-e2e.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ fi
8686

8787
# Upload image for e2e clusterctl upgrade tests
8888
source "${REPO_ROOT}/hack/ci/${RESOURCE_TYPE}.sh"
89-
CONTAINER_ARCHIVE="${ARTIFACTS}/capo-e2e-image.tar"
89+
CONTAINER_ARCHIVE="/tmp/capo-e2e-image.tar"
9090
SSH_KEY="$(get_ssh_private_key_file)"
9191
SSH_ARGS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o PasswordAuthentication=no"
9292
CONTROLLER_IP=${CONTROLLER_IP:-"10.0.3.15"}

test/e2e/shared/common.go

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ import (
3131
. "github.com/onsi/ginkgo/v2"
3232
. "github.com/onsi/gomega"
3333
corev1 "k8s.io/api/core/v1"
34+
"k8s.io/apimachinery/pkg/types"
3435
"k8s.io/apimachinery/pkg/util/sets"
36+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
37+
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
3538
"sigs.k8s.io/cluster-api/test/framework"
3639
"sigs.k8s.io/cluster-api/test/framework/clusterctl"
3740
"sigs.k8s.io/cluster-api/util"
@@ -199,15 +202,15 @@ func dumpMachine(ctx context.Context, e2eCtx *E2EContext, machine infrav1.OpenSt
199202
},
200203
{
201204
title: "containerd-info",
202-
cmd: "crictl info",
205+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock info",
203206
},
204207
{
205208
title: "containerd-containers",
206-
cmd: "crictl ps",
209+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps",
207210
},
208211
{
209212
title: "containerd-pods",
210-
cmd: "crictl pods",
213+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock pods",
211214
},
212215
{
213216
title: "cloud-final",
@@ -262,3 +265,125 @@ func SetEnvVar(key, value string, private bool) {
262265
Logf("Setting environment variable: key=%s, value=%s", key, printableValue)
263266
_ = os.Setenv(key, value)
264267
}
268+
269+
// getOpenStackClusterFromMachine gets the OpenStackCluster that is related to the given machine.
270+
func getOpenStackClusterFromMachine(ctx context.Context, client client.Client, machine *clusterv1.Machine) (*infrav1.OpenStackCluster, error) {
271+
key := types.NamespacedName{
272+
Namespace: machine.Namespace,
273+
Name: machine.Spec.ClusterName,
274+
}
275+
cluster := &clusterv1.Cluster{}
276+
err := client.Get(ctx, key, cluster)
277+
if err != nil {
278+
return nil, err
279+
}
280+
281+
key = types.NamespacedName{
282+
Namespace: cluster.Spec.InfrastructureRef.Namespace,
283+
Name: cluster.Spec.InfrastructureRef.Name,
284+
}
285+
openStackCluster := &infrav1.OpenStackCluster{}
286+
err = client.Get(ctx, key, openStackCluster)
287+
return openStackCluster, err
288+
}
289+
290+
type OpenStackLogCollector struct {
291+
E2EContext E2EContext
292+
}
293+
294+
// CollectMachineLog gets logs for the OpenStack resources related to the given machine.
295+
func (o OpenStackLogCollector) CollectMachineLog(ctx context.Context, managementClusterClient client.Client, m *clusterv1.Machine, outputPath string) error {
296+
machineLogBase := path.Join(outputPath, "instances", m.Namespace, m.Name)
297+
metaLog := path.Join(machineLogBase, "instance.log")
298+
299+
if err := os.MkdirAll(filepath.Dir(metaLog), 0o750); err != nil {
300+
_, _ = fmt.Fprintf(GinkgoWriter, "couldn't create directory %q for file: %s\n", metaLog, err)
301+
}
302+
303+
f, err := os.OpenFile(metaLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
304+
if err != nil {
305+
_, _ = fmt.Fprintf(GinkgoWriter, "couldn't open file %q: %s\n", metaLog, err)
306+
return nil
307+
}
308+
defer f.Close()
309+
310+
openStackCluster, err := getOpenStackClusterFromMachine(ctx, managementClusterClient, m)
311+
if err != nil {
312+
return fmt.Errorf("error getting OpenStackCluster for Machine: %s", err)
313+
}
314+
315+
if len(m.Status.Addresses) < 1 {
316+
return fmt.Errorf("unable to get logs for machine since it has no address")
317+
}
318+
ip := m.Status.Addresses[0].Address
319+
320+
srvs, err := GetOpenStackServers(&o.E2EContext, openStackCluster, sets.New(m.Spec.InfrastructureRef.Name))
321+
if err != nil {
322+
return fmt.Errorf("cannot dump machines, could not get servers from OpenStack: %v", err)
323+
}
324+
if len(srvs) != 1 {
325+
return fmt.Errorf("expected exactly 1 server but got %d", len(srvs))
326+
}
327+
srv := srvs[m.Spec.InfrastructureRef.Name]
328+
329+
serverJSON, err := json.MarshalIndent(srv, "", " ")
330+
if err != nil {
331+
return fmt.Errorf("error marshalling server %v: %s", srv, err)
332+
}
333+
if err := os.WriteFile(path.Join(machineLogBase, "server.txt"), serverJSON, 0o600); err != nil {
334+
return fmt.Errorf("error writing server JSON %s: %s", serverJSON, err)
335+
}
336+
_, _ = fmt.Fprintf(f, "instance found: %q\n", srv.ID)
337+
338+
srvUser := o.E2EContext.E2EConfig.GetVariable(SSHUserMachine)
339+
executeCommands(
340+
ctx,
341+
o.E2EContext.Settings.ArtifactFolder,
342+
o.E2EContext.Settings.Debug,
343+
filepath.Dir(f.Name()),
344+
ip,
345+
openStackCluster.Status.Bastion.FloatingIP,
346+
srvUser,
347+
[]command{
348+
// don't do this for now, it just takes to long
349+
// {
350+
// title: "systemd",
351+
// cmd: "journalctl --no-pager --output=short-precise | grep -v 'audit:\\|audit\\['",
352+
// },
353+
{
354+
title: "kern",
355+
cmd: "journalctl --no-pager --output=short-precise -k",
356+
},
357+
{
358+
title: "containerd-info",
359+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock info",
360+
},
361+
{
362+
title: "containerd-containers",
363+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps",
364+
},
365+
{
366+
title: "containerd-pods",
367+
cmd: "crictl --runtime-endpoint unix:///run/containerd/containerd.sock pods",
368+
},
369+
{
370+
title: "cloud-final",
371+
cmd: "journalctl --no-pager -u cloud-final",
372+
},
373+
{
374+
title: "kubelet",
375+
cmd: "journalctl --no-pager -u kubelet.service",
376+
},
377+
{
378+
title: "containerd",
379+
cmd: "journalctl --no-pager -u containerd.service",
380+
},
381+
},
382+
)
383+
return nil
384+
}
385+
386+
// CollectMachinePoolLog is not yet implemented for the OpenStack provider.
387+
func (o OpenStackLogCollector) CollectMachinePoolLog(_ context.Context, _ client.Client, _ *expv1.MachinePool, _ string) error {
388+
return fmt.Errorf("not implemented")
389+
}

test/e2e/shared/suite.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ func AllNodesBeforeSuite(e2eCtx *E2EContext, data []byte) {
182182
e2eCtx.Settings.ArtifactFolder = conf.ArtifactFolder
183183
e2eCtx.Settings.ConfigPath = conf.ConfigPath
184184
e2eCtx.Environment.ClusterctlConfigPath = conf.ClusterctlConfigPath
185-
e2eCtx.Environment.BootstrapClusterProxy = framework.NewClusterProxy("bootstrap", conf.KubeconfigPath, e2eCtx.Environment.Scheme)
185+
withLogCollector := framework.WithMachineLogCollector(OpenStackLogCollector{E2EContext: *e2eCtx})
186+
e2eCtx.Environment.BootstrapClusterProxy = framework.NewClusterProxy("bootstrap", conf.KubeconfigPath, e2eCtx.Environment.Scheme, withLogCollector)
186187
e2eCtx.E2EConfig = &conf.E2EConfig
187188
e2eCtx.Settings.KubetestConfigFilePath = conf.KubetestConfigFilePath
188189
e2eCtx.Settings.UseCIArtifacts = conf.UseCIArtifacts

0 commit comments

Comments
 (0)