From ccf9a249cedc4382d52df2531f377fb7b0314c04 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Thu, 16 Jan 2020 15:03:39 +0100 Subject: [PATCH] pkg/server: save the bootstrap MC content This patch injects the current machine config served by the MCS into the ignition config to have it on disk for later comparisons. This isn't making any difference between bootstrap and cluster but I'm naming this commit with bootstrap as this will be extremely helpful as a stopgap to investigate installer & MCO drifts. By having the MC content on disk, if a drift happens, we can collect the MC with must-gather and just compare it with what the MCO in the cluster is generating. Signed-off-by: Antonio Murdaca --- pkg/server/bootstrap_server.go | 2 +- pkg/server/cluster_server.go | 2 +- pkg/server/server.go | 33 +++++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/pkg/server/bootstrap_server.go b/pkg/server/bootstrap_server.go index e00e0b2e5f..16db9d09f9 100644 --- a/pkg/server/bootstrap_server.go +++ b/pkg/server/bootstrap_server.go @@ -97,7 +97,7 @@ func (bsc *bootstrapServer) GetConfig(cr poolRequest) (*igntypes.Config, error) appenders := getAppenders(currConf, bsc.kubeconfigFunc, mc.Spec.OSImageURL) for _, a := range appenders { - if err := a(&mc.Spec.Config); err != nil { + if err := a(mc); err != nil { return nil, err } } diff --git a/pkg/server/cluster_server.go b/pkg/server/cluster_server.go index 0c27f72c05..56bee8c129 100644 --- a/pkg/server/cluster_server.go +++ b/pkg/server/cluster_server.go @@ -73,7 +73,7 @@ func (cs *clusterServer) GetConfig(cr poolRequest) (*igntypes.Config, error) { appenders := getAppenders(currConf, cs.kubeconfigFunc, mc.Spec.OSImageURL) for _, a := range appenders { - if err := a(&mc.Spec.Config); err != nil { + if err := a(mc); err != nil { return nil, err } } diff --git a/pkg/server/server.go b/pkg/server/server.go index de529b41bb..455caab041 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -17,6 +17,15 @@ const ( // of the KubeConfig file on the machine. defaultMachineKubeConfPath = "/etc/kubernetes/kubeconfig" + // machineConfigContentPath contains the raw machine-config content + // served by the MCS. This is extremely useful when debugging drifts + // between the installer and the MCO itself. + // This is different than /etc/machine-config-daemon/currentconfig written + // by the MCD but it's gonna be the same 99% of the time. The reason we + // need this is that on bootstrap + first install we don't have the MCD + // running and writing that file. + machineConfigContentPath = "/etc/mcs-machine-config-content.json" + // defaultFileSystem defines the default file system to be // used for writing the ignition files created by the // server. @@ -27,7 +36,7 @@ const ( type kubeconfigFunc func() (kubeconfigData []byte, rootCAData []byte, err error) // appenderFunc appends Config. -type appenderFunc func(*igntypes.Config) error +type appenderFunc func(*mcfgv1.MachineConfig) error // Server defines the interface that is implemented by different // machine config server implementations. @@ -38,11 +47,14 @@ type Server interface { func getAppenders(currMachineConfig string, f kubeconfigFunc, osimageurl string) []appenderFunc { appenders := []appenderFunc{ // append machine annotations file. - func(config *igntypes.Config) error { return appendNodeAnnotations(config, currMachineConfig) }, + func(mc *mcfgv1.MachineConfig) error { return appendNodeAnnotations(&mc.Spec.Config, currMachineConfig) }, // append pivot - func(config *igntypes.Config) error { return appendInitialPivot(config, osimageurl) }, + func(mc *mcfgv1.MachineConfig) error { return appendInitialPivot(&mc.Spec.Config, osimageurl) }, // append kubeconfig. - func(config *igntypes.Config) error { return appendKubeConfig(config, f) }, + func(mc *mcfgv1.MachineConfig) error { return appendKubeConfig(&mc.Spec.Config, f) }, + // append the machineconfig content + //nolint:gocritic + func(mc *mcfgv1.MachineConfig) error { return appendInitialMachineConfig(mc) }, } return appenders } @@ -92,6 +104,19 @@ WantedBy=multi-user.target return nil } +// appendInitialMachineConfig saves the full serialized MachineConfig that was served +// by the MCS when the node first booted. This currently is only used as a debugging aid +// in cases where there is unexpected "drift" between the initial bootstrap MC/Ignition and the one +// computed by the cluster. +func appendInitialMachineConfig(mc *mcfgv1.MachineConfig) error { + mcJSON, err := json.MarshalIndent(mc, "", " ") + if err != nil { + return err + } + appendFileToIgnition(&mc.Spec.Config, machineConfigContentPath, string(mcJSON)) + return nil +} + func appendKubeConfig(conf *igntypes.Config, f kubeconfigFunc) error { kcData, _, err := f() if err != nil {