diff --git a/embed/ansible/kubitect/requirements.txt b/embed/ansible/kubitect/requirements.txt index 0719cdf1..44fdf63b 100644 --- a/embed/ansible/kubitect/requirements.txt +++ b/embed/ansible/kubitect/requirements.txt @@ -1,4 +1,4 @@ -ansible==5.8.0 -ansible-core==2.12.5 +ansible==8.5.0 +ansible-core==2.16.2 jinja2==3.1.2 -netaddr==0.7.19 +netaddr==0.9.0 diff --git a/pkg/cluster/executors/kubespray/kubespray.go b/pkg/cluster/executors/kubespray/kubespray.go index 7e288224..3f83cb81 100644 --- a/pkg/cluster/executors/kubespray/kubespray.go +++ b/pkg/cluster/executors/kubespray/kubespray.go @@ -14,6 +14,7 @@ import ( "github.com/MusicDin/kubitect/pkg/tools/git" "github.com/MusicDin/kubitect/pkg/tools/virtualenv" "github.com/MusicDin/kubitect/pkg/ui" + "github.com/MusicDin/kubitect/pkg/utils/file" "gopkg.in/yaml.v3" ) @@ -82,6 +83,14 @@ func (e *kubespray) Init() error { return err } + // Patch: There is an issue with unsafe conditionals in + // Kubespray with ansible-core version > 2.14.11. + reqPath := path.Join(dst, "requirements.txt") + reqPatch := []byte("ansible-core==2.14.11") + if err := file.Append(reqPath, reqPatch); err != nil { + return err + } + if err := e.VirtualEnv.Init(); err != nil { return fmt.Errorf("kubespray exec: initialize virtual environment: %v", err) } diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index f2a818a9..f454d780 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -3,7 +3,6 @@ package file import ( "fmt" "io/fs" - "io/ioutil" "os" "path" @@ -19,7 +18,7 @@ func Exists(path string) bool { // Read reads file on a given path and returns its content as a string. func Read(path string) (string, error) { - file, err := ioutil.ReadFile(path) + file, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("read file '%s': %v", path, err) @@ -39,11 +38,23 @@ func Copy(srcPath, dstPath string, mode fs.FileMode) error { return ForceCopy(srcPath, dstPath, mode) } +// Append appends the provided byte content with an additional new line to the file. +func Append(path string, content []byte) error { + file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm) + if err != nil { + return err + } + defer file.Close() + + _, err = file.Write(append(content, '\n')) + return err +} + // ForceCopy reads the file located at the source path and writes it to the // destination path with the specified permissions. All required subdirectories // are also created. func ForceCopy(srcPath, dstPath string, mode fs.FileMode) error { - file, err := ioutil.ReadFile(srcPath) + file, err := os.ReadFile(srcPath) if err != nil { return fmt.Errorf("copy file: %v", err) } @@ -63,7 +74,7 @@ func ForceCopy(srcPath, dstPath string, mode fs.FileMode) error { // ReadYaml reads yaml file on the given path and unmarshals it into the given // type. func ReadYaml[T interface{}](path string, typ T) (*T, error) { - yml, err := ioutil.ReadFile(path) + yml, err := os.ReadFile(path) if err != nil { return nil, err } @@ -79,5 +90,5 @@ func WriteYaml(obj interface{}, path string, perm fs.FileMode) error { return err } - return ioutil.WriteFile(path, yml, perm) + return os.WriteFile(path, yml, perm) } diff --git a/pkg/utils/file/file_test.go b/pkg/utils/file/file_test.go index 4ce67bb1..ed4a24a2 100644 --- a/pkg/utils/file/file_test.go +++ b/pkg/utils/file/file_test.go @@ -85,6 +85,18 @@ func TestForceCopy(t *testing.T) { assert.Equal(t, "source", out) } +func TestAppend(t *testing.T) { + src := tmpFile(t, "src.file", "source\n") + + require.NoError(t, Append(src, []byte("test"))) + require.NoError(t, Append(src, []byte("x=1.2.3"))) + require.NoError(t, Append(src, []byte("$ \n \\ "))) + + out, err := Read(src) + require.NoError(t, err) + assert.Equal(t, "source\ntest\nx=1.2.3\n$ \n \\ \n", out) +} + func TestWriteYaml(t *testing.T) { type T struct { Value int `yaml:"value"`