mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Add new --run-port flag to odo init to set ports non-interactively (#6953)
* Add new `--run-port` flag to `odo init` to set ports non-interactively As depicted in [1], this leverages the default (or single non-default) run command to find the linked container component. As such, it assumes that the command found is an exec command, and that the linked component is a container component. [1] https://github.com/redhat-developer/odo/issues/6925 * Add unit and integration tests highlighting the expectations * Document the new `--run-port` flag * Fix some typos and language correctness issues in the `odo init` doc * Add doc automation test for the output of `odo init --run-port` This ensures the output and sample in the doc are kept in sync with the code base.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
```console
|
||||
$ odo init --devfile go --name my-go-app --run-port 3456 --run-port 9876
|
||||
__
|
||||
/ \__ Initializing a new component
|
||||
\__/ \
|
||||
/ \__/ odo version: v3.12.0
|
||||
\__/
|
||||
|
||||
✓ Downloading devfile "go" [48ms]
|
||||
|
||||
Your new component 'my-go-app' is ready in the current directory.
|
||||
To start editing your component, use 'odo dev' and open this folder in your favorite IDE.
|
||||
Changes will be directly reflected on the cluster.
|
||||
```
|
||||
@@ -67,15 +67,20 @@ import NonEmptyDirectoryOutput from './docs-mdx/init/interactive_mode_directory_
|
||||
In non-interactive mode, you will have to specify from the command-line the information needed to get a devfile.
|
||||
|
||||
If you want to download a devfile from a registry, you must specify the devfile name with the `--devfile` flag. The devfile with the specified name will be searched in the registries referenced (using `odo preference view`), and the first one matching will be downloaded.
|
||||
If you want to download the devfile from a specific registry in the list or referenced registries, you can use the `--devfile-registry` flag to specify the name of this registry. By default odo uses official devfile registry [registry.devfile.io](https://registry.devfile.io). You can use registry's [web interface](https://registry.devfile.io/viewer) to view its content.
|
||||
If you want to download a version devfile, you must specify the version with `--devfile-version` flag.
|
||||
If you want to download the devfile from a specific registry in the list or referenced registries, you can use the `--devfile-registry` flag to specify the name of this registry. By default, `odo` uses the official devfile registry [registry.devfile.io](https://registry.devfile.io). You can use the registry [web interface](https://registry.devfile.io/viewer) to view its content.
|
||||
If you want to download a specific version of a devfile, you can specify the version with the `--devfile-version` flag.
|
||||
|
||||
If you prefer to download a devfile from an URL or from the local filesystem, you can use the `--devfile-path` instead.
|
||||
If you prefer to download a devfile from a URL or from the local filesystem, you can use the `--devfile-path` instead.
|
||||
|
||||
The `--starter` flag indicates the name of the starter project (as referenced in the selected devfile), that you want to use to start your development. To see the available starter projects for devfile stacks in the official devfile registry use its [web interface](https://registry.devfile.io/viewer) to view its content.
|
||||
|
||||
The required `--name` flag indicates how the component initialized by this command should be named. The name must follow the [Kubernetes naming convention](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names) and not be all-numeric.
|
||||
|
||||
If you know what ports your application uses, you can specify the `--run-port` flag to initialize the Devfile with the specified ports, instead of the default ones set in the registry.
|
||||
The `--run-port` flag is a repeatable flag that will make `odo` read the downloaded Devfile and look for the container component referenced by the default `run` command.
|
||||
It will then overwrite the container component endpoints with the ports specified.
|
||||
As such, it requires the default `run` command to be an `exec` command pointing to a `container` component.
|
||||
|
||||
#### Fetch Devfile from any registry of the list
|
||||
|
||||
In this example, the devfile will be downloaded from the **StagingRegistry** registry, which is the first one in the list containing the `nodejs-react` devfile.
|
||||
@@ -156,3 +161,26 @@ Use "latest" as the version name to fetch the latest version of a given Devfile.
|
||||
|
||||
</details>
|
||||
:::
|
||||
|
||||
#### Specify the application ports
|
||||
|
||||
|
||||
```console
|
||||
odo init \
|
||||
--devfile <devfile-name> \
|
||||
--name <component-name> \
|
||||
--run-port <port> [--run-port ANOTHER_PORT] \
|
||||
[--starter STARTER]
|
||||
```
|
||||
|
||||
In this example, `odo` will download the Devfile from the registry and overwrite the container endpoints with the ones specified in `--run-port`.
|
||||
This works because the Devfile downloaded from the registry defines a default `run` command of type `exec` and referencing a `container` component.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
import DevfileWithRunPortOutput from './docs-mdx/init/devfile_with_run-port_output.mdx';
|
||||
|
||||
<DevfileWithRunPortOutput />
|
||||
|
||||
</details>
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser"
|
||||
parsercommon "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
"k8s.io/klog"
|
||||
@@ -40,27 +41,39 @@ func handleApplicationPorts(w io.Writer, devfileobj parser.DevfileObj, ports []i
|
||||
|
||||
component := components[0]
|
||||
|
||||
err = setPortsInContainerComponent(&devfileobj, &component, ports, true)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileobj, nil
|
||||
}
|
||||
|
||||
func setPortsInContainerComponent(devfileobj *parser.DevfileObj, component *v1alpha2.Component, ports []int, withDebug bool) error {
|
||||
// Add the new ports at the beginning of the list (that is before any Debug endpoints).
|
||||
// This way, application ports will be port-forwarded first.
|
||||
portsToSet := make([]string, 0, len(ports))
|
||||
for _, p := range ports {
|
||||
portsToSet = append(portsToSet, strconv.Itoa(p))
|
||||
}
|
||||
debugEndpoints, err := libdevfile.GetDebugEndpointsForComponent(component)
|
||||
|
||||
debugEndpoints, err := libdevfile.GetDebugEndpointsForComponent(*component)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Clear the existing endpoint list
|
||||
component.Container.Endpoints = nil
|
||||
|
||||
// Add the new application ports first
|
||||
err = devfileobj.Data.SetPorts(map[string][]string{component.Name: portsToSet})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Append debug endpoints to the end of the list
|
||||
component.Container.Endpoints = append(component.Container.Endpoints, debugEndpoints...)
|
||||
if withDebug {
|
||||
component.Container.Endpoints = append(component.Container.Endpoints, debugEndpoints...)
|
||||
}
|
||||
|
||||
return devfileobj, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,12 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/libdevfile"
|
||||
"github.com/redhat-developer/odo/pkg/registry"
|
||||
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
@@ -24,6 +29,7 @@ const (
|
||||
FLAG_STARTER = "starter"
|
||||
FLAG_DEVFILE_PATH = "devfile-path"
|
||||
FLAG_DEVFILE_VERSION = "devfile-version"
|
||||
FLAG_RUN_PORT = "run-port"
|
||||
)
|
||||
|
||||
// FlagsBackend is a backend that will extract all needed information from flags passed to the command
|
||||
@@ -133,7 +139,80 @@ func (o FlagsBackend) PersonalizeDevfileConfig(devfileobj parser.DevfileObj) (pa
|
||||
return devfileobj, nil
|
||||
}
|
||||
|
||||
func (o FlagsBackend) HandleApplicationPorts(devfileobj parser.DevfileObj, ports []int, flags map[string]string) (parser.DevfileObj, error) {
|
||||
// Currently not supported, but this will be done in a separate issue: https://github.com/redhat-developer/odo/issues/6211
|
||||
func (o FlagsBackend) HandleApplicationPorts(devfileobj parser.DevfileObj, _ []int, flags map[string]string) (parser.DevfileObj, error) {
|
||||
d, err := setPortsForFlag(devfileobj, flags, FLAG_RUN_PORT)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func setPortsForFlag(devfileobj parser.DevfileObj, flags map[string]string, flagName string) (parser.DevfileObj, error) {
|
||||
flagVal := flags[flagName]
|
||||
// Repeatable flags are formatted as "[val1,val2]"
|
||||
if !(strings.HasPrefix(flagVal, "[") && strings.HasSuffix(flagVal, "]")) {
|
||||
return devfileobj, nil
|
||||
}
|
||||
portsStr := flagVal[1 : len(flagVal)-1]
|
||||
|
||||
var ports []int
|
||||
split := strings.Split(portsStr, ",")
|
||||
for _, s := range split {
|
||||
p, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, fmt.Errorf("invalid value for %s (%q): %w", flagName, s, err)
|
||||
}
|
||||
ports = append(ports, p)
|
||||
}
|
||||
|
||||
var kind v1alpha2.CommandGroupKind
|
||||
switch flagName {
|
||||
case FLAG_RUN_PORT:
|
||||
kind = v1alpha2.RunCommandGroupKind
|
||||
default:
|
||||
return parser.DevfileObj{}, fmt.Errorf("unknown flag: %q", flagName)
|
||||
}
|
||||
|
||||
cmd, ok, err := libdevfile.GetCommand(devfileobj, "", kind)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
if !ok {
|
||||
klog.V(3).Infof("Specified %s flag will not be applied - no default (or single non-default) command found for kind %v", flagName, kind)
|
||||
return devfileobj, nil
|
||||
}
|
||||
// command must be an exec command to determine the right container component endpoints to update.
|
||||
cmdType, err := common.GetCommandType(cmd)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
if cmdType != v1alpha2.ExecCommandType {
|
||||
return parser.DevfileObj{},
|
||||
fmt.Errorf("%v cannot be used with non-exec commands. Found out that command (id: %s) for kind %v is of type %q instead",
|
||||
flagName, cmd.Id, kind, cmdType)
|
||||
}
|
||||
|
||||
cmp, ok, err := libdevfile.FindComponentByName(devfileobj.Data, cmd.Exec.Component)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
if !ok {
|
||||
return parser.DevfileObj{}, fmt.Errorf("component not found in Devfile for exec command %q", cmd.Id)
|
||||
}
|
||||
cmpType, err := common.GetComponentType(cmp)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
if cmpType != v1alpha2.ContainerComponentType {
|
||||
return parser.DevfileObj{},
|
||||
fmt.Errorf("%v cannot be used with non-container components. Found out that command (id: %s) for kind %v points to a compoenent of type %q instead",
|
||||
flagName, cmd.Id, kind, cmpType)
|
||||
}
|
||||
|
||||
err = setPortsInContainerComponent(&devfileobj, &cmp, ports, false)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileobj, nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser"
|
||||
@@ -15,6 +17,7 @@ import (
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/api"
|
||||
"github.com/redhat-developer/odo/pkg/registry"
|
||||
"github.com/redhat-developer/odo/pkg/testingutil"
|
||||
"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
|
||||
)
|
||||
|
||||
@@ -468,3 +471,685 @@ func TestFlagsBackend_PersonalizeName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagsBackend_HandleApplicationPorts(t *testing.T) {
|
||||
type devfileProvider func(fs dffilesystem.Filesystem) (parser.DevfileObj, error)
|
||||
|
||||
zeroDevfileProvider := func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
return parser.DevfileObj{}, nil
|
||||
}
|
||||
fakeDevfileProvider := func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
||||
obj := parser.DevfileObj{
|
||||
Ctx: parsercontext.FakeContext(fs, "/tmp/devfile.yaml"),
|
||||
Data: devfileData,
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
type fields struct {
|
||||
registryClient registry.Client
|
||||
}
|
||||
type args struct {
|
||||
devfileObjProvider devfileProvider
|
||||
flags map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wantProvider devfileProvider
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "no run-port flag",
|
||||
args: args{
|
||||
devfileObjProvider: fakeDevfileProvider,
|
||||
flags: map[string]string{
|
||||
"opt1": "val1",
|
||||
FLAG_NAME: "my-name",
|
||||
},
|
||||
},
|
||||
wantProvider: fakeDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "flag string value not enclosed within []",
|
||||
args: args{
|
||||
devfileObjProvider: fakeDevfileProvider,
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "aaa,bbb",
|
||||
},
|
||||
},
|
||||
wantProvider: fakeDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "invalid port type",
|
||||
args: args{
|
||||
devfileObjProvider: fakeDevfileProvider,
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,abcde]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "devfile with no command, but --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "devfile with more than one default run commands, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "devrun2",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "devfile with more than one non-default run commands, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "devrun2",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "devrun2",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "devfile with no run command, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devdebug",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{Kind: v1alpha2.DebugCommandGroupKind},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devdebug",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{Kind: v1alpha2.DebugCommandGroupKind},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "devfile with a default non-exec (apply) run command, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Apply: &v1alpha2.ApplyCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "devfile with a default non-exec (composite) run command, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Composite: &v1alpha2.CompositeCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
|
||||
{
|
||||
name: "devfile with an exec run command with non-container component, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "some-random-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "devfile with an exec run command with non-container component, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
{
|
||||
Name: "k8s-comp1",
|
||||
ComponentUnion: v1alpha2.ComponentUnion{
|
||||
Kubernetes: &v1alpha2.KubernetesComponent{
|
||||
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
||||
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
||||
Inlined: "some-k8s-def",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "k8s-comp1",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
wantProvider: zeroDevfileProvider,
|
||||
},
|
||||
{
|
||||
name: "devfile with default exec run command with container component, --run-port set",
|
||||
args: args{
|
||||
devfileObjProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
testingutil.GetFakeContainerComponent("my-cont1", 1234, 2345),
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "my-cont1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "devdebug1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.DebugCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "my-cont2",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
flags: map[string]string{
|
||||
FLAG_NAME: "my-name",
|
||||
FLAG_RUN_PORT: "[8080,8081]",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
wantProvider: func(fs dffilesystem.Filesystem) (parser.DevfileObj, error) {
|
||||
devfileObj, err := fakeDevfileProvider(fs)
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
// only my-cont1 (referenced by the default run command) should change
|
||||
cont1 := testingutil.GetFakeContainerComponent("my-cont1")
|
||||
cont1.Container.Endpoints = append(cont1.Container.Endpoints,
|
||||
v1alpha2.Endpoint{
|
||||
Name: "port-8080-tcp",
|
||||
TargetPort: 8080,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
v1alpha2.Endpoint{
|
||||
Name: "port-8081-tcp",
|
||||
TargetPort: 8081,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
)
|
||||
err = devfileObj.Data.AddComponents([]v1alpha2.Component{
|
||||
cont1,
|
||||
testingutil.GetFakeContainerComponent("my-cont2", 4321, 5432),
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
err = devfileObj.Data.AddCommands([]v1alpha2.Command{
|
||||
{
|
||||
Id: "devrun1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.RunCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "my-cont1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "devdebug1",
|
||||
CommandUnion: v1alpha2.CommandUnion{
|
||||
Exec: &v1alpha2.ExecCommand{
|
||||
LabeledCommand: v1alpha2.LabeledCommand{
|
||||
BaseCommand: v1alpha2.BaseCommand{
|
||||
Group: &v1alpha2.CommandGroup{
|
||||
Kind: v1alpha2.DebugCommandGroupKind,
|
||||
IsDefault: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
Component: "my-cont2",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return parser.DevfileObj{}, err
|
||||
}
|
||||
return devfileObj, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &FlagsBackend{
|
||||
registryClient: tt.fields.registryClient,
|
||||
}
|
||||
fs := dffilesystem.NewFakeFs()
|
||||
devfileObj, err := tt.args.devfileObjProvider(fs)
|
||||
if err != nil {
|
||||
t.Errorf("error building input DevfileObj: %v", err)
|
||||
return
|
||||
}
|
||||
want, err := tt.wantProvider(fs)
|
||||
if err != nil {
|
||||
t.Errorf("error building expected DevfileObj: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
got, err := o.HandleApplicationPorts(devfileObj, nil, tt.args.flags)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("HandleApplicationPorts() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(want, got, cmpopts.IgnoreUnexported(parsercontext.DevfileCtx{})); diff != "" {
|
||||
t.Errorf("HandleApplicationPorts() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser"
|
||||
dfutil "github.com/devfile/library/v2/pkg/util"
|
||||
@@ -40,6 +41,17 @@ type InitClient struct {
|
||||
|
||||
var _ Client = (*InitClient)(nil)
|
||||
|
||||
// Explicit list of tags useful to select the right backend
|
||||
var _initFlags = []string{
|
||||
backend.FLAG_NAME,
|
||||
backend.FLAG_DEVFILE,
|
||||
backend.FLAG_DEVFILE_REGISTRY,
|
||||
backend.FLAG_STARTER,
|
||||
backend.FLAG_DEVFILE_PATH,
|
||||
backend.FLAG_DEVFILE_VERSION,
|
||||
backend.FLAG_RUN_PORT,
|
||||
}
|
||||
|
||||
func NewInitClient(fsys filesystem.Filesystem, preferenceClient preference.Client, registryClient registry.Client, alizerClient alizer.Client) *InitClient {
|
||||
// We create the asker client and the backends here and not at the CLI level, as we want to hide these details to the CLI
|
||||
askerClient := asker.NewSurveyAsker()
|
||||
@@ -57,9 +69,13 @@ func NewInitClient(fsys filesystem.Filesystem, preferenceClient preference.Clien
|
||||
// It ignores all the flags except the ones specific to init operation, for e.g. verbosity flag
|
||||
func (o *InitClient) GetFlags(flags map[string]string) map[string]string {
|
||||
initFlags := map[string]string{}
|
||||
outer:
|
||||
for flag, value := range flags {
|
||||
if flag == backend.FLAG_NAME || flag == backend.FLAG_DEVFILE || flag == backend.FLAG_DEVFILE_REGISTRY || flag == backend.FLAG_STARTER || flag == backend.FLAG_DEVFILE_PATH || flag == backend.FLAG_DEVFILE_VERSION {
|
||||
initFlags[flag] = value
|
||||
for _, f := range _initFlags {
|
||||
if flag == f {
|
||||
initFlags[flag] = value
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
}
|
||||
return initFlags
|
||||
|
||||
@@ -95,7 +95,9 @@ func executeCommand(ctx context.Context, devfileObj parser.DevfileObj, command v
|
||||
}
|
||||
|
||||
// GetCommand iterates through the devfile commands and returns the devfile command with the specified name and group kind.
|
||||
// If commandName is empty, it returns the default command for the group kind or returns an error if there is no default command.
|
||||
// If commandName is empty, it returns the default command for the group kind; or, if there is only one command for the specified kind, it will return that
|
||||
// (even if it is not marked as the default).
|
||||
// It returns an error if there is more than one default command.
|
||||
func GetCommand(
|
||||
devfileObj parser.DevfileObj,
|
||||
commandName string,
|
||||
|
||||
@@ -285,6 +285,7 @@ func NewCmdInit(name, fullName string, testClientset clientset.Clientset) *cobra
|
||||
initCmd.Flags().String(backend.FLAG_STARTER, "", "name of the starter project")
|
||||
initCmd.Flags().String(backend.FLAG_DEVFILE_PATH, "", "path to a devfile. This is an alternative to using devfile from Devfile registry. It can be local filesystem path or http(s) URL")
|
||||
initCmd.Flags().String(backend.FLAG_DEVFILE_VERSION, "", "version of the devfile stack; use \"latest\" to dowload the latest stack")
|
||||
initCmd.Flags().StringArray(backend.FLAG_RUN_PORT, []string{}, "ports used by the application (via the 'run' command)")
|
||||
|
||||
commonflags.UseOutputFlag(initCmd)
|
||||
// Add a defined annotation in order to appear in the help menu
|
||||
|
||||
@@ -212,6 +212,16 @@ var _ = Describe("doc command reference odo init", Label(helper.LabelNoCluster),
|
||||
diff := cmp.Diff(want, got)
|
||||
Expect(diff).To(BeEmpty(), file)
|
||||
})
|
||||
|
||||
It("set application ports after fetching Devfile", func() {
|
||||
args := []string{"init", "--devfile", "go", "--name", "my-go-app", "--run-port", "3456", "--run-port", "9876"}
|
||||
out := helper.Cmd("odo", args...).ShouldPass().Out()
|
||||
got := fmt.Sprintf(outputStringFormat, strings.Join(args, " "), helper.StripSpinner(out))
|
||||
file := "devfile_with_run-port_output.mdx"
|
||||
want := helper.GetMDXContent(filepath.Join(commonPath, file))
|
||||
diff := cmp.Diff(want, got)
|
||||
Expect(diff).To(BeEmpty(), file)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/devfile"
|
||||
)
|
||||
|
||||
// DevfileUpdater is a helper type that can mutate a Devfile object.
|
||||
@@ -105,3 +107,10 @@ func SetFsGroup(containerName string, fsGroup int) DevfileUpdater {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ReadRawDevfile parses and validates the Devfile specified and returns its raw content.
|
||||
func ReadRawDevfile(devfilePath string) parser.DevfileObj {
|
||||
d, err := devfile.ParseAndValidateFromFile(devfilePath, "", false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return d
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/tidwall/gjson"
|
||||
@@ -616,4 +618,57 @@ spec:
|
||||
})
|
||||
})
|
||||
|
||||
Context("setting application ports", func() {
|
||||
When("running odo init --run-port with a Devfile with no commands", func() {
|
||||
BeforeEach(func() {
|
||||
helper.Cmd("odo", "init", "--name", "aname", "--devfile-path",
|
||||
filepath.Join(helper.GetExamplePath(), "source", "devfiles", "nodejs", "devfile-without-commands.yaml"),
|
||||
"--run-port", "1234", "--run-port", "2345", "--run-port", "3456").ShouldPass().Out()
|
||||
})
|
||||
It("should ignore the run ports", func() {
|
||||
d := helper.ReadRawDevfile(filepath.Join(commonVar.Context, "devfile.yaml"))
|
||||
components, err := d.Data.GetComponents(common.DevfileOptions{
|
||||
ComponentOptions: common.ComponentOptions{
|
||||
ComponentType: v1alpha2.ContainerComponentType,
|
||||
},
|
||||
})
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(components).To(HaveLen(1))
|
||||
Expect(components[0].Name).Should(Equal("runtime"))
|
||||
Expect(components[0].Container).ShouldNot(BeNil())
|
||||
Expect(components[0].Container.Endpoints).Should(HaveLen(2))
|
||||
Expect(components[0].Container.Endpoints[0].Name).Should(Equal("http-node"))
|
||||
Expect(components[0].Container.Endpoints[0].TargetPort).Should(Equal(3000))
|
||||
Expect(components[0].Container.Endpoints[1].Name).Should(Equal("debug"))
|
||||
Expect(components[0].Container.Endpoints[1].TargetPort).Should(Equal(5858))
|
||||
Expect(components[0].Container.Endpoints[1].Exposure).Should(Equal(v1alpha2.NoneEndpointExposure))
|
||||
})
|
||||
})
|
||||
|
||||
When("running odo init --run-port with a Devfile with no commands", func() {
|
||||
BeforeEach(func() {
|
||||
helper.Cmd("odo", "init", "--name", "aname", "--devfile-path",
|
||||
filepath.Join(helper.GetExamplePath(), "source", "devfiles", "nodejs", "devfile-with-debugrun.yaml"),
|
||||
"--run-port", "1234", "--run-port", "2345", "--run-port", "3456").ShouldPass().Out()
|
||||
})
|
||||
It("should overwrite the ports into the container component referenced by the default run command", func() {
|
||||
d := helper.ReadRawDevfile(filepath.Join(commonVar.Context, "devfile.yaml"))
|
||||
components, err := d.Data.GetComponents(common.DevfileOptions{
|
||||
ComponentOptions: common.ComponentOptions{
|
||||
ComponentType: v1alpha2.ContainerComponentType,
|
||||
},
|
||||
})
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(components).To(HaveLen(1))
|
||||
Expect(components[0].Name).Should(Equal("runtime"))
|
||||
Expect(components[0].Container).ShouldNot(BeNil())
|
||||
Expect(components[0].Container.Endpoints).Should(HaveLen(3))
|
||||
for i, p := range []int{1234, 2345, 3456} {
|
||||
Expect(components[0].Container.Endpoints[i].Name).Should(Equal(fmt.Sprintf("port-%d-tcp", p)))
|
||||
Expect(components[0].Container.Endpoints[i].TargetPort).Should(Equal(p))
|
||||
Expect(components[0].Container.Endpoints[i].Protocol).Should(Equal(v1alpha2.TCPEndpointProtocol))
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user