diff --git a/upup/pkg/fi/BUILD.bazel b/upup/pkg/fi/BUILD.bazel index a05e82c9dfa3a..7596a67eef5d3 100644 --- a/upup/pkg/fi/BUILD.bazel +++ b/upup/pkg/fi/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "executor.go", "files.go", "files_owner.go", + "files_owner_windows.go", "has_address.go", "http.go", "lifecycle.go", diff --git a/upup/pkg/fi/files.go b/upup/pkg/fi/files.go index 4a758ccbcde9e..5f4f94731b0b4 100644 --- a/upup/pkg/fi/files.go +++ b/upup/pkg/fi/files.go @@ -29,7 +29,8 @@ import ( "k8s.io/kops/util/pkg/hashing" ) -func WriteFile(destPath string, contents Resource, fileMode os.FileMode, dirMode os.FileMode) error { +// WriteFile writes a file to the specified path, setting the mode, owner & group. +func WriteFile(destPath string, contents Resource, fileMode os.FileMode, dirMode os.FileMode, owner string, group string) error { err := os.MkdirAll(path.Dir(destPath), dirMode) if err != nil { return fmt.Errorf("error creating directories for destination file %q: %v", destPath, err) @@ -45,6 +46,11 @@ func WriteFile(destPath string, contents Resource, fileMode os.FileMode, dirMode return err } + _, err = EnsureFileOwner(destPath, owner, group) + if err != nil { + return err + } + return nil } diff --git a/upup/pkg/fi/files_owner.go b/upup/pkg/fi/files_owner.go index 2bcec53f4af08..029ad1fb6c5a5 100644 --- a/upup/pkg/fi/files_owner.go +++ b/upup/pkg/fi/files_owner.go @@ -26,6 +26,8 @@ import ( "k8s.io/klog/v2" ) +// EnsureFileOwner will set the owner & group for a file. +// Empty values for owner/group will leave the owner/group unchanged. func EnsureFileOwner(destPath string, owner string, groupName string) (bool, error) { changed := false stat, err := os.Lstat(destPath) diff --git a/upup/pkg/fi/files_owner_windows.go b/upup/pkg/fi/files_owner_windows.go new file mode 100644 index 0000000000000..e7b8dba73a74a --- /dev/null +++ b/upup/pkg/fi/files_owner_windows.go @@ -0,0 +1,24 @@ +// +build windows + +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fi + +// EnsureFileOwner dummy version for Windows +func EnsureFileOwner(destPath string, owner string, groupName string) (bool, error) { + return false, nil +} diff --git a/upup/pkg/fi/files_test.go b/upup/pkg/fi/files_test.go index 301e34420f344..d16776b785033 100644 --- a/upup/pkg/fi/files_test.go +++ b/upup/pkg/fi/files_test.go @@ -56,7 +56,7 @@ func TestWriteFile(t *testing.T) { }, } for _, test := range tests { - err := WriteFile(test.path, NewBytesResource(test.data), test.fileMode, test.dirMode) + err := WriteFile(test.path, NewBytesResource(test.data), test.fileMode, test.dirMode, "", "") if err != nil { t.Errorf("Error writing file {%s}, error: {%v}", test.path, err) continue diff --git a/upup/pkg/fi/nodeup/nodetasks/file.go b/upup/pkg/fi/nodeup/nodetasks/file.go index d6fab0a7fcdfd..fc132b0c6a9ec 100644 --- a/upup/pkg/fi/nodeup/nodetasks/file.go +++ b/upup/pkg/fi/nodeup/nodetasks/file.go @@ -234,7 +234,7 @@ func (_ *File) RenderLocal(t *local.LocalTarget, a, e, changes *File) error { } } else if e.Type == FileType_File { if changes.Contents != nil { - err = fi.WriteFile(e.Path, e.Contents, fileMode, dirMode) + err = fi.WriteFile(e.Path, e.Contents, fileMode, dirMode, fi.StringValue(e.Owner), fi.StringValue(e.Group)) if err != nil { return fmt.Errorf("error copying file %q: %v", e.Path, err) } diff --git a/upup/pkg/fi/nodeup/nodetasks/service.go b/upup/pkg/fi/nodeup/nodetasks/service.go index a7a1e50fc522a..06a24cf1134ca 100644 --- a/upup/pkg/fi/nodeup/nodetasks/service.go +++ b/upup/pkg/fi/nodeup/nodetasks/service.go @@ -278,7 +278,7 @@ func (_ *Service) RenderLocal(t *local.LocalTarget, a, e, changes *Service) erro if changes.Definition != nil { servicePath := path.Join(systemdSystemPath, serviceName) - err := fi.WriteFile(servicePath, fi.NewStringResource(*e.Definition), 0644, 0755) + err := fi.WriteFile(servicePath, fi.NewStringResource(*e.Definition), 0644, 0755, "", "") if err != nil { return fmt.Errorf("error writing systemd service file: %v", err) }