Skip to content

Commit

Permalink
feat: provide MountStatus resource for system partition mounts
Browse files Browse the repository at this point in the history
Fixes #4133

This is pretty limited resource, as it covers only system mounts, but
this is all we need for KubeSpan for now. More complete solution should
probably involve COSIfying whole mount subsystem.

Example:

```
$ talosctl -n 172.20.0.2 get mounts
NODE         NAMESPACE   TYPE          ID          VERSION   SOURCE      TARGET          FILESYSTEM TYPE
172.20.0.2   runtime     MountStatus   EPHEMERAL   1         /dev/vda6   /var            xfs
172.20.0.2   runtime     MountStatus   STATE       1         /dev/vda5   /system/state   xfs
```

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
  • Loading branch information
smira committed Aug 25, 2021
1 parent 950f122 commit 85cda1b
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func NewState() (*State, error) {
&perf.Memory{},
&runtime.KernelParamSpec{},
&runtime.KernelParamStatus{},
&runtime.MountStatus{},
&secrets.API{},
&secrets.Etcd{},
&secrets.Kubernetes{},
Expand Down
17 changes: 17 additions & 0 deletions internal/pkg/mount/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package mount

import (
"context"
"fmt"
"os"
"sync"
Expand All @@ -19,6 +20,8 @@ import (
"github.com/talos-systems/talos/internal/pkg/partition"
"github.com/talos-systems/talos/pkg/machinery/config"
"github.com/talos-systems/talos/pkg/machinery/constants"
runtimeres "github.com/talos-systems/talos/pkg/resources/runtime"
"github.com/talos-systems/talos/pkg/resources/v1alpha1"
)

var (
Expand Down Expand Up @@ -203,6 +206,16 @@ func SystemPartitionMount(r runtime.Runtime, label string, opts ...Option) (err
return err
}

// record mount as the resources
mountStatus := runtimeres.NewMountStatus(v1alpha1.NamespaceName, label)
mountStatus.TypedSpec().Source = mountpoint.Source()
mountStatus.TypedSpec().Target = mountpoint.Target()
mountStatus.TypedSpec().FilesystemType = mountpoint.Fstype()

if err = r.State().V1Alpha2().Resources().Create(context.Background(), mountStatus); err != nil {
return fmt.Errorf("error creating mount status resource: %w", err)
}

mountpointsMutex.Lock()
defer mountpointsMutex.Unlock()

Expand All @@ -226,6 +239,10 @@ func SystemPartitionUnmount(r runtime.Runtime, label string) (err error) {
return err
}

if err = r.State().V1Alpha2().Resources().Destroy(context.Background(), runtimeres.NewMountStatus(v1alpha1.NamespaceName, label).Metadata()); err != nil {
return fmt.Errorf("error destroying mount status resource: %w", err)
}

mountpointsMutex.Lock()
delete(mountpoints, label)
mountpointsMutex.Unlock()
Expand Down
91 changes: 91 additions & 0 deletions pkg/resources/runtime/mount_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package runtime

import (
"fmt"

"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
)

// MountStatusType is type of Mount resource.
const MountStatusType = resource.Type("MountStatuses.runtime.talos.dev")

// MountStatus resource holds defined sysctl flags status.
type MountStatus struct {
md resource.Metadata
spec MountStatusSpec
}

// MountStatusSpec describes status of the defined sysctls.
type MountStatusSpec struct {
Source string `yaml:"source"`
Target string `yaml:"target"`
FilesystemType string `yaml:"filesystemType"`
Options []string `yaml:"options"`
}

// NewMountStatus initializes a MountStatus resource.
func NewMountStatus(namespace resource.Namespace, id resource.ID) *MountStatus {
r := &MountStatus{
md: resource.NewMetadata(namespace, MountStatusType, id, resource.VersionUndefined),
spec: MountStatusSpec{},
}

r.md.BumpVersion()

return r
}

// Metadata implements resource.Resource.
func (r *MountStatus) Metadata() *resource.Metadata {
return &r.md
}

// Spec implements resource.Resource.
func (r *MountStatus) Spec() interface{} {
return r.spec
}

func (r *MountStatus) String() string {
return fmt.Sprintf("runtime.MountStatus.(%q)", r.md.ID())
}

// DeepCopy implements resource.Resource.
func (r *MountStatus) DeepCopy() resource.Resource {
return &MountStatus{
md: r.md,
spec: r.spec,
}
}

// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (r *MountStatus) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MountStatusType,
Aliases: []resource.Type{"Mounts"},
DefaultNamespace: NamespaceName,
PrintColumns: []meta.PrintColumn{
{
Name: "Source",
JSONPath: `{.source}`,
},
{
Name: "Target",
JSONPath: `{.target}`,
},
{
Name: "Filesystem Type",
JSONPath: `{.filesystemType}`,
},
},
}
}

// TypedSpec allows to access the MountStatusSpec with the proper type.
func (r *MountStatus) TypedSpec() *MountStatusSpec {
return &r.spec
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestRegisterResource(t *testing.T) {
for _, resource := range []resource.Resource{
&runtime.KernelParamSpec{},
&runtime.KernelParamStatus{},
&runtime.MountStatus{},
} {
assert.NoError(t, resourceRegistry.Register(ctx, resource))
}
Expand Down

0 comments on commit 85cda1b

Please sign in to comment.