chore: cleanup code

- Replace unsafe resource interface calls with type-safe versions.
- Remove unused parameter names.
- Minor changes.

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
Dmitriy Matrenichev 2024-11-04 20:58:54 +03:00
parent 61d363e1d0
commit cedabeddf7
No known key found for this signature in database
GPG Key ID: 94B473337258BFD5
103 changed files with 341 additions and 320 deletions

2
go.mod
View File

@ -141,7 +141,7 @@ require (
github.com/siderolabs/crypto v0.5.0 github.com/siderolabs/crypto v0.5.0
github.com/siderolabs/discovery-api v0.1.4 github.com/siderolabs/discovery-api v0.1.4
github.com/siderolabs/discovery-client v0.1.10 github.com/siderolabs/discovery-client v0.1.10
github.com/siderolabs/gen v0.6.1 github.com/siderolabs/gen v0.7.0
github.com/siderolabs/go-api-signature v0.3.6 github.com/siderolabs/go-api-signature v0.3.6
github.com/siderolabs/go-blockdevice v0.4.8 github.com/siderolabs/go-blockdevice v0.4.8
github.com/siderolabs/go-blockdevice/v2 v2.0.3 github.com/siderolabs/go-blockdevice/v2 v2.0.3

4
go.sum
View File

@ -638,8 +638,8 @@ github.com/siderolabs/discovery-api v0.1.4 h1:2fMEFSMiWaD1zDiBDY5md8VxItvL1rDQRS
github.com/siderolabs/discovery-api v0.1.4/go.mod h1:kaBy+G42v2xd/uAF/NIe383sjNTBE2AhxPTyi9SZI0s= github.com/siderolabs/discovery-api v0.1.4/go.mod h1:kaBy+G42v2xd/uAF/NIe383sjNTBE2AhxPTyi9SZI0s=
github.com/siderolabs/discovery-client v0.1.10 h1:bTAvFLiISSzVXyYL1cIgAz8cPYd9ZfvhxwdebgtxARA= github.com/siderolabs/discovery-client v0.1.10 h1:bTAvFLiISSzVXyYL1cIgAz8cPYd9ZfvhxwdebgtxARA=
github.com/siderolabs/discovery-client v0.1.10/go.mod h1:Ew1z07eyJwqNwum84IKYH4S649KEKK5WUmRW49HlXS8= github.com/siderolabs/discovery-client v0.1.10/go.mod h1:Ew1z07eyJwqNwum84IKYH4S649KEKK5WUmRW49HlXS8=
github.com/siderolabs/gen v0.6.1 h1:Mex6Q41Tlw3e+4cGvlju2x4UwULD5WMo/D82n7IxV0Y= github.com/siderolabs/gen v0.7.0 h1:uHAt3WD0dof28NHFuguWBbDokaXQraR/HyVxCLw2QCU=
github.com/siderolabs/gen v0.6.1/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ= github.com/siderolabs/gen v0.7.0/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ=
github.com/siderolabs/go-api-signature v0.3.6 h1:wDIsXbpl7Oa/FXvxB6uz4VL9INA9fmr3EbmjEZYFJrU= github.com/siderolabs/go-api-signature v0.3.6 h1:wDIsXbpl7Oa/FXvxB6uz4VL9INA9fmr3EbmjEZYFJrU=
github.com/siderolabs/go-api-signature v0.3.6/go.mod h1:hoH13AfunHflxbXfh+NoploqV13ZTDfQ1mQJWNVSW9U= github.com/siderolabs/go-api-signature v0.3.6/go.mod h1:hoH13AfunHflxbXfh+NoploqV13ZTDfQ1mQJWNVSW9U=
github.com/siderolabs/go-blockdevice v0.4.8 h1:KfdWvIx0Jft5YVuCsFIJFwjWEF1oqtzkgX9PeU9cX4c= github.com/siderolabs/go-blockdevice v0.4.8 h1:KfdWvIx0Jft5YVuCsFIJFwjWEF1oqtzkgX9PeU9cX4c=

View File

@ -16,7 +16,7 @@ require (
github.com/blang/semver/v4 v4.0.0 github.com/blang/semver/v4 v4.0.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/klauspost/compress v1.17.11 github.com/klauspost/compress v1.17.11
github.com/siderolabs/gen v0.6.1 github.com/siderolabs/gen v0.7.0
github.com/siderolabs/go-retry v0.3.3 github.com/siderolabs/go-retry v0.3.3
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
golang.org/x/sync v0.8.0 golang.org/x/sync v0.8.0

View File

@ -179,8 +179,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/siderolabs/gen v0.6.1 h1:Mex6Q41Tlw3e+4cGvlju2x4UwULD5WMo/D82n7IxV0Y= github.com/siderolabs/gen v0.7.0 h1:uHAt3WD0dof28NHFuguWBbDokaXQraR/HyVxCLw2QCU=
github.com/siderolabs/gen v0.6.1/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ= github.com/siderolabs/gen v0.7.0/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ=
github.com/siderolabs/go-retry v0.3.3 h1:zKV+S1vumtO72E6sYsLlmIdV/G/GcYSBLiEx/c9oCEg= github.com/siderolabs/go-retry v0.3.3 h1:zKV+S1vumtO72E6sYsLlmIdV/G/GcYSBLiEx/c9oCEg=
github.com/siderolabs/go-retry v0.3.3/go.mod h1:Ff/VGc7v7un4uQg3DybgrmOWHEmJ8BzZds/XNn/BqMI= github.com/siderolabs/go-retry v0.3.3/go.mod h1:Ff/VGc7v7un4uQg3DybgrmOWHEmJ8BzZds/XNn/BqMI=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=

View File

@ -11,7 +11,7 @@ require (
github.com/invopop/jsonschema v0.12.0 github.com/invopop/jsonschema v0.12.0
github.com/microcosm-cc/bluemonday v1.0.27 github.com/microcosm-cc/bluemonday v1.0.27
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/siderolabs/gen v0.6.1 github.com/siderolabs/gen v0.7.0
github.com/wk8/go-ordered-map/v2 v2.1.8 github.com/wk8/go-ordered-map/v2 v2.1.8
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
mvdan.cc/gofumpt v0.7.0 mvdan.cc/gofumpt v0.7.0

View File

@ -31,8 +31,8 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/siderolabs/gen v0.6.1 h1:Mex6Q41Tlw3e+4cGvlju2x4UwULD5WMo/D82n7IxV0Y= github.com/siderolabs/gen v0.7.0 h1:uHAt3WD0dof28NHFuguWBbDokaXQraR/HyVxCLw2QCU=
github.com/siderolabs/gen v0.6.1/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ= github.com/siderolabs/gen v0.7.0/go.mod h1:an3a2Y53O7kUjnnK8Bfu3gewtvnIOu5RTU6HalFtXQQ=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/unix4ever/yaml v0.0.0-20220527175918-f17b0f05cf2c h1:Vn6nVVu9MdOYvXPkJP83iX5jVIfvxFC9v9xIKb+DlaQ= github.com/unix4ever/yaml v0.0.0-20220527175918-f17b0f05cf2c h1:Vn6nVVu9MdOYvXPkJP83iX5jVIfvxFC9v9xIKb+DlaQ=

View File

@ -59,11 +59,11 @@ func (ctrl *LVMActivationController) Outputs() []controller.Output {
//nolint:gocyclo //nolint:gocyclo
func (ctrl *LVMActivationController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *LVMActivationController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
if ctrl.seenVolumes == nil { if ctrl.seenVolumes == nil {
ctrl.seenVolumes = make(map[string]struct{}) ctrl.seenVolumes = map[string]struct{}{}
} }
if ctrl.activatedVGs == nil { if ctrl.activatedVGs == nil {
ctrl.activatedVGs = make(map[string]struct{}) ctrl.activatedVGs = map[string]struct{}{}
} }
for { for {

View File

@ -49,7 +49,7 @@ func (ctrl *SystemDiskController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *SystemDiskController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *SystemDiskController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-r.EventCh(): case <-r.EventCh():

View File

@ -67,7 +67,7 @@ func partitionIdxMatch(devicePath string, partitionIdx int) cel.Expression {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *UserDiskConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *UserDiskConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-r.EventCh(): case <-r.EventCh():

View File

@ -132,7 +132,7 @@ func (ctrl *VolumeConfigController) convertEncryption(in cfg.Encryption, out *bl
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *VolumeConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *VolumeConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-r.EventCh(): case <-r.EventCh():

View File

@ -60,7 +60,7 @@ func (ctrl *KubernetesPushController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KubernetesPushController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubernetesPushController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
defer func() { defer func() {
if ctrl.kubernetesClient != nil { if ctrl.kubernetesClient != nil {
ctrl.kubernetesClient.Close() //nolint:errcheck ctrl.kubernetesClient.Close() //nolint:errcheck

View File

@ -113,7 +113,7 @@ func (ctrl *LocalAffiliateController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *LocalAffiliateController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *LocalAffiliateController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"go.uber.org/zap" "go.uber.org/zap"
@ -99,8 +100,8 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim
return fmt.Errorf("error caching node identity: %w", err) return fmt.Errorf("error caching node identity: %w", err)
} }
if err := r.Modify(ctx, cluster.NewIdentity(cluster.NamespaceName, cluster.LocalIdentity), func(r resource.Resource) error { if err := safe.WriterModify(ctx, r, cluster.NewIdentity(cluster.NamespaceName, cluster.LocalIdentity), func(r *cluster.Identity) error {
*r.(*cluster.Identity).TypedSpec() = localIdentity *r.TypedSpec() = localIdentity
return nil return nil
}); err != nil { }); err != nil {
@ -108,12 +109,12 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim
} }
// generate `/etc/machine-id` from node identity // generate `/etc/machine-id` from node identity
if err := r.Modify(ctx, files.NewEtcFileSpec(files.NamespaceName, "machine-id"), if err := safe.WriterModify(ctx, r, files.NewEtcFileSpec(files.NamespaceName, "machine-id"),
func(r resource.Resource) error { func(r *files.EtcFileSpec) error {
var err error var err error
r.(*files.EtcFileSpec).TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID() r.TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID()
r.(*files.EtcFileSpec).TypedSpec().Mode = 0o444 r.TypedSpec().Mode = 0o444
return err return err
}); err != nil { }); err != nil {

View File

@ -9,7 +9,6 @@ import (
"fmt" "fmt"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
@ -50,7 +49,7 @@ func (ctrl *MachineTypeController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *MachineTypeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MachineTypeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -69,8 +68,8 @@ func (ctrl *MachineTypeController) Run(ctx context.Context, r controller.Runtime
machineType = cfg.Config().Machine().Type() machineType = cfg.Config().Machine().Type()
} }
if err = r.Modify(ctx, config.NewMachineType(), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, config.NewMachineType(), func(r *config.MachineType) error {
r.(*config.MachineType).SetMachineType(machineType) r.SetMachineType(machineType)
return nil return nil
}); err != nil { }); err != nil {

View File

@ -49,7 +49,7 @@ func (ctrl *SeccompProfileController) Outputs() []controller.Output {
} }
// Run implements controller.StatsController interface. // Run implements controller.StatsController interface.
func (ctrl *SeccompProfileController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *SeccompProfileController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -51,7 +51,7 @@ func (ctrl *SeccompProfileFileController) Outputs() []controller.Output {
// Run implements controller.StatsController interface. // Run implements controller.StatsController interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *SeccompProfileFileController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *SeccompProfileFileController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
// initially, wait for /var to be mounted // initially, wait for /var to be mounted
if err := r.UpdateInputs([]controller.Input{ if err := r.UpdateInputs([]controller.Input{
{ {

View File

@ -57,7 +57,7 @@ func (ctrl *MemberController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *MemberController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MemberController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -42,7 +42,7 @@ type MemberSuite struct {
func (suite *MemberSuite) assertEtcdMember(member *etcd.Member) func() error { func (suite *MemberSuite) assertEtcdMember(member *etcd.Member) func() error {
return func() error { return func() error {
r, err := suite.State().Get(suite.Ctx(), member.Metadata()) r, err := ctest.Get[*etcd.Member](suite, member.Metadata())
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
return retry.ExpectedError(err) return retry.ExpectedError(err)
@ -51,7 +51,7 @@ func (suite *MemberSuite) assertEtcdMember(member *etcd.Member) func() error {
return err return err
} }
spec := r.(*etcd.Member).TypedSpec() spec := r.TypedSpec()
expectedSpec := member.TypedSpec() expectedSpec := member.TypedSpec()
suite.Require().Equal(expectedSpec.MemberID, spec.MemberID) suite.Require().Equal(expectedSpec.MemberID, spec.MemberID)

View File

@ -62,7 +62,7 @@ func (ctrl *PKIController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *PKIController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *PKIController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -67,7 +67,7 @@ func (ctrl *SpecController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *SpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *SpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -11,7 +11,7 @@ import (
"sort" "sort"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/siderolabs/talos/internal/pkg/toml" "github.com/siderolabs/talos/internal/pkg/toml"
@ -52,7 +52,7 @@ func (ctrl *CRIConfigPartsController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
if ctrl.CRIConfdPath == "" { if ctrl.CRIConfdPath == "" {
ctrl.CRIConfdPath = constants.CRIConfdPath ctrl.CRIConfdPath = constants.CRIConfdPath
} }
@ -77,9 +77,9 @@ func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runt
return err return err
} }
if err := r.Modify(ctx, files.NewEtcFileSpec(files.NamespaceName, constants.CRIConfig), if err := safe.WriterModify(ctx, r, files.NewEtcFileSpec(files.NamespaceName, constants.CRIConfig),
func(r resource.Resource) error { func(r *files.EtcFileSpec) error {
spec := r.(*files.EtcFileSpec).TypedSpec() spec := r.TypedSpec()
spec.Contents = out spec.Contents = out
spec.Mode = 0o600 spec.Mode = 0o600

View File

@ -13,7 +13,6 @@ import (
"path/filepath" "path/filepath"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
@ -62,7 +61,7 @@ func (ctrl *CRIRegistryConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
basePath := filepath.Join(constants.CRIConfdPath, "hosts") basePath := filepath.Join(constants.CRIConfdPath, "hosts")
shadowPath := filepath.Join(constants.SystemPath, basePath) shadowPath := filepath.Join(constants.SystemPath, basePath)
@ -113,9 +112,9 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R
criHosts = &containerd.HostsConfig{} criHosts = &containerd.HostsConfig{}
} }
if err := r.Modify(ctx, files.NewEtcFileSpec(files.NamespaceName, constants.CRIRegistryConfigPart), if err := safe.WriterModify(ctx, r, files.NewEtcFileSpec(files.NamespaceName, constants.CRIRegistryConfigPart),
func(r resource.Resource) error { func(r *files.EtcFileSpec) error {
spec := r.(*files.EtcFileSpec).TypedSpec() spec := r.TypedSpec()
spec.Contents = criRegistryContents spec.Contents = criRegistryContents
spec.Mode = 0o600 spec.Mode = 0o600

View File

@ -14,6 +14,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -72,13 +73,13 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
case <-r.EventCh(): case <-r.EventCh():
} }
list, err := r.List(ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined)) list, err := safe.ReaderList[*files.EtcFileSpec](ctx, r, resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined))
if err != nil { if err != nil {
return fmt.Errorf("error listing specs: %w", err) return fmt.Errorf("error listing specs: %w", err)
} }
// add finalizers for all live resources // add finalizers for all live resources
for _, res := range list.Items { for res := range list.All() {
if res.Metadata().Phase() != resource.PhaseRunning { if res.Metadata().Phase() != resource.PhaseRunning {
continue continue
} }
@ -90,8 +91,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
touchedIDs := make(map[resource.ID]struct{}) touchedIDs := make(map[resource.ID]struct{})
for _, item := range list.Items { for spec := range list.All() {
spec := item.(*files.EtcFileSpec) //nolint:errcheck,forcetypeassert
filename := spec.Metadata().ID() filename := spec.Metadata().ID()
_, mountExists := ctrl.bindMounts[filename] _, mountExists := ctrl.bindMounts[filename]
@ -137,8 +137,8 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
return fmt.Errorf("error updating %q: %w", dst, err) return fmt.Errorf("error updating %q: %w", dst, err)
} }
if err = r.Modify(ctx, files.NewEtcFileStatus(files.NamespaceName, filename), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, files.NewEtcFileStatus(files.NamespaceName, filename), func(r *files.EtcFileStatus) error {
r.(*files.EtcFileStatus).TypedSpec().SpecVersion = spec.Metadata().Version().String() r.TypedSpec().SpecVersion = spec.Metadata().Version().String()
return nil return nil
}); err != nil { }); err != nil {
@ -150,12 +150,12 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
} }
// list statuses for cleanup // list statuses for cleanup
list, err = r.List(ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileStatusType, "", resource.VersionUndefined)) statuses, err := safe.ReaderList[*files.EtcFileStatus](ctx, r, resource.NewMetadata(files.NamespaceName, files.EtcFileStatusType, "", resource.VersionUndefined))
if err != nil { if err != nil {
return fmt.Errorf("error listing resources: %w", err) return fmt.Errorf("error listing resources: %w", err)
} }
for _, res := range list.Items { for res := range statuses.All() {
if _, ok := touchedIDs[res.Metadata().ID()]; !ok { if _, ok := touchedIDs[res.Metadata().ID()]; !ok {
if err = r.Destroy(ctx, res.Metadata()); err != nil { if err = r.Destroy(ctx, res.Metadata()); err != nil {
return fmt.Errorf("error cleaning up specs: %w", err) return fmt.Errorf("error cleaning up specs: %w", err)

View File

@ -54,7 +54,7 @@ func (ctrl *AddressFilterController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *AddressFilterController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *AddressFilterController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -87,7 +87,7 @@ func (ctrl *KubeletSpecController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *KubeletSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubeletSpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -74,7 +74,7 @@ func (ctrl *KubeletStaticPodController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KubeletStaticPodController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubeletStaticPodController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
var kubeletClient *kubelet.Client var kubeletClient *kubelet.Client
refreshTicker := time.NewTicker(15 * time.Second) // refresh kubelet pods status every 15 seconds refreshTicker := time.NewTicker(15 * time.Second) // refresh kubelet pods status every 15 seconds

View File

@ -64,7 +64,7 @@ func (ctrl *ManifestController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *ManifestController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *ManifestController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -58,7 +58,7 @@ func (ctrl *NodeAnnotationSpecController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *NodeAnnotationSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *NodeAnnotationSpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -51,7 +51,7 @@ func (ctrl *NodeCordonedSpecController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *NodeCordonedSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *NodeCordonedSpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -59,7 +59,7 @@ func (ctrl *NodeLabelSpecController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *NodeLabelSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *NodeLabelSpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -59,7 +59,7 @@ func (ctrl *NodenameController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *NodenameController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *NodenameController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -68,7 +68,7 @@ func (ctrl *RenderConfigsStaticPodController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *RenderConfigsStaticPodController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *RenderConfigsStaticPodController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -83,7 +83,7 @@ func (ctrl *RenderSecretsStaticPodController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *RenderSecretsStaticPodController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *RenderSecretsStaticPodController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -54,7 +54,7 @@ func (ctrl *StaticEndpointController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *StaticEndpointController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *StaticEndpointController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -54,7 +54,7 @@ func (ctrl *StaticPodConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *StaticPodConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *StaticPodConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -63,7 +63,7 @@ func (ctrl *EndpointController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *EndpointController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *EndpointController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -12,6 +12,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"go.uber.org/zap" "go.uber.org/zap"
@ -73,7 +74,7 @@ func (ctrl *IdentityController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *IdentityController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *IdentityController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
if ctrl.StatePath == "" { if ctrl.StatePath == "" {
ctrl.StatePath = constants.StateMountPoint ctrl.StatePath = constants.StateMountPoint
} }
@ -92,19 +93,19 @@ func (ctrl *IdentityController) Run(ctx context.Context, r controller.Runtime, l
return fmt.Errorf("error reading mount status: %w", err) return fmt.Errorf("error reading mount status: %w", err)
} }
cfg, err := r.Get(ctx, resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined)) cfg, err := safe.ReaderGet[*kubespan.Config](ctx, r, resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined))
if err != nil && !state.IsNotFoundError(err) { if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error getting kubespan configuration: %w", err) return fmt.Errorf("error getting kubespan configuration: %w", err)
} }
firstMAC, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, network.FirstHardwareAddr, resource.VersionUndefined)) firstMAC, err := safe.ReaderGet[*network.HardwareAddr](ctx, r, resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, network.FirstHardwareAddr, resource.VersionUndefined))
if err != nil && !state.IsNotFoundError(err) { if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error getting first MAC address: %w", err) return fmt.Errorf("error getting first MAC address: %w", err)
} }
touchedIDs := make(map[resource.ID]struct{}) touchedIDs := make(map[resource.ID]struct{})
if cfg != nil && firstMAC != nil && cfg.(*kubespan.Config).TypedSpec().Enabled { if cfg != nil && firstMAC != nil && cfg.TypedSpec().Enabled {
var localIdentity kubespan.IdentitySpec var localIdentity kubespan.IdentitySpec
if err = controllers.LoadOrNewFromFile(filepath.Join(ctrl.StatePath, constants.KubeSpanIdentityFilename), &localIdentity, func(v any) error { if err = controllers.LoadOrNewFromFile(filepath.Join(ctrl.StatePath, constants.KubeSpanIdentityFilename), &localIdentity, func(v any) error {
@ -113,15 +114,15 @@ func (ctrl *IdentityController) Run(ctx context.Context, r controller.Runtime, l
return fmt.Errorf("error caching kubespan identity: %w", err) return fmt.Errorf("error caching kubespan identity: %w", err)
} }
kubespanCfg := cfg.(*kubespan.Config).TypedSpec() kubespanCfg := cfg.TypedSpec()
mac := firstMAC.(*network.HardwareAddr).TypedSpec() mac := firstMAC.TypedSpec()
if err = kubespanadapter.IdentitySpec(&localIdentity).UpdateAddress(kubespanCfg.ClusterID, net.HardwareAddr(mac.HardwareAddr)); err != nil { if err = kubespanadapter.IdentitySpec(&localIdentity).UpdateAddress(kubespanCfg.ClusterID, net.HardwareAddr(mac.HardwareAddr)); err != nil {
return fmt.Errorf("error updating KubeSpan address: %w", err) return fmt.Errorf("error updating KubeSpan address: %w", err)
} }
if err = r.Modify(ctx, kubespan.NewIdentity(kubespan.NamespaceName, kubespan.LocalIdentity), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, kubespan.NewIdentity(kubespan.NamespaceName, kubespan.LocalIdentity), func(res *kubespan.Identity) error {
*res.(*kubespan.Identity).TypedSpec() = localIdentity *res.TypedSpec() = localIdentity
return nil return nil
}); err != nil { }); err != nil {

View File

@ -163,12 +163,12 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
case <-tickerC: case <-tickerC:
} }
cfg, err := r.Get(ctx, resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined)) cfg, err := safe.ReaderGet[*kubespan.Config](ctx, r, resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined))
if err != nil && !state.IsNotFoundError(err) { if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error getting kubespan configuration: %w", err) return fmt.Errorf("error getting kubespan configuration: %w", err)
} }
if cfg == nil || !cfg.(*kubespan.Config).TypedSpec().Enabled { if cfg == nil || !cfg.TypedSpec().Enabled {
if ticker != nil { if ticker != nil {
ticker.Stop() ticker.Stop()
@ -203,9 +203,9 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
tickerC = ticker.C tickerC = ticker.C
} }
cfgSpec := cfg.(*kubespan.Config).TypedSpec() cfgSpec := cfg.TypedSpec()
localIdentity, err := r.Get(ctx, resource.NewMetadata(kubespan.NamespaceName, kubespan.IdentityType, kubespan.LocalIdentity, resource.VersionUndefined)) localIdentity, err := safe.ReaderGet[*kubespan.Identity](ctx, r, resource.NewMetadata(kubespan.NamespaceName, kubespan.IdentityType, kubespan.LocalIdentity, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -214,7 +214,7 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo
return fmt.Errorf("error getting local KubeSpan identity: %w", err) return fmt.Errorf("error getting local KubeSpan identity: %w", err)
} }
localSpec := localIdentity.(*kubespan.Identity).TypedSpec() localSpec := localIdentity.TypedSpec()
// fetch PeerSpecs and PeerStatuses and sync them // fetch PeerSpecs and PeerStatuses and sync them
peerSpecList, err := r.List(ctx, resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerSpecType, "", resource.VersionUndefined)) peerSpecList, err := r.List(ctx, resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerSpecType, "", resource.VersionUndefined))

View File

@ -12,6 +12,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/value" "github.com/siderolabs/gen/value"
"github.com/siderolabs/go-procfs/procfs" "github.com/siderolabs/go-procfs/procfs"
@ -162,11 +163,12 @@ func (ctrl *AddressConfigController) apply(ctx context.Context, r controller.Run
for _, address := range addresses { for _, address := range addresses {
id := network.LayeredID(address.ConfigLayer, network.AddressID(address.LinkName, address.Address)) id := network.LayeredID(address.ConfigLayer, network.AddressID(address.LinkName, address.Address))
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewAddressSpec(network.ConfigNamespaceName, id), network.NewAddressSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.AddressSpec) error {
*r.(*network.AddressSpec).TypedSpec() = address *r.TypedSpec() = address
return nil return nil
}, },

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"go.uber.org/zap" "go.uber.org/zap"
@ -57,7 +58,7 @@ func (ctrl *AddressEventController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *AddressEventController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *AddressEventController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
ticker := time.NewTicker(time.Minute * 10) ticker := time.NewTicker(time.Minute * 10)
defer ticker.Stop() defer ticker.Stop()
@ -72,8 +73,9 @@ func (ctrl *AddressEventController) Run(ctx context.Context, r controller.Runtim
var addresses []string var addresses []string
nodeAddr, err := r.Get( nodeAddr, err := safe.ReaderGet[*network.NodeAddress](
ctx, ctx,
r,
resource.NewMetadata( resource.NewMetadata(
network.NamespaceName, network.NamespaceName,
network.NodeAddressType, network.NodeAddressType,
@ -87,7 +89,7 @@ func (ctrl *AddressEventController) Run(ctx context.Context, r controller.Runtim
return err return err
} }
} else { } else {
for _, addr := range nodeAddr.(*network.NodeAddress).TypedSpec().Addresses { for _, addr := range nodeAddr.TypedSpec().Addresses {
addresses = append( addresses = append(
addresses, addresses,
addr.Addr().String(), addr.Addr().String(),
@ -97,13 +99,13 @@ func (ctrl *AddressEventController) Run(ctx context.Context, r controller.Runtim
var hostname string var hostname string
hostnameStatus, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined)) hostnameStatus, err := safe.ReaderGet[*network.HostnameStatus](ctx, r, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined))
if err != nil { if err != nil {
if !state.IsNotFoundError(err) { if !state.IsNotFoundError(err) {
return err return err
} }
} else { } else {
hostname = hostnameStatus.(*network.HostnameStatus).TypedSpec().Hostname hostname = hostnameStatus.TypedSpec().Hostname
} }
ctrl.V1Alpha1Events.Publish(ctx, &machine.AddressEvent{ ctrl.V1Alpha1Events.Publish(ctx, &machine.AddressEvent{

View File

@ -13,6 +13,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -56,7 +57,7 @@ func (ctrl *AddressMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *AddressMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *AddressMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -89,9 +90,7 @@ func (ctrl *AddressMergeController) Run(ctx context.Context, r controller.Runtim
conflictsDetected := 0 conflictsDetected := 0
for id, address := range addresses { for id, address := range addresses {
if err = r.Modify(ctx, network.NewAddressSpec(network.NamespaceName, id), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewAddressSpec(network.NamespaceName, id), func(addr *network.AddressSpec) error {
addr := res.(*network.AddressSpec) //nolint:errcheck,forcetypeassert
*addr.TypedSpec() = *address.TypedSpec() *addr.TypedSpec() = *address.TypedSpec()
return nil return nil

View File

@ -14,6 +14,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/jsimonetti/rtnetlink/v2" "github.com/jsimonetti/rtnetlink/v2"
"github.com/mdlayher/arp" "github.com/mdlayher/arp"
"go.uber.org/zap" "go.uber.org/zap"
@ -76,13 +77,13 @@ func (ctrl *AddressSpecController) Run(ctx context.Context, r controller.Runtime
} }
// list source network configuration resources // list source network configuration resources
list, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined)) list, err := safe.ReaderList[*network.AddressSpec](ctx, r, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined))
if err != nil { if err != nil {
return fmt.Errorf("error listing source network addresses: %w", err) return fmt.Errorf("error listing source network addresses: %w", err)
} }
// add finalizers for all live resources // add finalizers for all live resources
for _, res := range list.Items { for res := range list.All() {
if res.Metadata().Phase() != resource.PhaseRunning { if res.Metadata().Phase() != resource.PhaseRunning {
continue continue
} }
@ -105,9 +106,7 @@ func (ctrl *AddressSpecController) Run(ctx context.Context, r controller.Runtime
} }
// loop over addresses and make reconcile decision // loop over addresses and make reconcile decision
for _, res := range list.Items { for address := range list.All() {
address := res.(*network.AddressSpec) //nolint:forcetypeassert,errcheck
if err = ctrl.syncAddress(ctx, r, logger, conn, links, addrs, address); err != nil { if err = ctrl.syncAddress(ctx, r, logger, conn, links, addrs, address); err != nil {
return err return err
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/jsimonetti/rtnetlink/v2" "github.com/jsimonetti/rtnetlink/v2"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -46,7 +47,7 @@ func (ctrl *AddressStatusController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *AddressStatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *AddressStatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
watcher, err := watch.NewRtNetlink(watch.NewDefaultRateLimitedTrigger(ctx, r), unix.RTMGRP_LINK|unix.RTMGRP_IPV4_IFADDR|unix.RTMGRP_IPV6_IFADDR) watcher, err := watch.NewRtNetlink(watch.NewDefaultRateLimitedTrigger(ctx, r), unix.RTMGRP_LINK|unix.RTMGRP_IPV4_IFADDR|unix.RTMGRP_IPV6_IFADDR)
if err != nil { if err != nil {
return err return err
@ -98,8 +99,8 @@ func (ctrl *AddressStatusController) Run(ctx context.Context, r controller.Runti
ipPrefix := netip.PrefixFrom(ipAddr, int(addr.PrefixLength)) ipPrefix := netip.PrefixFrom(ipAddr, int(addr.PrefixLength))
id := network.AddressID(linkLookup[addr.Index], ipPrefix) id := network.AddressID(linkLookup[addr.Index], ipPrefix)
if err = r.Modify(ctx, network.NewAddressStatus(network.NamespaceName, id), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewAddressStatus(network.NamespaceName, id), func(r *network.AddressStatus) error {
status := r.(*network.AddressStatus).TypedSpec() status := r.TypedSpec()
status.Address = ipPrefix status.Address = ipPrefix
status.Local, _ = netip.AddrFromSlice(addr.Attributes.Local) status.Local, _ = netip.AddrFromSlice(addr.Attributes.Local)

View File

@ -163,11 +163,12 @@ func (ctrl *DNSResolveCacheController) Run(ctx context.Context, r controller.Run
} }
prxs := xiter.Map( prxs := xiter.Map(
upstreams.All(),
// We are using iterator here to preserve finalizer on // We are using iterator here to preserve finalizer on
func(upstream *network.DNSUpstream) *proxy.Proxy { func(upstream *network.DNSUpstream) *proxy.Proxy {
return upstream.TypedSpec().Value.Conn.Proxy().(*proxy.Proxy) return upstream.TypedSpec().Value.Conn.Proxy().(*proxy.Proxy)
}) },
upstreams.All(),
)
if ctrl.handler.SetProxy(prxs) { if ctrl.handler.SetProxy(prxs) {
ctrl.Logger.Info("updated dns server nameservers", zap.Array("addrs", addrsArr(upstreams))) ctrl.Logger.Info("updated dns server nameservers", zap.Array("addrs", addrsArr(upstreams)))

View File

@ -8,9 +8,11 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"iter"
"net/netip" "net/netip"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
@ -19,6 +21,7 @@ import (
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"github.com/siderolabs/gen/value" "github.com/siderolabs/gen/value"
"github.com/siderolabs/gen/xiter"
"go.uber.org/zap" "go.uber.org/zap"
efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files" efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files"
@ -89,7 +92,7 @@ func (ctrl *EtcFileController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -161,7 +164,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
dnsServers = []netip.Addr{hostDNSCfg.TypedSpec().ServiceHostDNSAddress} dnsServers = []netip.Addr{hostDNSCfg.TypedSpec().ServiceHostDNSAddress}
} }
conf := renderResolvConf(dnsServers, hostnameStatusSpec, cfgProvider) conf := renderResolvConf(slices.All(dnsServers), hostnameStatusSpec, cfgProvider)
if err = os.MkdirAll(filepath.Dir(ctrl.PodResolvConfPath), 0o755); err != nil { if err = os.MkdirAll(filepath.Dir(ctrl.PodResolvConfPath), 0o755); err != nil {
return fmt.Errorf("error creating pod resolv.conf dir: %w", err) return fmt.Errorf("error creating pod resolv.conf dir: %w", err)
@ -189,18 +192,18 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo
} }
} }
var localDNS = []netip.Addr{netip.MustParseAddr("127.0.0.53")} var localDNS = xiter.Single2(0, netip.MustParseAddr("127.0.0.53"))
func pickNameservers(hostDNSCfg *network.HostDNSConfig, resolverStatus *network.ResolverStatus) []netip.Addr { func pickNameservers(hostDNSCfg *network.HostDNSConfig, resolverStatus *network.ResolverStatus) iter.Seq2[int, netip.Addr] {
if hostDNSCfg.TypedSpec().Enabled { if hostDNSCfg.TypedSpec().Enabled {
// local dns resolve cache enabled, route host dns requests to 127.0.0.1 // local dns resolve cache enabled, route host dns requests to 127.0.0.1
return localDNS return localDNS
} }
return resolverStatus.TypedSpec().DNSServers return slices.All(resolverStatus.TypedSpec().DNSServers)
} }
func renderResolvConf(nameservers []netip.Addr, hostnameStatus *network.HostnameStatusSpec, cfgProvider talosconfig.Config) []byte { func renderResolvConf(nameservers iter.Seq2[int, netip.Addr], hostnameStatus *network.HostnameStatusSpec, cfgProvider talosconfig.Config) []byte {
var buf bytes.Buffer var buf bytes.Buffer
for i, ns := range nameservers { for i, ns := range nameservers {
@ -229,9 +232,7 @@ func (ctrl *EtcFileController) renderHosts(hostnameStatus *network.HostnameStatu
tabW := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0) tabW := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0)
write := func(s string) { write := func(s string) { tabW.Write([]byte(s)) } //nolint:errcheck
tabW.Write([]byte(s)) //nolint:errcheck
}
write("127.0.0.1\tlocalhost\n") write("127.0.0.1\tlocalhost\n")

View File

@ -127,9 +127,9 @@ func (suite *EtcFileConfigSuite) SetupTest() {
suite.hostDNSConfig.TypedSpec().Enabled = true suite.hostDNSConfig.TypedSpec().Enabled = true
suite.hostDNSConfig.TypedSpec().ListenAddresses = []netip.AddrPort{ suite.hostDNSConfig.TypedSpec().ListenAddresses = []netip.AddrPort{
netip.MustParseAddrPort("127.0.0.53:53"), netip.MustParseAddrPort("127.0.0.53:53"),
netip.MustParseAddrPort("10.96.0.9:53"), netip.MustParseAddrPort("169.254.116.108:53"),
} }
suite.hostDNSConfig.TypedSpec().ServiceHostDNSAddress = netip.MustParseAddr("10.96.0.9") suite.hostDNSConfig.TypedSpec().ServiceHostDNSAddress = netip.MustParseAddr("169.254.116.108")
} }
func (suite *EtcFileConfigSuite) startRuntime() { func (suite *EtcFileConfigSuite) startRuntime() {
@ -228,7 +228,7 @@ func (suite *EtcFileConfigSuite) TestComplete() {
etcFileContents{ etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n10.0.0.1 a b\n10.0.0.2 c d\n", //nolint:lll hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n10.0.0.1 a b\n10.0.0.2 c d\n", //nolint:lll
resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n", resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n",
resolvGlobalConf: "nameserver 10.96.0.9\n\nsearch example.com\n", resolvGlobalConf: "nameserver 169.254.116.108\n\nsearch example.com\n",
}, },
) )
} }
@ -239,7 +239,7 @@ func (suite *EtcFileConfigSuite) TestNoExtraHosts() {
etcFileContents{ etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n", resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n",
resolvGlobalConf: "nameserver 10.96.0.9\n\nsearch example.com\n", resolvGlobalConf: "nameserver 169.254.116.108\n\nsearch example.com\n",
}, },
) )
} }
@ -262,7 +262,7 @@ func (suite *EtcFileConfigSuite) TestNoSearchDomain() {
etcFileContents{ etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.53\n", resolvConf: "nameserver 127.0.0.53\n",
resolvGlobalConf: "nameserver 10.96.0.9\n", resolvGlobalConf: "nameserver 169.254.116.108\n",
}, },
) )
} }
@ -275,7 +275,7 @@ func (suite *EtcFileConfigSuite) TestNoDomainname() {
etcFileContents{ etcFileContents{
hosts: "127.0.0.1 localhost\n33.11.22.44 foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", hosts: "127.0.0.1 localhost\n33.11.22.44 foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n",
resolvConf: "nameserver 127.0.0.53\n", resolvConf: "nameserver 127.0.0.53\n",
resolvGlobalConf: "nameserver 10.96.0.9\n", resolvGlobalConf: "nameserver 169.254.116.108\n",
}, },
) )
} }
@ -286,7 +286,7 @@ func (suite *EtcFileConfigSuite) TestOnlyResolvers() {
etcFileContents{ etcFileContents{
hosts: "", hosts: "",
resolvConf: "nameserver 127.0.0.53\n", resolvConf: "nameserver 127.0.0.53\n",
resolvGlobalConf: "nameserver 10.96.0.9\n", resolvGlobalConf: "nameserver 169.254.116.108\n",
}, },
) )
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/resources/network" "github.com/siderolabs/talos/pkg/machinery/resources/network"
@ -47,7 +48,7 @@ func (ctrl *HardwareAddrController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *HardwareAddrController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *HardwareAddrController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -80,8 +81,8 @@ func (ctrl *HardwareAddrController) Run(ctx context.Context, r controller.Runtim
continue continue
} }
if err = r.Modify(ctx, network.NewHardwareAddr(network.NamespaceName, network.FirstHardwareAddr), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewHardwareAddr(network.NamespaceName, network.FirstHardwareAddr), func(r *network.HardwareAddr) error {
spec := r.(*network.HardwareAddr).TypedSpec() spec := r.TypedSpec()
spec.HardwareAddr = link.TypedSpec().HardwareAddr spec.HardwareAddr = link.TypedSpec().HardwareAddr
spec.Name = link.Metadata().ID() spec.Name = link.Metadata().ID()

View File

@ -98,13 +98,13 @@ func (ctrl *HostnameConfigController) Run(ctx context.Context, r controller.Runt
// defaults // defaults
var defaultAddr *network.NodeAddress var defaultAddr *network.NodeAddress
addrs, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.NodeAddressDefaultID, resource.VersionUndefined)) addrs, err := safe.ReaderGet[*network.NodeAddress](ctx, r, resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.NodeAddressDefaultID, resource.VersionUndefined))
if err != nil { if err != nil {
if !state.IsNotFoundError(err) { if !state.IsNotFoundError(err) {
return fmt.Errorf("error getting config: %w", err) return fmt.Errorf("error getting config: %w", err)
} }
} else { } else {
defaultAddr = addrs.(*network.NodeAddress) //nolint:errcheck,forcetypeassert defaultAddr = addrs
} }
// parse kernel cmdline for the default gateway // parse kernel cmdline for the default gateway
@ -122,9 +122,9 @@ func (ctrl *HostnameConfigController) Run(ctx context.Context, r controller.Runt
} }
if cfgProvider.Machine().Features().StableHostnameEnabled() { if cfgProvider.Machine().Features().StableHostnameEnabled() {
var identity resource.Resource var identity *cluster.Identity
identity, err = r.Get(ctx, resource.NewMetadata(cluster.NamespaceName, cluster.IdentityType, cluster.LocalIdentity, resource.VersionUndefined)) identity, err = safe.ReaderGet[*cluster.Identity](ctx, r, resource.NewMetadata(cluster.NamespaceName, cluster.IdentityType, cluster.LocalIdentity, resource.VersionUndefined))
if err != nil { if err != nil {
if !state.IsNotFoundError(err) { if !state.IsNotFoundError(err) {
return fmt.Errorf("error getting local identity: %w", err) return fmt.Errorf("error getting local identity: %w", err)
@ -133,7 +133,7 @@ func (ctrl *HostnameConfigController) Run(ctx context.Context, r controller.Runt
continue continue
} }
nodeID := identity.(*cluster.Identity).TypedSpec().NodeID nodeID := identity.TypedSpec().NodeID
stableHostname := ctrl.getStableDefault(nodeID) stableHostname := ctrl.getStableDefault(nodeID)
specs = append(specs, *stableHostname) specs = append(specs, *stableHostname)
@ -183,11 +183,12 @@ func (ctrl *HostnameConfigController) apply(ctx context.Context, r controller.Ru
for _, spec := range specs { for _, spec := range specs {
id := network.LayeredID(spec.ConfigLayer, network.HostnameID) id := network.LayeredID(spec.ConfigLayer, network.HostnameID)
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewHostnameSpec(network.ConfigNamespaceName, id), network.NewHostnameSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.HostnameSpec) error {
*r.(*network.HostnameSpec).TypedSpec() = spec *r.TypedSpec() = spec
return nil return nil
}, },

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -54,7 +55,7 @@ func (ctrl *HostnameMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *HostnameMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *HostnameMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -83,9 +84,7 @@ func (ctrl *HostnameMergeController) Run(ctx context.Context, r controller.Runti
} }
if final.Hostname != "" { if final.Hostname != "" {
if err = r.Modify(ctx, network.NewHostnameSpec(network.NamespaceName, network.HostnameID), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewHostnameSpec(network.NamespaceName, network.HostnameID), func(spec *network.HostnameSpec) error {
spec := res.(*network.HostnameSpec) //nolint:errcheck,forcetypeassert
*spec.TypedSpec() = final *spec.TypedSpec() = final
return nil return nil

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -91,9 +92,7 @@ func (ctrl *HostnameSpecController) Run(ctx context.Context, r controller.Runtim
return fmt.Errorf("error removing finalizer: %w", err) return fmt.Errorf("error removing finalizer: %w", err)
} }
case resource.PhaseRunning: case resource.PhaseRunning:
if err = r.Modify(ctx, network.NewHostnameStatus(network.NamespaceName, spec.Metadata().ID()), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewHostnameStatus(network.NamespaceName, spec.Metadata().ID()), func(status *network.HostnameStatus) error {
status := r.(*network.HostnameStatus) //nolint:forcetypeassert,errcheck
status.TypedSpec().Hostname = spec.TypedSpec().Hostname status.TypedSpec().Hostname = spec.TypedSpec().Hostname
status.TypedSpec().Domainname = spec.TypedSpec().Domainname status.TypedSpec().Domainname = spec.TypedSpec().Domainname

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/maps" "github.com/siderolabs/gen/maps"
"github.com/siderolabs/gen/pair/ordered" "github.com/siderolabs/gen/pair/ordered"
@ -236,11 +237,12 @@ func (ctrl *LinkConfigController) apply(ctx context.Context, r controller.Runtim
for _, link := range links { for _, link := range links {
id := network.LayeredID(link.ConfigLayer, network.LinkID(link.Name)) id := network.LayeredID(link.ConfigLayer, network.LinkID(link.Name))
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewLinkSpec(network.ConfigNamespaceName, id), network.NewLinkSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.LinkSpec) error {
*r.(*network.LinkSpec).TypedSpec() = link *r.TypedSpec() = link
return nil return nil
}, },

View File

@ -12,6 +12,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -103,9 +104,7 @@ func (ctrl *LinkMergeController) Run(ctx context.Context, r controller.Runtime,
conflictsDetected := 0 conflictsDetected := 0
for id, link := range links { for id, link := range links {
if err = r.Modify(ctx, network.NewLinkSpec(network.NamespaceName, id), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewLinkSpec(network.NamespaceName, id), func(l *network.LinkSpec) error {
l := res.(*network.LinkSpec) //nolint:errcheck,forcetypeassert
*l.TypedSpec() = *link *l.TypedSpec() = *link
return nil return nil

View File

@ -13,6 +13,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/jsimonetti/rtnetlink/v2" "github.com/jsimonetti/rtnetlink/v2"
"github.com/mdlayher/ethtool" "github.com/mdlayher/ethtool"
ethtoolioctl "github.com/safchain/ethtool" ethtoolioctl "github.com/safchain/ethtool"
@ -221,8 +222,8 @@ func (ctrl *LinkStatusController) reconcile(
} }
} }
if err = r.Modify(ctx, network.NewLinkStatus(network.NamespaceName, link.Attributes.Name), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewLinkStatus(network.NamespaceName, link.Attributes.Name), func(r *network.LinkStatus) error {
status := r.(*network.LinkStatus).TypedSpec() status := r.TypedSpec()
status.Index = link.Index status.Index = link.Index
status.HardwareAddr = nethelpers.HardwareAddr(link.Attributes.Address) status.HardwareAddr = nethelpers.HardwareAddr(link.Attributes.Address)

View File

@ -61,7 +61,7 @@ func (ctrl *NfTablesChainConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) (err error) { func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) (err error) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -162,7 +162,10 @@ func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller
network.NfTablesRule{ network.NfTablesRule{
MatchSourceAddress: &network.NfTablesAddressMatch{ MatchSourceAddress: &network.NfTablesAddressMatch{
IncludeSubnets: xslices.Map( IncludeSubnets: xslices.Map(
append(slices.Clone(cfg.Config().Cluster().Network().PodCIDRs()), cfg.Config().Cluster().Network().ServiceCIDRs()...), slices.Concat(
cfg.Config().Cluster().Network().PodCIDRs(),
cfg.Config().Cluster().Network().ServiceCIDRs(),
),
netip.MustParsePrefix, netip.MustParsePrefix,
), ),
}, },

View File

@ -13,6 +13,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/siderolabs/gen/value" "github.com/siderolabs/gen/value"
"go.uber.org/zap" "go.uber.org/zap"
@ -62,7 +63,7 @@ func (ctrl *NodeAddressController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
var addressStatusController AddressStatusController var addressStatusController AddressStatusController
addressStatusControllerName := addressStatusController.Name() addressStatusControllerName := addressStatusController.Name()
@ -161,8 +162,8 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime
// update output resources // update output resources
if !value.IsZero(defaultAddress) { if !value.IsZero(defaultAddress) {
if err = r.Modify(ctx, network.NewNodeAddress(network.NamespaceName, network.NodeAddressDefaultID), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewNodeAddress(network.NamespaceName, network.NodeAddressDefaultID), func(r *network.NodeAddress) error {
spec := r.(*network.NodeAddress).TypedSpec() spec := r.TypedSpec()
// never overwrite default address if it's already set // never overwrite default address if it's already set
// we should start handing default address updates, but for now we're not ready // we should start handing default address updates, but for now we're not ready
@ -300,8 +301,8 @@ outer:
} }
func updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resource.ID, current []netip.Prefix) error { func updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resource.ID, current []netip.Prefix) error {
if err := r.Modify(ctx, network.NewNodeAddress(network.NamespaceName, id), func(r resource.Resource) error { if err := safe.WriterModify(ctx, r, network.NewNodeAddress(network.NamespaceName, id), func(r *network.NodeAddress) error {
spec := r.(*network.NodeAddress).TypedSpec() spec := r.TypedSpec()
spec.Addresses = current spec.Addresses = current
@ -314,8 +315,8 @@ func updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resour
} }
func updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id resource.ID, accumulative []netip.Prefix) error { func updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id resource.ID, accumulative []netip.Prefix) error {
if err := r.Modify(ctx, network.NewNodeAddress(network.NamespaceName, id), func(r resource.Resource) error { if err := safe.WriterModify(ctx, r, network.NewNodeAddress(network.NamespaceName, id), func(r *network.NodeAddress) error {
spec := r.(*network.NodeAddress).TypedSpec() spec := r.TypedSpec()
for _, ip := range accumulative { for _, ip := range accumulative {
// find insert position using binary search // find insert position using binary search
@ -328,9 +329,7 @@ func updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id r
} }
// insert at position i // insert at position i
spec.Addresses = append(spec.Addresses, netip.Prefix{}) spec.Addresses = slices.Insert(spec.Addresses, i, ip)
copy(spec.Addresses[i+1:], spec.Addresses[i:])
spec.Addresses[i] = ip
} }
return nil return nil

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/siderolabs/gen/xslices" "github.com/siderolabs/gen/xslices"
@ -303,11 +304,12 @@ func (ctrl *OperatorConfigController) apply(ctx context.Context, r controller.Ru
for _, spec := range specs { for _, spec := range specs {
id := network.LayeredID(spec.ConfigLayer, network.OperatorID(spec.Operator, spec.LinkName)) id := network.LayeredID(spec.ConfigLayer, network.OperatorID(spec.Operator, spec.LinkName))
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewOperatorSpec(network.ConfigNamespaceName, id), network.NewOperatorSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.OperatorSpec) error {
*r.(*network.OperatorSpec).TypedSpec() = spec *r.TypedSpec() = spec
return nil return nil
}, },

View File

@ -13,6 +13,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -56,7 +57,7 @@ func (ctrl *OperatorMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *OperatorMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *OperatorMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -89,9 +90,7 @@ func (ctrl *OperatorMergeController) Run(ctx context.Context, r controller.Runti
conflictsDetected := 0 conflictsDetected := 0
for id, operator := range operators { for id, operator := range operators {
if err = r.Modify(ctx, network.NewOperatorSpec(network.NamespaceName, id), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewOperatorSpec(network.NamespaceName, id), func(op *network.OperatorSpec) error {
op := res.(*network.OperatorSpec) //nolint:errcheck,forcetypeassert
*op.TypedSpec() = *operator.TypedSpec() *op.TypedSpec() = *operator.TypedSpec()
return nil return nil

View File

@ -141,7 +141,7 @@ func (mock *mockOperator) TimeServerSpecs() []network.TimeServerSpecSpec {
return mock.timeservers return mock.timeservers
} }
func (suite *OperatorSpecSuite) newOperator(logger *zap.Logger, spec *network.OperatorSpecSpec) operator.Operator { func (suite *OperatorSpecSuite) newOperator(_ *zap.Logger, spec *network.OperatorSpecSpec) operator.Operator {
return &mockOperator{ return &mockOperator{
spec: *spec, spec: *spec,
} }
@ -311,7 +311,8 @@ func (suite *OperatorSpecSuite) TestScheduling() {
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry( retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error { func() error {
return suite.assertRunning( return suite.assertRunning(
[]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error { []string{"dhcp4/eth0", "vip/eth0"},
func(op *mockOperator) error {
switch op.spec.Operator { //nolint:exhaustive switch op.spec.Operator { //nolint:exhaustive
case network.OperatorDHCP4: case network.OperatorDHCP4:
suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric) suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric)
@ -339,7 +340,8 @@ func (suite *OperatorSpecSuite) TestScheduling() {
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry( retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error { func() error {
return suite.assertRunning( return suite.assertRunning(
[]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error { []string{"dhcp4/eth0", "vip/eth0"},
func(op *mockOperator) error {
switch op.spec.Operator { //nolint:exhaustive switch op.spec.Operator { //nolint:exhaustive
case network.OperatorDHCP4: case network.OperatorDHCP4:
suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric) suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric)

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/siderolabs/gen/xslices" "github.com/siderolabs/gen/xslices"
@ -176,11 +177,12 @@ func (ctrl *OperatorVIPConfigController) apply(ctx context.Context, r controller
for _, spec := range specs { for _, spec := range specs {
id := network.LayeredID(spec.ConfigLayer, network.OperatorID(spec.Operator, spec.LinkName)) id := network.LayeredID(spec.ConfigLayer, network.OperatorID(spec.Operator, spec.LinkName))
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewOperatorSpec(network.ConfigNamespaceName, id), network.NewOperatorSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.OperatorSpec) error {
*r.(*network.OperatorSpec).TypedSpec() = spec *r.TypedSpec() = spec
return nil return nil
}, },

View File

@ -140,11 +140,12 @@ func (ctrl *ResolverConfigController) apply(ctx context.Context, r controller.Ru
for _, spec := range specs { for _, spec := range specs {
id := network.LayeredID(spec.ConfigLayer, network.ResolverID) id := network.LayeredID(spec.ConfigLayer, network.ResolverID)
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewResolverSpec(network.ConfigNamespaceName, id), network.NewResolverSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.ResolverSpec) error {
*r.(*network.ResolverSpec).TypedSpec() = spec *r.TypedSpec() = spec
return nil return nil
}, },

View File

@ -58,7 +58,7 @@ func (ctrl *ResolverMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *ResolverMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *ResolverMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -57,13 +58,13 @@ func (ctrl *ResolverSpecController) Run(ctx context.Context, r controller.Runtim
} }
// list source network configuration resources // list source network configuration resources
list, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.ResolverSpecType, "", resource.VersionUndefined)) list, err := safe.ReaderListAll[*network.ResolverSpec](ctx, r)
if err != nil { if err != nil {
return fmt.Errorf("error listing source network addresses: %w", err) return fmt.Errorf("error listing source network addresses: %w", err)
} }
// add finalizers for all live resources // add finalizers for all live resources
for _, res := range list.Items { for res := range list.All() {
if res.Metadata().Phase() != resource.PhaseRunning { if res.Metadata().Phase() != resource.PhaseRunning {
continue continue
} }
@ -74,9 +75,7 @@ func (ctrl *ResolverSpecController) Run(ctx context.Context, r controller.Runtim
} }
// loop over specs and sync to statuses // loop over specs and sync to statuses
for _, res := range list.Items { for spec := range list.All() {
spec := res.(*network.ResolverSpec) //nolint:forcetypeassert,errcheck
switch spec.Metadata().Phase() { switch spec.Metadata().Phase() {
case resource.PhaseTearingDown: case resource.PhaseTearingDown:
if err = r.Destroy(ctx, resource.NewMetadata(network.NamespaceName, network.ResolverStatusType, spec.Metadata().ID(), resource.VersionUndefined)); err != nil && !state.IsNotFoundError(err) { if err = r.Destroy(ctx, resource.NewMetadata(network.NamespaceName, network.ResolverStatusType, spec.Metadata().ID(), resource.VersionUndefined)); err != nil && !state.IsNotFoundError(err) {
@ -89,10 +88,8 @@ func (ctrl *ResolverSpecController) Run(ctx context.Context, r controller.Runtim
case resource.PhaseRunning: case resource.PhaseRunning:
logger.Info("setting resolvers", zap.Stringers("resolvers", spec.TypedSpec().DNSServers)) logger.Info("setting resolvers", zap.Stringers("resolvers", spec.TypedSpec().DNSServers))
if err = r.Modify(ctx, network.NewResolverStatus(network.NamespaceName, spec.Metadata().ID()), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewResolverStatus(network.NamespaceName, spec.Metadata().ID()), func(r *network.ResolverStatus) error {
status := r.(*network.ResolverStatus) //nolint:forcetypeassert,errcheck r.TypedSpec().DNSServers = spec.TypedSpec().DNSServers
status.TypedSpec().DNSServers = spec.TypedSpec().DNSServers
return nil return nil
}); err != nil { }); err != nil {

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/value" "github.com/siderolabs/gen/value"
"github.com/siderolabs/go-procfs/procfs" "github.com/siderolabs/go-procfs/procfs"
@ -156,11 +157,12 @@ func (ctrl *RouteConfigController) apply(ctx context.Context, r controller.Runti
for _, route := range routes { for _, route := range routes {
id := network.LayeredID(route.ConfigLayer, network.RouteID(route.Table, route.Family, route.Destination, route.Gateway, route.Priority, route.OutLinkName)) id := network.LayeredID(route.ConfigLayer, network.RouteID(route.Table, route.Family, route.Destination, route.Gateway, route.Priority, route.OutLinkName))
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewRouteSpec(network.ConfigNamespaceName, id), network.NewRouteSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.RouteSpec) error {
*r.(*network.RouteSpec).TypedSpec() = route *r.TypedSpec() = route
return nil return nil
}, },

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -54,7 +55,7 @@ func (ctrl *RouteMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *RouteMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *RouteMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -87,9 +88,7 @@ func (ctrl *RouteMergeController) Run(ctx context.Context, r controller.Runtime,
conflictsDetected := 0 conflictsDetected := 0
for id, route := range routes { for id, route := range routes {
if err = r.Modify(ctx, network.NewRouteSpec(network.NamespaceName, id), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewRouteSpec(network.NamespaceName, id), func(rt *network.RouteSpec) error {
rt := res.(*network.RouteSpec) //nolint:errcheck,forcetypeassert
*rt.TypedSpec() = *route.TypedSpec() *rt.TypedSpec() = *route.TypedSpec()
return nil return nil

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/jsimonetti/rtnetlink/v2" "github.com/jsimonetti/rtnetlink/v2"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -46,7 +47,7 @@ func (ctrl *RouteStatusController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *RouteStatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *RouteStatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
watcher, err := watch.NewRtNetlink(watch.NewDefaultRateLimitedTrigger(ctx, r), unix.RTMGRP_IPV4_MROUTE|unix.RTMGRP_IPV4_ROUTE|unix.RTMGRP_IPV6_MROUTE|unix.RTMGRP_IPV6_ROUTE) watcher, err := watch.NewRtNetlink(watch.NewDefaultRateLimitedTrigger(ctx, r), unix.RTMGRP_IPV4_MROUTE|unix.RTMGRP_IPV4_ROUTE|unix.RTMGRP_IPV6_MROUTE|unix.RTMGRP_IPV6_ROUTE)
if err != nil { if err != nil {
return err return err
@ -106,8 +107,8 @@ func (ctrl *RouteStatusController) Run(ctx context.Context, r controller.Runtime
id := network.RouteID(nethelpers.RoutingTable(route.Table), nethelpers.Family(route.Family), dstPrefix, gatewayAddr, route.Attributes.Priority, outLinkName) id := network.RouteID(nethelpers.RoutingTable(route.Table), nethelpers.Family(route.Family), dstPrefix, gatewayAddr, route.Attributes.Priority, outLinkName)
if err = r.Modify(ctx, network.NewRouteStatus(network.NamespaceName, id), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewRouteStatus(network.NamespaceName, id), func(r *network.RouteStatus) error {
status := r.(*network.RouteStatus).TypedSpec() status := r.TypedSpec()
status.Family = nethelpers.Family(route.Family) status.Family = nethelpers.Family(route.Family)
status.Destination = dstPrefix status.Destination = dstPrefix

View File

@ -76,7 +76,7 @@ func (ctrl *StatusController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *StatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *StatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -140,11 +140,12 @@ func (ctrl *TimeServerConfigController) apply(ctx context.Context, r controller.
for _, spec := range specs { for _, spec := range specs {
id := network.LayeredID(spec.ConfigLayer, network.TimeServerID) id := network.LayeredID(spec.ConfigLayer, network.TimeServerID)
if err := r.Modify( if err := safe.WriterModify(
ctx, ctx,
r,
network.NewTimeServerSpec(network.ConfigNamespaceName, id), network.NewTimeServerSpec(network.ConfigNamespaceName, id),
func(r resource.Resource) error { func(r *network.TimeServerSpec) error {
*r.(*network.TimeServerSpec).TypedSpec() = spec *r.TypedSpec() = spec
return nil return nil
}, },

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -54,7 +55,7 @@ func (ctrl *TimeServerMergeController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *TimeServerMergeController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *TimeServerMergeController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -89,9 +90,7 @@ func (ctrl *TimeServerMergeController) Run(ctx context.Context, r controller.Run
} }
if final.NTPServers != nil { if final.NTPServers != nil {
if err = r.Modify(ctx, network.NewTimeServerSpec(network.NamespaceName, network.TimeServerID), func(res resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewTimeServerSpec(network.NamespaceName, network.TimeServerID), func(spec *network.TimeServerSpec) error {
spec := res.(*network.TimeServerSpec) //nolint:errcheck,forcetypeassert
*spec.TypedSpec() = final *spec.TypedSpec() = final
return nil return nil

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -97,9 +98,7 @@ func (ctrl *TimeServerSpecController) Run(ctx context.Context, r controller.Runt
logger.Info("setting time servers", zap.Strings("addresses", ntps)) logger.Info("setting time servers", zap.Strings("addresses", ntps))
if err = r.Modify(ctx, network.NewTimeServerStatus(network.NamespaceName, spec.Metadata().ID()), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, network.NewTimeServerStatus(network.NamespaceName, spec.Metadata().ID()), func(status *network.TimeServerStatus) error {
status := r.(*network.TimeServerStatus) //nolint:forcetypeassert,errcheck
status.TypedSpec().NTPServers = spec.TypedSpec().NTPServers status.TypedSpec().NTPServers = spec.TypedSpec().NTPServers
return nil return nil

View File

@ -9,7 +9,7 @@ import (
"time" "time"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe"
"github.com/prometheus/procfs" "github.com/prometheus/procfs"
"go.uber.org/zap" "go.uber.org/zap"
@ -47,7 +47,7 @@ func (ctrl *StatsController) Outputs() []controller.Output {
} }
// Run implements controller.StatsController interface. // Run implements controller.StatsController interface.
func (ctrl *StatsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *StatsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
ticker := time.NewTicker(updateInterval) ticker := time.NewTicker(updateInterval)
defer ticker.Stop() defer ticker.Stop()
@ -90,8 +90,8 @@ func (ctrl *StatsController) updateCPU(ctx context.Context, r controller.Runtime
return err return err
} }
return r.Modify(ctx, cpu, func(r resource.Resource) error { return safe.WriterModify(ctx, r, cpu, func(r *perf.CPU) error {
perfadapter.CPU(r.(*perf.CPU)).Update(&stat) perfadapter.CPU(r).Update(&stat)
return nil return nil
}) })
@ -105,8 +105,8 @@ func (ctrl *StatsController) updateMemory(ctx context.Context, r controller.Runt
return err return err
} }
return r.Modify(ctx, mem, func(r resource.Resource) error { return safe.WriterModify(ctx, r, mem, func(r *perf.Memory) error {
perfadapter.Memory(r.(*perf.Memory)).Update(&info) perfadapter.Memory(r).Update(&info)
return nil return nil
}) })

View File

@ -42,7 +42,7 @@ func (ctrl *DevicesStatusController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *DevicesStatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *DevicesStatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
// in container mode, devices are always ready // in container mode, devices are always ready
if ctrl.V1Alpha1Mode != machineruntime.ModeContainer { if ctrl.V1Alpha1Mode != machineruntime.ModeContainer {
if err := v1alpha1.WaitForServiceHealthy(ctx, r, "udevd", nil); err != nil { if err := v1alpha1.WaitForServiceHealthy(ctx, r, "udevd", nil); err != nil {

View File

@ -57,7 +57,7 @@ func (ctrl *EventsSinkConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *EventsSinkConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) (err error) { func (ctrl *EventsSinkConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) (err error) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -53,7 +53,7 @@ func (ctrl *ExtensionServiceConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *ExtensionServiceConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *ExtensionServiceConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -55,7 +55,7 @@ func (ctrl *ExtensionServiceConfigFilesController) Outputs() []controller.Output
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *ExtensionServiceConfigFilesController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *ExtensionServiceConfigFilesController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer { if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer {
return nil return nil
} }

View File

@ -12,7 +12,7 @@ import (
"strings" "strings"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/constants"
@ -44,7 +44,7 @@ func (ctrl *ExtensionStatusController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *ExtensionStatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *ExtensionStatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
// controller runs once, as extensions are static // controller runs once, as extensions are static
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -66,8 +66,8 @@ func (ctrl *ExtensionStatusController) Run(ctx context.Context, r controller.Run
for _, layer := range cfg.Layers { for _, layer := range cfg.Layers {
id := strings.TrimSuffix(layer.Image, ".sqsh") id := strings.TrimSuffix(layer.Image, ".sqsh")
if err := r.Modify(ctx, runtime.NewExtensionStatus(runtime.NamespaceName, id), func(res resource.Resource) error { if err := safe.WriterModify(ctx, r, runtime.NewExtensionStatus(runtime.NamespaceName, id), func(res *runtime.ExtensionStatus) error {
*res.(*runtime.ExtensionStatus).TypedSpec() = *layer *res.TypedSpec() = *layer
return nil return nil
}); err != nil { }); err != nil {

View File

@ -50,7 +50,7 @@ func (ctrl *KernelModuleConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KernelModuleConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KernelModuleConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -46,7 +46,7 @@ func (ctrl *KernelModuleSpecController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *KernelModuleSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KernelModuleSpecController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer { if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer {
// not supported in container mode // not supported in container mode
return nil return nil

View File

@ -9,7 +9,6 @@ import (
"fmt" "fmt"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
@ -52,7 +51,7 @@ func (ctrl *KernelParamConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KernelParamConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KernelParamConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -72,8 +71,8 @@ func (ctrl *KernelParamConfigController) Run(ctx context.Context, r controller.R
setKernelParam := func(kind, key, value string) error { setKernelParam := func(kind, key, value string) error {
item := runtime.NewKernelParamSpec(runtime.NamespaceName, kind+"."+key) item := runtime.NewKernelParamSpec(runtime.NamespaceName, kind+"."+key)
return r.Modify(ctx, item, func(res resource.Resource) error { return safe.WriterModify(ctx, r, item, func(res *runtime.KernelParamSpec) error {
res.(*runtime.KernelParamSpec).TypedSpec().Value = value res.TypedSpec().Value = value
return nil return nil
}) })

View File

@ -10,7 +10,7 @@ import (
"os" "os"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe"
"go.uber.org/zap" "go.uber.org/zap"
v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
@ -45,7 +45,7 @@ func (ctrl *KernelParamDefaultsController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *KernelParamDefaultsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KernelParamDefaultsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return nil return nil
@ -59,8 +59,8 @@ func (ctrl *KernelParamDefaultsController) Run(ctx context.Context, r controller
value := prop.Value value := prop.Value
item := runtime.NewKernelParamDefaultSpec(runtime.NamespaceName, prop.Key) item := runtime.NewKernelParamDefaultSpec(runtime.NamespaceName, prop.Key)
if err := r.Modify(ctx, item, func(res resource.Resource) error { if err := safe.WriterModify(ctx, r, item, func(res *runtime.KernelParamDefaultSpec) error {
res.(*runtime.KernelParamDefaultSpec).TypedSpec().Value = value res.TypedSpec().Value = value
return nil return nil
}); err != nil { }); err != nil {

View File

@ -8,10 +8,12 @@ import (
"context" "context"
"errors" "errors"
"os" "os"
"slices"
"strings" "strings"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"go.uber.org/zap" "go.uber.org/zap"
@ -93,9 +95,7 @@ func (ctrl *KernelParamSpecController) Run(ctx context.Context, r controller.Run
configsCounts := len(configs.Items) configsCounts := len(configs.Items)
list := configs.Items list := slices.Concat(configs.Items, defaults.Items)
list = append(list, defaults.Items...)
touchedIDs := map[string]string{} touchedIDs := map[string]string{}
@ -117,8 +117,8 @@ func (ctrl *KernelParamSpecController) Run(ctx context.Context, r controller.Run
if errors.Is(err, os.ErrNotExist) && spec.IgnoreErrors { if errors.Is(err, os.ErrNotExist) && spec.IgnoreErrors {
status := runtime.NewKernelParamStatus(runtime.NamespaceName, id) status := runtime.NewKernelParamStatus(runtime.NamespaceName, id)
if e := r.Modify(ctx, status, func(res resource.Resource) error { if e := safe.WriterModify(ctx, r, status, func(res *runtime.KernelParamStatus) error {
res.(*runtime.KernelParamStatus).TypedSpec().Unsupported = true res.TypedSpec().Unsupported = true
return nil return nil
}); e != nil { }); e != nil {
@ -154,10 +154,7 @@ func (ctrl *KernelParamSpecController) Run(ctx context.Context, r controller.Run
} }
func (ctrl *KernelParamSpecController) updateKernelParam(ctx context.Context, r controller.Runtime, key, value string) error { func (ctrl *KernelParamSpecController) updateKernelParam(ctx context.Context, r controller.Runtime, key, value string) error {
prop := &kernel.Param{ prop := &kernel.Param{Key: key, Value: value}
Key: key,
Value: value,
}
if _, ok := ctrl.defaults[key]; !ok { if _, ok := ctrl.defaults[key]; !ok {
if data, err := krnl.ReadParam(prop); err == nil { if data, err := krnl.ReadParam(prop); err == nil {
@ -175,9 +172,9 @@ func (ctrl *KernelParamSpecController) updateKernelParam(ctx context.Context, r
status := runtime.NewKernelParamStatus(runtime.NamespaceName, key) status := runtime.NewKernelParamStatus(runtime.NamespaceName, key)
return r.Modify(ctx, status, func(res resource.Resource) error { return safe.WriterModify(ctx, r, status, func(res *runtime.KernelParamStatus) error {
res.(*runtime.KernelParamStatus).TypedSpec().Current = value res.TypedSpec().Current = value
res.(*runtime.KernelParamStatus).TypedSpec().Default = strings.TrimSpace(ctrl.defaults[key]) res.TypedSpec().Default = strings.TrimSpace(ctrl.defaults[key])
return nil return nil
}) })
@ -187,10 +184,7 @@ func (ctrl *KernelParamSpecController) resetKernelParam(ctx context.Context, r c
var err error var err error
if def, ok := ctrl.defaults[key]; ok { if def, ok := ctrl.defaults[key]; ok {
err = krnl.WriteParam(&kernel.Param{ err = krnl.WriteParam(&kernel.Param{Key: key, Value: def})
Key: key,
Value: def,
})
} else { } else {
err = krnl.DeleteParam(&kernel.Param{Key: key}) err = krnl.DeleteParam(&kernel.Param{Key: key})
} }

View File

@ -58,7 +58,7 @@ func (ctrl *KmsgLogConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KmsgLogConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) (err error) { func (ctrl *KmsgLogConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) (err error) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -48,7 +48,7 @@ func (ctrl *MachineStatusPublisherController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *MachineStatusPublisherController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MachineStatusPublisherController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -61,7 +61,7 @@ func (ctrl *MaintenanceConfigController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *MaintenanceConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MaintenanceConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -62,7 +62,7 @@ func (ctrl *SecurityStateController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *SecurityStateController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *SecurityStateController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -49,7 +49,7 @@ func (ctrl *WatchdogTimerConfigController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *WatchdogTimerConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) (err error) { func (ctrl *WatchdogTimerConfigController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) (err error) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -13,6 +13,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/crypto/x509" "github.com/siderolabs/crypto/x509"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
@ -82,7 +83,7 @@ func (ctrl *APIController) Run(ctx context.Context, r controller.Runtime, logger
return err return err
} }
machineTypeRes, err := r.Get(ctx, resource.NewMetadata(config.NamespaceName, config.MachineTypeType, config.MachineTypeID, resource.VersionUndefined)) machineTypeRes, err := safe.ReaderGet[*config.MachineType](ctx, r, resource.NewMetadata(config.NamespaceName, config.MachineTypeType, config.MachineTypeID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -91,9 +92,9 @@ func (ctrl *APIController) Run(ctx context.Context, r controller.Runtime, logger
return fmt.Errorf("error getting machine type: %w", err) return fmt.Errorf("error getting machine type: %w", err)
} }
machineType := machineTypeRes.(*config.MachineType).MachineType() machineType := machineTypeRes.MachineType()
networkResource, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.StatusType, network.StatusID, resource.VersionUndefined)) networkResource, err := safe.ReaderGet[*network.Status](ctx, r, resource.NewMetadata(network.NamespaceName, network.StatusType, network.StatusID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -102,7 +103,7 @@ func (ctrl *APIController) Run(ctx context.Context, r controller.Runtime, logger
return err return err
} }
networkStatus := networkResource.(*network.Status).TypedSpec() networkStatus := networkResource.TypedSpec()
if !(networkStatus.AddressReady && networkStatus.HostnameReady) { if !(networkStatus.AddressReady && networkStatus.HostnameReady) {
continue continue
@ -189,7 +190,7 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
case <-refreshTicker.C: case <-refreshTicker.C:
} }
machineTypeRes, err := r.Get(ctx, resource.NewMetadata(config.NamespaceName, config.MachineTypeType, config.MachineTypeID, resource.VersionUndefined)) machineTypeRes, err := safe.ReaderGet[*config.MachineType](ctx, r, resource.NewMetadata(config.NamespaceName, config.MachineTypeType, config.MachineTypeID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -198,7 +199,7 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
return fmt.Errorf("error getting machine type: %w", err) return fmt.Errorf("error getting machine type: %w", err)
} }
machineType := machineTypeRes.(*config.MachineType).MachineType() machineType := machineTypeRes.MachineType()
switch machineType { switch machineType {
case machine.TypeInit, machine.TypeControlPlane: case machine.TypeInit, machine.TypeControlPlane:
@ -215,7 +216,7 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
panic(fmt.Sprintf("unexpected machine type %v", machineType)) panic(fmt.Sprintf("unexpected machine type %v", machineType))
} }
rootResource, err := r.Get(ctx, resource.NewMetadata(secrets.NamespaceName, secrets.OSRootType, secrets.OSRootID, resource.VersionUndefined)) rootResource, err := safe.ReaderGet[*secrets.OSRoot](ctx, r, resource.NewMetadata(secrets.NamespaceName, secrets.OSRootType, secrets.OSRootID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
if err = ctrl.teardownAll(ctx, r); err != nil { if err = ctrl.teardownAll(ctx, r); err != nil {
@ -228,9 +229,9 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
return fmt.Errorf("error getting etcd root secrets: %w", err) return fmt.Errorf("error getting etcd root secrets: %w", err)
} }
rootSpec := rootResource.(*secrets.OSRoot).TypedSpec() rootSpec := rootResource.TypedSpec()
certSANResource, err := r.Get(ctx, resource.NewMetadata(secrets.NamespaceName, secrets.CertSANType, secrets.CertSANAPIID, resource.VersionUndefined)) certSANResource, err := safe.ReaderGet[*secrets.CertSAN](ctx, r, resource.NewMetadata(secrets.NamespaceName, secrets.CertSANType, secrets.CertSANAPIID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -239,7 +240,7 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
return fmt.Errorf("error getting certSANs: %w", err) return fmt.Errorf("error getting certSANs: %w", err)
} }
certSANs := certSANResource.(*secrets.CertSAN).TypedSpec() certSANs := certSANResource.TypedSpec()
var endpointsStr []string var endpointsStr []string
@ -310,9 +311,9 @@ func (ctrl *APIController) generateControlPlane(ctx context.Context, r controlle
return fmt.Errorf("failed to generate API client cert: %w", err) return fmt.Errorf("failed to generate API client cert: %w", err)
} }
if err := r.Modify(ctx, secrets.NewAPI(), if err := safe.WriterModify(ctx, r, secrets.NewAPI(),
func(r resource.Resource) error { func(r *secrets.API) error {
apiSecrets := r.(*secrets.API).TypedSpec() apiSecrets := r.TypedSpec()
apiSecrets.AcceptedCAs = rootSpec.AcceptedCAs apiSecrets.AcceptedCAs = rootSpec.AcceptedCAs
apiSecrets.Server = x509.NewCertificateAndKeyFromKeyPair(serverCert) apiSecrets.Server = x509.NewCertificateAndKeyFromKeyPair(serverCert)
@ -387,9 +388,9 @@ func (ctrl *APIController) generateWorker(ctx context.Context, r controller.Runt
return fmt.Errorf("failed to sign API server CSR: %w", err) return fmt.Errorf("failed to sign API server CSR: %w", err)
} }
if err := r.Modify(ctx, secrets.NewAPI(), if err := safe.WriterModify(ctx, r, secrets.NewAPI(),
func(r resource.Resource) error { func(r *secrets.API) error {
apiSecrets := r.(*secrets.API).TypedSpec() apiSecrets := r.TypedSpec()
apiSecrets.AcceptedCAs = []*x509.PEMEncodedCertificate{ apiSecrets.AcceptedCAs = []*x509.PEMEncodedCertificate{
{ {

View File

@ -10,6 +10,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"go.uber.org/zap" "go.uber.org/zap"
@ -66,7 +67,7 @@ func (ctrl *APICertSANsController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -74,7 +75,7 @@ func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime
case <-r.EventCh(): case <-r.EventCh():
} }
apiRootRes, err := r.Get(ctx, resource.NewMetadata(secrets.NamespaceName, secrets.OSRootType, secrets.OSRootID, resource.VersionUndefined)) apiRootRes, err := safe.ReaderGet[*secrets.OSRoot](ctx, r, resource.NewMetadata(secrets.NamespaceName, secrets.OSRootType, secrets.OSRootID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
if err = ctrl.teardownAll(ctx, r); err != nil { if err = ctrl.teardownAll(ctx, r); err != nil {
@ -87,9 +88,9 @@ func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime
return fmt.Errorf("error getting root k8s secrets: %w", err) return fmt.Errorf("error getting root k8s secrets: %w", err)
} }
apiRoot := apiRootRes.(*secrets.OSRoot).TypedSpec() apiRoot := apiRootRes.TypedSpec()
hostnameResource, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined)) hostnameResource, err := safe.ReaderGet[*network.HostnameStatus](ctx, r, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -98,9 +99,9 @@ func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime
return err return err
} }
hostnameStatus := hostnameResource.(*network.HostnameStatus).TypedSpec() hostnameStatus := hostnameResource.TypedSpec()
addressesResource, err := r.Get(ctx, addressesResource, err := safe.ReaderGet[*network.NodeAddress](ctx, r,
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined)) resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
@ -110,10 +111,10 @@ func (ctrl *APICertSANsController) Run(ctx context.Context, r controller.Runtime
return err return err
} }
nodeAddresses := addressesResource.(*network.NodeAddress).TypedSpec() nodeAddresses := addressesResource.TypedSpec()
if err = r.Modify(ctx, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANAPIID), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANAPIID), func(r *secrets.CertSAN) error {
spec := r.(*secrets.CertSAN).TypedSpec() spec := r.TypedSpec()
spec.Reset() spec.Reset()

View File

@ -80,7 +80,7 @@ func (ctrl *EtcdController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *EtcdController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *EtcdController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -120,7 +120,7 @@ func (ctrl *EtcdController) Run(ctx context.Context, r controller.Runtime, logge
} }
// wait for time sync as certs depend on current time // wait for time sync as certs depend on current time
timeSyncResource, err := r.Get(ctx, resource.NewMetadata(v1alpha1.NamespaceName, time.StatusType, time.StatusID, resource.VersionUndefined)) timeSyncResource, err := safe.ReaderGet[*time.Status](ctx, r, resource.NewMetadata(v1alpha1.NamespaceName, time.StatusType, time.StatusID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -129,7 +129,7 @@ func (ctrl *EtcdController) Run(ctx context.Context, r controller.Runtime, logge
return err return err
} }
if !timeSyncResource.(*time.Status).TypedSpec().Synced { if !timeSyncResource.TypedSpec().Synced {
continue continue
} }

View File

@ -71,7 +71,7 @@ func (ctrl *KubernetesController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KubernetesController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubernetesController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
refreshTicker := time.NewTicker(KubernetesCertificateValidityDuration / 2) refreshTicker := time.NewTicker(KubernetesCertificateValidityDuration / 2)
defer refreshTicker.Stop() defer refreshTicker.Stop()

View File

@ -11,6 +11,7 @@ import (
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
"go.uber.org/zap" "go.uber.org/zap"
@ -67,7 +68,7 @@ func (ctrl *KubernetesCertSANsController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo //nolint:gocyclo
func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -75,7 +76,7 @@ func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.
case <-r.EventCh(): case <-r.EventCh():
} }
k8sRootRes, err := r.Get(ctx, resource.NewMetadata(secrets.NamespaceName, secrets.KubernetesRootType, secrets.KubernetesRootID, resource.VersionUndefined)) k8sRootRes, err := safe.ReaderGet[*secrets.KubernetesRoot](ctx, r, resource.NewMetadata(secrets.NamespaceName, secrets.KubernetesRootType, secrets.KubernetesRootID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
if err = ctrl.teardownAll(ctx, r); err != nil { if err = ctrl.teardownAll(ctx, r); err != nil {
@ -88,9 +89,9 @@ func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.
return fmt.Errorf("error getting root k8s secrets: %w", err) return fmt.Errorf("error getting root k8s secrets: %w", err)
} }
k8sRoot := k8sRootRes.(*secrets.KubernetesRoot).TypedSpec() k8sRoot := k8sRootRes.TypedSpec()
hostnameResource, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined)) hostnameResource, err := safe.ReaderGet[*network.HostnameStatus](ctx, r, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
continue continue
@ -99,9 +100,10 @@ func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.
return err return err
} }
hostnameStatus := hostnameResource.(*network.HostnameStatus).TypedSpec() hostnameStatus := hostnameResource.TypedSpec()
addressesResource, err := r.Get(ctx, addressesResource, err := safe.ReaderGet[*network.NodeAddress](ctx,
r,
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined)) resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined))
if err != nil { if err != nil {
if state.IsNotFoundError(err) { if state.IsNotFoundError(err) {
@ -111,10 +113,10 @@ func (ctrl *KubernetesCertSANsController) Run(ctx context.Context, r controller.
return err return err
} }
nodeAddresses := addressesResource.(*network.NodeAddress).TypedSpec() nodeAddresses := addressesResource.TypedSpec()
if err = r.Modify(ctx, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANKubernetesID), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANKubernetesID), func(r *secrets.CertSAN) error {
spec := r.(*secrets.CertSAN).TypedSpec() spec := r.TypedSpec()
spec.Reset() spec.Reset()

View File

@ -51,7 +51,7 @@ func (ctrl *KubernetesDynamicCertsController) Outputs() []controller.Output {
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
// //
//nolint:gocyclo,cyclop //nolint:gocyclo,cyclop
func (ctrl *KubernetesDynamicCertsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *KubernetesDynamicCertsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
// wait for the network to be ready first, then switch to regular inputs // wait for the network to be ready first, then switch to regular inputs
if err := r.UpdateInputs([]controller.Input{ if err := r.UpdateInputs([]controller.Input{
{ {

View File

@ -10,7 +10,6 @@ import (
"net/netip" "net/netip"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/optional" "github.com/siderolabs/gen/optional"
@ -58,7 +57,7 @@ func (ctrl *MaintenanceCertSANsController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *MaintenanceCertSANsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MaintenanceCertSANsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -80,8 +79,8 @@ func (ctrl *MaintenanceCertSANsController) Run(ctx context.Context, r controller
return err return err
} }
if err = r.Modify(ctx, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANMaintenanceID), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANMaintenanceID), func(r *secrets.CertSAN) error {
spec := r.(*secrets.CertSAN).TypedSpec() spec := r.TypedSpec()
spec.Reset() spec.Reset()

View File

@ -40,7 +40,7 @@ func (ctrl *MaintenanceRootController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *MaintenanceRootController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *MaintenanceRootController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
// run this controller only once, as the CA never changes // run this controller only once, as the CA never changes
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -56,7 +56,7 @@ func (ctrl *TrustedRootsController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *TrustedRootsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *TrustedRootsController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@ -45,7 +45,7 @@ func (ctrl *AdjtimeStatusController) Outputs() []controller.Output {
} }
// Run implements controller.Controller interface. // Run implements controller.Controller interface.
func (ctrl *AdjtimeStatusController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { func (ctrl *AdjtimeStatusController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error {
if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer { if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer {
// in container mode, clock is managed by the host // in container mode, clock is managed by the host
return nil return nil

View File

@ -132,7 +132,11 @@ func (ctrl *SyncController) Run(ctx context.Context, r controller.Runtime, logge
timeSyncTimeoutTimer = nil timeSyncTimeoutTimer = nil
} }
timeServersStatus, err := r.Get(ctx, resource.NewMetadata(network.NamespaceName, network.TimeServerStatusType, network.TimeServerID, resource.VersionUndefined)) timeServersStatus, err := safe.ReaderGet[*network.TimeServerStatus](
ctx,
r,
resource.NewMetadata(network.NamespaceName, network.TimeServerStatusType, network.TimeServerID, resource.VersionUndefined),
)
if err != nil { if err != nil {
if !state.IsNotFoundError(err) { if !state.IsNotFoundError(err) {
return fmt.Errorf("error getting time server status: %w", err) return fmt.Errorf("error getting time server status: %w", err)
@ -142,7 +146,7 @@ func (ctrl *SyncController) Run(ctx context.Context, r controller.Runtime, logge
continue continue
} }
timeServers := timeServersStatus.(*network.TimeServerStatus).TypedSpec().NTPServers timeServers := timeServersStatus.TypedSpec().NTPServers
cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID) cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID)
if err != nil { if err != nil {
@ -227,8 +231,8 @@ func (ctrl *SyncController) Run(ctx context.Context, r controller.Runtime, logge
timeSynced = true timeSynced = true
} }
if err = r.Modify(ctx, time.NewStatus(), func(r resource.Resource) error { if err = safe.WriterModify(ctx, r, time.NewStatus(), func(r *time.Status) error {
*r.(*time.Status).TypedSpec() = time.StatusSpec{ *r.TypedSpec() = time.StatusSpec{
Epoch: epoch, Epoch: epoch,
Synced: timeSynced, Synced: timeSynced,
SyncDisabled: syncDisabled, SyncDisabled: syncDisabled,

View File

@ -9,7 +9,7 @@ import (
"sync" "sync"
"github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
"go.uber.org/zap" "go.uber.org/zap"
@ -74,9 +74,7 @@ func (ctrl *ServiceController) Run(ctx context.Context, r controller.Runtime, lo
switch msg.Action { //nolint:exhaustive switch msg.Action { //nolint:exhaustive
case machine.ServiceStateEvent_RUNNING: case machine.ServiceStateEvent_RUNNING:
if err := r.Modify(ctx, service, func(r resource.Resource) error { if err := safe.WriterModify(ctx, r, service, func(svc *v1alpha1.Service) error {
svc := r.(*v1alpha1.Service) //nolint:errcheck,forcetypeassert
*svc.TypedSpec() = v1alpha1.ServiceSpec{ *svc.TypedSpec() = v1alpha1.ServiceSpec{
Running: true, Running: true,
Healthy: msg.GetHealth().GetHealthy(), Healthy: msg.GetHealth().GetHealthy(),

View File

@ -195,12 +195,16 @@ func (r *Runtime) Logging() runtime.LoggingManager {
// NodeName implements the Runtime interface. // NodeName implements the Runtime interface.
func (r *Runtime) NodeName() (string, error) { func (r *Runtime) NodeName() (string, error) {
nodenameResource, err := r.s.V1Alpha2().Resources().Get(context.Background(), resource.NewMetadata(k8s.NamespaceName, k8s.NodenameType, k8s.NodenameID, resource.VersionUndefined)) nodenameResource, err := safe.ReaderGet[*k8s.Nodename](
context.Background(),
r.s.V1Alpha2().Resources(),
resource.NewMetadata(k8s.NamespaceName, k8s.NodenameType, k8s.NodenameID, resource.VersionUndefined),
)
if err != nil { if err != nil {
return "", fmt.Errorf("error getting nodename resource: %w", err) return "", fmt.Errorf("error getting nodename resource: %w", err)
} }
return nodenameResource.(*k8s.Nodename).TypedSpec().Nodename, nil return nodenameResource.TypedSpec().Nodename, nil
} }
// IsBootstrapAllowed checks for CRI to be up, checked in the bootstrap method. // IsBootstrapAllowed checks for CRI to be up, checked in the bootstrap method.

View File

@ -76,7 +76,7 @@ type Etcd struct {
} }
// ID implements the Service interface. // ID implements the Service interface.
func (e *Etcd) ID(r runtime.Runtime) string { func (e *Etcd) ID(runtime.Runtime) string {
return "etcd" return "etcd"
} }
@ -149,7 +149,7 @@ func (e *Etcd) PreFunc(ctx context.Context, r runtime.Runtime) error {
} }
// PostFunc implements the Service interface. // PostFunc implements the Service interface.
func (e *Etcd) PostFunc(r runtime.Runtime, state events.ServiceState) (err error) { func (e *Etcd) PostFunc(runtime.Runtime, events.ServiceState) (err error) {
if e.promoteCtxCancel != nil { if e.promoteCtxCancel != nil {
e.promoteCtxCancel() e.promoteCtxCancel()
} }
@ -173,7 +173,7 @@ func (e *Etcd) Condition(r runtime.Runtime) conditions.Condition {
} }
// DependsOn implements the Service interface. // DependsOn implements the Service interface.
func (e *Etcd) DependsOn(r runtime.Runtime) []string { func (e *Etcd) DependsOn(runtime.Runtime) []string {
return []string{"cri"} return []string{"cri"}
} }
@ -330,12 +330,15 @@ func buildInitialCluster(ctx context.Context, r runtime.Runtime, name string, pe
// we "allow" a failure here since we want to fallthrough and attempt to add the etcd member regardless of // we "allow" a failure here since we want to fallthrough and attempt to add the etcd member regardless of
// whether we can print our IPs // whether we can print our IPs
currentAddresses, addrErr := r.State().V1Alpha2().Resources().Get(ctx, currentAddresses, addrErr := safe.ReaderGet[*network.NodeAddress](
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined)) ctx,
r.State().V1Alpha2().Resources(),
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s), resource.VersionUndefined),
)
if addrErr != nil { if addrErr != nil {
log.Printf("error getting node addresses: %s", addrErr.Error()) log.Printf("error getting node addresses: %s", addrErr.Error())
} else { } else {
ips := currentAddresses.(*network.NodeAddress).TypedSpec().IPs() ips := currentAddresses.TypedSpec().IPs()
log.Printf("%s", ips) log.Printf("%s", ips)
} }
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/containerd/containerd/v2/pkg/namespaces" "github.com/containerd/containerd/v2/pkg/namespaces"
"github.com/containerd/containerd/v2/pkg/oci" "github.com/containerd/containerd/v2/pkg/oci"
"github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
@ -45,18 +46,18 @@ type Kubelet struct {
} }
// ID implements the Service interface. // ID implements the Service interface.
func (k *Kubelet) ID(r runtime.Runtime) string { func (k *Kubelet) ID(runtime.Runtime) string {
return "kubelet" return "kubelet"
} }
// PreFunc implements the Service interface. // PreFunc implements the Service interface.
func (k *Kubelet) PreFunc(ctx context.Context, r runtime.Runtime) error { func (k *Kubelet) PreFunc(ctx context.Context, r runtime.Runtime) error {
specResource, err := r.State().V1Alpha2().Resources().Get(ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined)) specResource, err := safe.ReaderGet[*k8s.KubeletSpec](ctx, r.State().V1Alpha2().Resources(), resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined))
if err != nil { if err != nil {
return err return err
} }
spec := specResource.(*k8s.KubeletSpec).TypedSpec() spec := specResource.TypedSpec()
client, err := containerdapi.New(constants.CRIContainerdAddress) client, err := containerdapi.New(constants.CRIContainerdAddress)
if err != nil { if err != nil {
@ -85,7 +86,7 @@ func (k *Kubelet) PreFunc(ctx context.Context, r runtime.Runtime) error {
} }
// PostFunc implements the Service interface. // PostFunc implements the Service interface.
func (k *Kubelet) PostFunc(r runtime.Runtime, state events.ServiceState) (err error) { func (k *Kubelet) PostFunc(runtime.Runtime, events.ServiceState) (err error) {
return nil return nil
} }
@ -98,18 +99,22 @@ func (k *Kubelet) Condition(r runtime.Runtime) conditions.Condition {
} }
// DependsOn implements the Service interface. // DependsOn implements the Service interface.
func (k *Kubelet) DependsOn(r runtime.Runtime) []string { func (k *Kubelet) DependsOn(runtime.Runtime) []string {
return []string{"cri"} return []string{"cri"}
} }
// Runner implements the Service interface. // Runner implements the Service interface.
func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) { func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) {
specResource, err := r.State().V1Alpha2().Resources().Get(context.Background(), resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined)) specResource, err := safe.ReaderGet[*k8s.KubeletSpec](
context.Background(),
r.State().V1Alpha2().Resources(),
resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined),
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
spec := specResource.(*k8s.KubeletSpec).TypedSpec() spec := specResource.TypedSpec()
// Set the process arguments. // Set the process arguments.
args := runner.Args{ args := runner.Args{

Some files were not shown because too many files have changed in this diff Show More