Fix binary data, Add tests, Error management #91
@@ -1,7 +1,5 @@
|
|||||||
|
|
||||||
<div style="text-align:center; margin: auto 0 4em 0" align="center">
|
<div style="text-align:center; margin: auto 0 4em 0" align="center">
|
||||||
<img src="./doc/docs/statics/logo-vertical.svg" alt="Katenary Logo" style="max-width: 90%" align="center"/>
|
<img src="./doc/docs/statics/logo-vertical.svg" alt="Katenary Logo" style="max-width: 90%" align="center"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
[](https://katenary.readthedocs.io/en/latest/?badge=latest)
|
[](https://katenary.readthedocs.io/en/latest/?badge=latest)
|
||||||
@@ -262,7 +260,7 @@ return {
|
|||||||
settings = {
|
settings = {
|
||||||
yaml = {
|
yaml = {
|
||||||
schemas = {
|
schemas = {
|
||||||
["https://raw.githubusercontent.com/metal3d/katenary/refs/heads/master/katenary.json"] = "katenary.yaml",
|
["https://raw.githubusercontent.com/metal3d/katenary/master/katenary.json"] = "katenary.yaml",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -278,12 +276,12 @@ Use this address to validate the `katenary.yaml` file in VSCode:
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"yaml.schemas": {
|
"yaml.schemas": {
|
||||||
"https://raw.githubusercontent.com/metal3d/katenary/refs/heads/master/katenary.json": "katenary.yaml"
|
"https://raw.githubusercontent.com/metal3d/katenary/master/katenary.json": "katenary.yaml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> You can, of course, replace the `refs/heads/master` with a specific tag or branch.
|
> You can, of course, replace the `master` with a specific tag or branch.
|
||||||
|
|
||||||
## What a name…
|
## What a name…
|
||||||
|
|
||||||
|
@@ -141,11 +141,11 @@ func generateConvertCommand() *cobra.Command {
|
|||||||
convertCmd := &cobra.Command{
|
convertCmd := &cobra.Command{
|
||||||
Use: "convert",
|
Use: "convert",
|
||||||
Short: "Converts a docker-compose file to a Helm Chart",
|
Short: "Converts a docker-compose file to a Helm Chart",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if givenAppVersion != "" {
|
if givenAppVersion != "" {
|
||||||
appVersion = &givenAppVersion
|
appVersion = &givenAppVersion
|
||||||
}
|
}
|
||||||
generator.Convert(generator.ConvertOptions{
|
return generator.Convert(generator.ConvertOptions{
|
||||||
Force: force,
|
Force: force,
|
||||||
OutputDir: outputDir,
|
OutputDir: outputDir,
|
||||||
Profiles: profiles,
|
Profiles: profiles,
|
||||||
|
@@ -119,7 +119,7 @@ type ChartTemplate struct {
|
|||||||
```
|
```
|
||||||
|
|
||||||
<a name="ConfigMap"></a>
|
<a name="ConfigMap"></a>
|
||||||
## type [ConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L35-L40>)
|
## type [ConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L36-L41>)
|
||||||
|
|
||||||
ConfigMap is a kubernetes ConfigMap. Implements the DataMap interface.
|
ConfigMap is a kubernetes ConfigMap. Implements the DataMap interface.
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ type ConfigMap struct {
|
|||||||
```
|
```
|
||||||
|
|
||||||
<a name="NewConfigMap"></a>
|
<a name="NewConfigMap"></a>
|
||||||
### func [NewConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L44>)
|
### func [NewConfigMap](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L45>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *ConfigMap
|
func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *ConfigMap
|
||||||
@@ -140,7 +140,7 @@ func NewConfigMap(service types.ServiceConfig, appName string, forFile bool) *Co
|
|||||||
NewConfigMap creates a new ConfigMap from a compose service. The appName is the name of the application taken from the project name. The ConfigMap is filled by environment variables and labels "map\-env".
|
NewConfigMap creates a new ConfigMap from a compose service. The appName is the name of the application taken from the project name. The ConfigMap is filled by environment variables and labels "map\-env".
|
||||||
|
|
||||||
<a name="NewConfigMapFromDirectory"></a>
|
<a name="NewConfigMapFromDirectory"></a>
|
||||||
### func [NewConfigMapFromDirectory](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L117>)
|
### func [NewConfigMapFromDirectory](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L118>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap
|
func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string) *ConfigMap
|
||||||
@@ -148,8 +148,17 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string
|
|||||||
|
|
||||||
NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps.
|
NewConfigMapFromDirectory creates a new ConfigMap from a compose service. This path is the path to the file or directory. If the path is a directory, all files in the directory are added to the ConfigMap. Each subdirectory are ignored. Note that the Generate\(\) function will create the subdirectories ConfigMaps.
|
||||||
|
|
||||||
|
<a name="ConfigMap.AddBinaryData"></a>
|
||||||
|
### func \(\*ConfigMap\) [AddBinaryData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L154>)
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *ConfigMap) AddBinaryData(key string, value []byte)
|
||||||
|
```
|
||||||
|
|
||||||
|
AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists.
|
||||||
|
|
||||||
<a name="ConfigMap.AddData"></a>
|
<a name="ConfigMap.AddData"></a>
|
||||||
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L148>)
|
### func \(\*ConfigMap\) [AddData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L149>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *ConfigMap) AddData(key, value string)
|
func (c *ConfigMap) AddData(key, value string)
|
||||||
@@ -157,17 +166,8 @@ func (c *ConfigMap) AddData(key, value string)
|
|||||||
|
|
||||||
AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
|
AddData adds a key value pair to the configmap. Append or overwrite the value if the key already exists.
|
||||||
|
|
||||||
<a name="ConfigMap.AppendDir"></a>
|
|
||||||
### func \(\*ConfigMap\) [AppendDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L154>)
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (c *ConfigMap) AppendDir(path string)
|
|
||||||
```
|
|
||||||
|
|
||||||
AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, you need to call this function for each subdirectory.
|
|
||||||
|
|
||||||
<a name="ConfigMap.AppendFile"></a>
|
<a name="ConfigMap.AppendFile"></a>
|
||||||
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L189>)
|
### func \(\*ConfigMap\) [AppendFile](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L209>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *ConfigMap) AppendFile(path string)
|
func (c *ConfigMap) AppendFile(path string)
|
||||||
@@ -175,8 +175,17 @@ func (c *ConfigMap) AppendFile(path string)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="ConfigMap.AppenddDir"></a>
|
||||||
|
### func \(\*ConfigMap\) [AppenddDir](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L163>)
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (c *ConfigMap) AppenddDir(path string)
|
||||||
|
```
|
||||||
|
|
||||||
|
AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, you need to call this function for each subdirectory.
|
||||||
|
|
||||||
<a name="ConfigMap.Filename"></a>
|
<a name="ConfigMap.Filename"></a>
|
||||||
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L207>)
|
### func \(\*ConfigMap\) [Filename](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L232>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *ConfigMap) Filename() string
|
func (c *ConfigMap) Filename() string
|
||||||
@@ -185,7 +194,7 @@ func (c *ConfigMap) Filename() string
|
|||||||
Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
|
Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
|
||||||
|
|
||||||
<a name="ConfigMap.SetData"></a>
|
<a name="ConfigMap.SetData"></a>
|
||||||
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L217>)
|
### func \(\*ConfigMap\) [SetData](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L242>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *ConfigMap) SetData(data map[string]string)
|
func (c *ConfigMap) SetData(data map[string]string)
|
||||||
@@ -194,7 +203,7 @@ func (c *ConfigMap) SetData(data map[string]string)
|
|||||||
SetData sets the data of the configmap. It replaces the entire data.
|
SetData sets the data of the configmap. It replaces the entire data.
|
||||||
|
|
||||||
<a name="ConfigMap.Yaml"></a>
|
<a name="ConfigMap.Yaml"></a>
|
||||||
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L222>)
|
### func \(\*ConfigMap\) [Yaml](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L247>)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *ConfigMap) Yaml() ([]byte, error)
|
func (c *ConfigMap) Yaml() ([]byte, error)
|
||||||
@@ -421,7 +430,7 @@ func (d *Deployment) Yaml() ([]byte, error)
|
|||||||
Yaml returns the yaml representation of the deployment.
|
Yaml returns the yaml representation of the deployment.
|
||||||
|
|
||||||
<a name="FileMapUsage"></a>
|
<a name="FileMapUsage"></a>
|
||||||
## type [FileMapUsage](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L19>)
|
## type [FileMapUsage](<https://github.com/metal3d/katenary/blob/develop/generator/configMap.go#L20>)
|
||||||
|
|
||||||
FileMapUsage is the usage of the filemap.
|
FileMapUsage is the usage of the filemap.
|
||||||
|
|
||||||
|
@@ -196,13 +196,13 @@ type Icon string
|
|||||||
const (
|
const (
|
||||||
IconSuccess Icon = "✅"
|
IconSuccess Icon = "✅"
|
||||||
IconFailure Icon = "❌"
|
IconFailure Icon = "❌"
|
||||||
IconWarning Icon = "⚠️'"
|
IconWarning Icon = "❕"
|
||||||
IconNote Icon = "📝"
|
IconNote Icon = "📝"
|
||||||
IconWorld Icon = "🌐"
|
IconWorld Icon = "🌐"
|
||||||
IconPlug Icon = "🔌"
|
IconPlug Icon = "🔌"
|
||||||
IconPackage Icon = "📦"
|
IconPackage Icon = "📦"
|
||||||
IconCabinet Icon = "🗄️"
|
IconCabinet Icon = "🗄️"
|
||||||
IconInfo Icon = "❕"
|
IconInfo Icon = "🔵"
|
||||||
IconSecret Icon = "🔒"
|
IconSecret Icon = "🔒"
|
||||||
IconConfig Icon = "🔧"
|
IconConfig Icon = "🔧"
|
||||||
IconDependency Icon = "🔗"
|
IconDependency Icon = "🔗"
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"katenary/generator/labels"
|
"katenary/generator/labels"
|
||||||
"katenary/generator/labels/labelStructs"
|
"katenary/generator/labels/labelStructs"
|
||||||
"katenary/utils"
|
"katenary/utils"
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -149,58 +151,84 @@ func (c *ConfigMap) AddData(key, value string) {
|
|||||||
c.Data[key] = value
|
c.Data[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists.
|
||||||
|
func (c *ConfigMap) AddBinaryData(key string, value []byte) {
|
||||||
|
if c.BinaryData == nil {
|
||||||
|
c.BinaryData = make(map[string][]byte)
|
||||||
|
}
|
||||||
|
c.BinaryData[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
// AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory,
|
// AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory,
|
||||||
// you need to call this function for each subdirectory.
|
// you need to call this function for each subdirectory.
|
||||||
func (c *ConfigMap) AppendDir(path string) {
|
func (c *ConfigMap) AppendDir(path string) error {
|
||||||
// read all files in the path and add them to the configmap
|
// read all files in the path and add them to the configmap
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Path %s does not exist\n", path)
|
return fmt.Errorf("Path %s does not exist, %w\n", path, err)
|
||||||
}
|
}
|
||||||
// recursively read all files in the path and add them to the configmap
|
// recursively read all files in the path and add them to the configmap
|
||||||
if stat.IsDir() {
|
if stat.IsDir() {
|
||||||
files, err := os.ReadDir(path)
|
files, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if file.IsDir() {
|
if file.IsDir() {
|
||||||
|
utils.Warn("Subdirectories are ignored for the moment, skipping", filepath.Join(path, file.Name()))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
path := filepath.Join(path, file.Name())
|
path := filepath.Join(path, file.Name())
|
||||||
content, err := os.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
// remove the path from the file
|
// remove the path from the file
|
||||||
filename := filepath.Base(path)
|
filename := filepath.Base(path)
|
||||||
c.AddData(filename, string(content))
|
if utf8.Valid(content) {
|
||||||
|
c.AddData(filename, string(content))
|
||||||
|
} else {
|
||||||
|
c.AddBinaryData(filename, content)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// add the file to the configmap
|
// add the file to the configmap
|
||||||
content, err := os.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
|
}
|
||||||
|
filename := filepath.Base(path)
|
||||||
|
if utf8.Valid(content) {
|
||||||
|
c.AddData(filename, string(content))
|
||||||
|
} else {
|
||||||
|
c.AddBinaryData(filename, content)
|
||||||
}
|
}
|
||||||
c.AddData(filepath.Base(path), string(content))
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigMap) AppendFile(path string) {
|
func (c *ConfigMap) AppendFile(path string) error {
|
||||||
// read all files in the path and add them to the configmap
|
// read all files in the path and add them to the configmap
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Path %s does not exist\n", path)
|
return fmt.Errorf("Path %s doesn not exists, %w", path, err)
|
||||||
}
|
}
|
||||||
// recursively read all files in the path and add them to the configmap
|
// recursively read all files in the path and add them to the configmap
|
||||||
if !stat.IsDir() {
|
if !stat.IsDir() {
|
||||||
// add the file to the configmap
|
// add the file to the configmap
|
||||||
content, err := os.ReadFile(path)
|
content, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
c.AddData(filepath.Base(path), string(content))
|
if utf8.Valid(content) {
|
||||||
|
c.AddData(filepath.Base(path), string(content))
|
||||||
|
} else {
|
||||||
|
c.AddBinaryData(filepath.Base(path), content)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
|
// Filename returns the filename of the configmap. If the configmap is used for files, the filename contains the path.
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
@@ -73,3 +74,19 @@ services:
|
|||||||
t.Errorf("Expected FOO to be baz, got %s", v)
|
t.Errorf("Expected FOO to be baz, got %s", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppendBadFile(t *testing.T) {
|
||||||
|
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
|
||||||
|
err := cm.AppendFile("foo")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, got nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendBadDir(t *testing.T) {
|
||||||
|
cm := NewConfigMap(types.ServiceConfig{}, "app", true)
|
||||||
|
err := cm.AppendDir("foo")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, got nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -90,7 +90,7 @@ var keyRegExp = regexp.MustCompile(`^\s*[^#]+:.*`)
|
|||||||
|
|
||||||
// Convert a compose (docker, podman...) project to a helm chart.
|
// Convert a compose (docker, podman...) project to a helm chart.
|
||||||
// It calls Generate() to generate the chart and then write it to the disk.
|
// It calls Generate() to generate the chart and then write it to the disk.
|
||||||
func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
func Convert(config ConvertOptions, dockerComposeFile ...string) error {
|
||||||
var (
|
var (
|
||||||
templateDir = filepath.Join(config.OutputDir, "templates")
|
templateDir = filepath.Join(config.OutputDir, "templates")
|
||||||
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
|
helpersPath = filepath.Join(config.OutputDir, "templates", "_helpers.tpl")
|
||||||
@@ -105,7 +105,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
// go to the root of the project
|
// go to the root of the project
|
||||||
if err := os.Chdir(filepath.Dir(dockerComposeFile[0])); err != nil {
|
if err := os.Chdir(filepath.Dir(dockerComposeFile[0])); err != nil {
|
||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
return err
|
||||||
}
|
}
|
||||||
defer os.Chdir(currentDir) // after the generation, go back to the original directory
|
defer os.Chdir(currentDir) // after the generation, go back to the original directory
|
||||||
|
|
||||||
@@ -118,13 +118,13 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
project, err := parser.Parse(config.Profiles, config.EnvFiles, dockerComposeFile...)
|
project, err := parser.Parse(config.Profiles, config.EnvFiles, dockerComposeFile...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// check older version of labels
|
// check older version of labels
|
||||||
if err := checkOldLabels(project); err != nil {
|
if err := checkOldLabels(project); err != nil {
|
||||||
fmt.Println(utils.IconFailure, err)
|
fmt.Println(utils.IconFailure, err)
|
||||||
os.Exit(1)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use katenary.yaml file here to set the labels
|
// TODO: use katenary.yaml file here to set the labels
|
||||||
@@ -140,7 +140,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
)
|
)
|
||||||
if !overwrite {
|
if !overwrite {
|
||||||
fmt.Println("Aborting")
|
fmt.Println("Aborting")
|
||||||
os.Exit(126) // 126 is the exit code for "Command invoked cannot execute"
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println() // clean line
|
fmt.Println() // clean line
|
||||||
@@ -150,7 +150,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
chart, err := Generate(project)
|
chart, err := Generate(project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the app version is set from the command line, use it
|
// if the app version is set from the command line, use it
|
||||||
@@ -194,6 +194,7 @@ func Convert(config ConvertOptions, dockerComposeFile ...string) {
|
|||||||
|
|
||||||
// call helm update if needed
|
// call helm update if needed
|
||||||
callHelmUpdate(config)
|
callHelmUpdate(config)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addChartDoc(values []byte, project *types.Project) []byte {
|
func addChartDoc(values []byte, project *types.Project) []byte {
|
||||||
|
@@ -48,7 +48,9 @@ func internalCompileTest(t *testing.T, options ...string) string {
|
|||||||
AppVersion: appVersion,
|
AppVersion: appVersion,
|
||||||
ChartVersion: chartVersion,
|
ChartVersion: chartVersion,
|
||||||
}
|
}
|
||||||
Convert(convertOptions, "compose.yml")
|
if err := Convert(convertOptions, "compose.yml"); err != nil {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
// launch helm lint to check the generated chart
|
// launch helm lint to check the generated chart
|
||||||
if helmLint(convertOptions) != nil {
|
if helmLint(convertOptions) != nil {
|
||||||
|
@@ -2,8 +2,13 @@ package generator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/png"
|
||||||
"katenary/generator/labels"
|
"katenary/generator/labels"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "k8s.io/api/apps/v1"
|
v1 "k8s.io/api/apps/v1"
|
||||||
@@ -149,6 +154,140 @@ services:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBinaryMount(t *testing.T) {
|
||||||
|
composeFile := `
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: nginx
|
||||||
|
volumes:
|
||||||
|
- ./images/foo.png:/var/www/foo
|
||||||
|
labels:
|
||||||
|
%[1]s/configmap-files: |-
|
||||||
|
- ./images/foo.png
|
||||||
|
`
|
||||||
|
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||||
|
tmpDir := setup(composeFile)
|
||||||
|
log.Println(tmpDir)
|
||||||
|
defer teardown(tmpDir)
|
||||||
|
|
||||||
|
os.Mkdir(filepath.Join(tmpDir, "images"), 0o755)
|
||||||
|
|
||||||
|
// create a png image
|
||||||
|
pngFile := tmpDir + "/images/foo.png"
|
||||||
|
w, h := 100, 100
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
|
red := color.RGBA{255, 0, 0, 255}
|
||||||
|
for y := 0; y < h; y++ {
|
||||||
|
for x := 0; x < w; x++ {
|
||||||
|
img.Set(x, y, red)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blue := color.RGBA{0, 0, 255, 255}
|
||||||
|
for y := 30; y < 70; y++ {
|
||||||
|
for x := 30; x < 70; x++ {
|
||||||
|
img.Set(x, y, blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentDir, _ := os.Getwd()
|
||||||
|
os.Chdir(tmpDir)
|
||||||
|
defer os.Chdir(currentDir)
|
||||||
|
|
||||||
|
f, err := os.Create(pngFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
png.Encode(f, img)
|
||||||
|
f.Close()
|
||||||
|
output := internalCompileTest(t, "-s", "templates/web/deployment.yaml")
|
||||||
|
d := v1.Deployment{}
|
||||||
|
yaml.Unmarshal([]byte(output), &d)
|
||||||
|
volumes := d.Spec.Template.Spec.Volumes
|
||||||
|
if len(volumes) != 1 {
|
||||||
|
t.Errorf("Expected 1 volume, got %d", len(volumes))
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := corev1.ConfigMap{}
|
||||||
|
cmContent, err := helmTemplate(ConvertOptions{
|
||||||
|
OutputDir: "chart",
|
||||||
|
}, "-s", "templates/web/statics/images/configmap.yaml")
|
||||||
|
yaml.Unmarshal([]byte(cmContent), &cm)
|
||||||
|
if im, ok := cm.BinaryData["foo.png"]; !ok {
|
||||||
|
t.Errorf("Expected foo.png to be in the configmap")
|
||||||
|
} else {
|
||||||
|
if len(im) == 0 {
|
||||||
|
t.Errorf("Expected image to be non-empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGloballyBinaryMount(t *testing.T) {
|
||||||
|
composeFile := `
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: nginx
|
||||||
|
volumes:
|
||||||
|
- ./images:/var/www/foo
|
||||||
|
labels:
|
||||||
|
%[1]s/configmap-files: |-
|
||||||
|
- ./images
|
||||||
|
`
|
||||||
|
composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix)
|
||||||
|
tmpDir := setup(composeFile)
|
||||||
|
log.Println(tmpDir)
|
||||||
|
defer teardown(tmpDir)
|
||||||
|
|
||||||
|
os.Mkdir(filepath.Join(tmpDir, "images"), 0o755)
|
||||||
|
|
||||||
|
// create a png image
|
||||||
|
pngFile := tmpDir + "/images/foo.png"
|
||||||
|
w, h := 100, 100
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
|
red := color.RGBA{255, 0, 0, 255}
|
||||||
|
for y := 0; y < h; y++ {
|
||||||
|
for x := 0; x < w; x++ {
|
||||||
|
img.Set(x, y, red)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blue := color.RGBA{0, 0, 255, 255}
|
||||||
|
for y := 30; y < 70; y++ {
|
||||||
|
for x := 30; x < 70; x++ {
|
||||||
|
img.Set(x, y, blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentDir, _ := os.Getwd()
|
||||||
|
os.Chdir(tmpDir)
|
||||||
|
defer os.Chdir(currentDir)
|
||||||
|
|
||||||
|
f, err := os.Create(pngFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
png.Encode(f, img)
|
||||||
|
f.Close()
|
||||||
|
output := internalCompileTest(t, "-s", "templates/web/deployment.yaml")
|
||||||
|
d := v1.Deployment{}
|
||||||
|
yaml.Unmarshal([]byte(output), &d)
|
||||||
|
volumes := d.Spec.Template.Spec.Volumes
|
||||||
|
if len(volumes) != 1 {
|
||||||
|
t.Errorf("Expected 1 volume, got %d", len(volumes))
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := corev1.ConfigMap{}
|
||||||
|
cmContent, err := helmTemplate(ConvertOptions{
|
||||||
|
OutputDir: "chart",
|
||||||
|
}, "-s", "templates/web/statics/images/configmap.yaml")
|
||||||
|
yaml.Unmarshal([]byte(cmContent), &cm)
|
||||||
|
if im, ok := cm.BinaryData["foo.png"]; !ok {
|
||||||
|
t.Errorf("Expected foo.png to be in the configmap")
|
||||||
|
} else {
|
||||||
|
if len(im) == 0 {
|
||||||
|
t.Errorf("Expected image to be non-empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindFrom(t *testing.T) {
|
func TestBindFrom(t *testing.T) {
|
||||||
composeFile := `
|
composeFile := `
|
||||||
services:
|
services:
|
||||||
|
@@ -9,13 +9,13 @@ type Icon string
|
|||||||
const (
|
const (
|
||||||
IconSuccess Icon = "✅"
|
IconSuccess Icon = "✅"
|
||||||
IconFailure Icon = "❌"
|
IconFailure Icon = "❌"
|
||||||
IconWarning Icon = "⚠️'"
|
IconWarning Icon = "❕"
|
||||||
IconNote Icon = "📝"
|
IconNote Icon = "📝"
|
||||||
IconWorld Icon = "🌐"
|
IconWorld Icon = "🌐"
|
||||||
IconPlug Icon = "🔌"
|
IconPlug Icon = "🔌"
|
||||||
IconPackage Icon = "📦"
|
IconPackage Icon = "📦"
|
||||||
IconCabinet Icon = "🗄️"
|
IconCabinet Icon = "🗄️"
|
||||||
IconInfo Icon = "❕"
|
IconInfo Icon = "🔵"
|
||||||
IconSecret Icon = "🔒"
|
IconSecret Icon = "🔒"
|
||||||
IconConfig Icon = "🔧"
|
IconConfig Icon = "🔧"
|
||||||
IconDependency Icon = "🔗"
|
IconDependency Icon = "🔗"
|
||||||
|
Reference in New Issue
Block a user