Skip to content

Commit

Permalink
Merge pull request #2940 from ggiguash/cluster_id
Browse files Browse the repository at this point in the history
USHIFT-2090: Introduce cluster-id file creation on MicroShift startup
  • Loading branch information
openshift-merge-bot[bot] committed Feb 5, 2024
2 parents c94bf3e + f9e7df2 commit 524e9af
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 2 deletions.
21 changes: 19 additions & 2 deletions docs/user/debugging_tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,27 @@ metadata:

## Checking the LVMS Version

Like the MicroShift version, the LVM version is available via a configmap. To get the version, run:
Like the MicroShift version, the LVM version is available via a configmap.
To get the version, run the following command.

```bash
$ oc get configmap -n kube-public lvms-version -ojsonpath='{.data.version}'
$ oc get configmap -n kube-public lvms-version -o jsonpath='{.data.version}'
```

## Checking the MicroShift Cluster ID

MicroShift uses the `kube-system` namespace metadata UID value as a unique cluster identifier.
To get the cluster ID, run the following command.

```bash
$ oc get namespaces kube-system -o jsonpath='{.metadata.uid}'
```

If the cluster is not running, examine the `/var/lib/microshift/cluster-id` file contents to
get the cluster ID.

```bash
$ sudo cat /var/lib/microshift/cluster-id
```

## Generating an SOS Report
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ func RunMicroshift(cfg *config.Config) error {
util.Must(m.AddService(node.NewKubeletServer(cfg)))
util.Must(m.AddService(loadbalancerservice.NewLoadbalancerServiceController(cfg)))
util.Must(m.AddService(controllers.NewKubeStorageVersionMigrator(cfg)))
util.Must(m.AddService(controllers.NewClusterID(cfg)))

// Storing and clearing the env, so other components don't send the READY=1 until MicroShift is fully ready
notifySocket := os.Getenv("NOTIFY_SOCKET")
Expand Down
99 changes: 99 additions & 0 deletions pkg/controllers/clusterid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
Copyright © 2024 MicroShift Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers

import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/openshift/microshift/pkg/config"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog/v2"
)

type ClusterID struct {
cfg *config.Config
}

func NewClusterID(cfg *config.Config) *ClusterID {
s := &ClusterID{}
s.cfg = cfg
return s
}

func (s *ClusterID) Name() string { return "cluster-id-manager" }
func (s *ClusterID) Dependencies() []string {
return []string{"kube-apiserver"}
}

func (s *ClusterID) Run(ctx context.Context, ready chan<- struct{}, stopped chan<- struct{}) error {
defer close(stopped)
defer close(ready)

// Read the 'kube-system' namespace attributes
restConfig, err := clientcmd.BuildConfigFromFlags("", s.cfg.KubeConfigPath(config.KubeAdmin))
if err != nil {
return fmt.Errorf("failed to build kubeconfig admin path: %v", err)
}
coreClient := clientv1.NewForConfigOrDie(rest.AddUserAgent(restConfig, "core-agent"))
namespace, err := coreClient.Namespaces().Get(ctx, "kube-system", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("failed to read 'kube-system' namespace attributes: %v", err)
}

// Use the 'kube-system' namespace metadata UID as the MicroShift Cluster ID
clusterID := string(namespace.ObjectMeta.UID)
// Write <config.DataDir>/cluster-id file if it does not already exist
// or has inconsistent contents
err = initClusterIDFile(clusterID)
if err != nil {
return fmt.Errorf("failed to initialize cluster ID file: %v", err)
}
// Log the cluster ID
klog.Infof("MicroShift Cluster ID: %v", clusterID)

return ctx.Err()
}

func initClusterIDFile(clusterID string) error {
// The location of the cluster ID file
fileName := filepath.Join(config.DataDir, "cluster-id")

// Read and verify the cluster ID file if it already exists,
// logging a warning if the cluster ID is inconsistent
data, err := os.ReadFile(fileName)
if err != nil && !os.IsNotExist(err) {
// File exists, but cannot be read
return err
}
if len(data) > 0 {
if string(data) == clusterID {
// Consistent cluster ID file exists
return nil
}
klog.Warningf("Overwriting an inconsistent MicroShift Cluster ID '%v' in '%v' file", string(data), fileName)
}

// Write a new cluster ID file
klog.Infof("Writing MicroShift Cluster ID '%v' to '%v'", clusterID, fileName)
return os.WriteFile(fileName, []byte(clusterID), 0400)
}
92 changes: 92 additions & 0 deletions test/suites/osconfig/clusterid.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
*** Settings ***
Documentation Tests verifying MicroShift cluster ID functionality
Resource ../../resources/microshift-host.resource
Resource ../../resources/microshift-process.resource
Resource ../../resources/oc.resource
Resource ../../resources/ostree-health.resource

Suite Setup Setup
Suite Teardown Teardown

Test Tags restart slow


*** Variables ***
${CLUSTERID_FILE} /var/lib/microshift/cluster-id
${CLUSTERID_NS} kube-system


*** Test Cases ***
Verify Cluster ID Change For New Database
[Documentation] Verify that cluster ID changes after MicroShift
... database is cleaned and service restarted
${old_nid}= Get MicroShift Cluster ID From Namespace
${old_fid}= Get MicroShift Cluster ID From File
Create New MicroShift Cluster
${new_nid}= Get MicroShift Cluster ID From Namespace
${new_fid}= Get MicroShift Cluster ID From File

Should Be Equal As Strings ${old_nid} ${old_fid}
Should Be Equal As Strings ${new_nid} ${new_fid}

Should Not Be Equal As Strings ${old_nid} ${new_nid}
Should Not Be Equal As Strings ${old_fid} ${new_fid}

Verify Inconsistent Cluster ID Recovery
[Documentation] Verify that cluster ID is correctly rewritten on the
... service restart after manual tampering by a user.
Tamper With Cluster ID File
Restart MicroShift

${nid}= Get MicroShift Cluster ID From Namespace
${fid}= Get MicroShift Cluster ID From File
Should Be Equal As Strings ${nid} ${fid}


*** Keywords ***
Setup
[Documentation] Set up all of the tests in this suite
Check Required Env Variables
Login MicroShift Host
Setup Kubeconfig

Teardown
[Documentation] Test suite teardown
Remove Kubeconfig
Logout MicroShift Host

Create New MicroShift Cluster
[Documentation] Clean the database and restart MicroShift service.
Cleanup MicroShift --all --keep-images
Enable MicroShift
Start MicroShift
Setup Kubeconfig
Restart Greenboot And Wait For Success

Get MicroShift Cluster ID From File
[Documentation] Read and return the cluster ID from the file.
${stdout} ${rc}= Execute Command
... cat ${CLUSTERID_FILE}
... sudo=True return_rc=True return_stdout=True
Should Be Equal As Integers 0 ${rc}

Should Not Be Empty ${stdout}
RETURN ${stdout}

Get MicroShift Cluster ID From Namespace
[Documentation] Read and return the cluster ID from the kube-system namespace.
${clusterid}= Oc Get Jsonpath namespaces ${CLUSTERID_NS} ${CLUSTERID_NS} .metadata.uid

Should Not Be Empty ${clusterid}
RETURN ${clusterid}

Tamper With Cluster ID File
[Documentation] Append invalid characters to the cluster ID file.
${stdout} ${stderr} ${rc}= Execute Command
... sed -i '$ s/$/123/' ${CLUSTERID_FILE}
... sudo=True return_rc=True return_stdout=True return_stderr=True

Should Be Equal As Integers 0 ${rc}

0 comments on commit 524e9af

Please sign in to comment.