mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Do not set Memory limit on podman when cgroup is v1 (#7028)
This commit is contained in:
@@ -32,7 +32,7 @@ const (
|
||||
portForwardingHelperImage = "quay.io/devfile/base-developer-image@sha256:27d5ce66a259decb84770ea0d1ce8058a806f39dfcfeed8387f9cf2f29e76480"
|
||||
)
|
||||
|
||||
func createPodFromComponent(
|
||||
func (o *DevClient) createPodFromComponent(
|
||||
ctx context.Context,
|
||||
debug bool,
|
||||
buildCommand string,
|
||||
@@ -55,6 +55,18 @@ func createPodFromComponent(
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
podmanCaps, err := o.podmanClient.GetCapabilities()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if !podmanCaps.Cgroupv2 {
|
||||
for i := range podTemplate.Spec.Containers {
|
||||
delete(podTemplate.Spec.Containers[i].Resources.Limits, corev1.ResourceMemory)
|
||||
}
|
||||
}
|
||||
|
||||
containers := podTemplate.Spec.Containers
|
||||
if len(containers) == 0 {
|
||||
return nil, nil, fmt.Errorf("no valid components found in the devfile")
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser"
|
||||
"github.com/devfile/library/v2/pkg/devfile/parser/data"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"github.com/redhat-developer/odo/pkg/labels"
|
||||
"github.com/redhat-developer/odo/pkg/libdevfile/generator"
|
||||
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
|
||||
"github.com/redhat-developer/odo/pkg/podman"
|
||||
"github.com/redhat-developer/odo/pkg/version"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -143,11 +145,12 @@ func Test_createPodFromComponent(t *testing.T) {
|
||||
customAddress string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantPod func(basePod *corev1.Pod) *corev1.Pod
|
||||
wantFwPorts []api.ForwardedPort
|
||||
wantErr bool
|
||||
name string
|
||||
capabilities podman.Capabilities
|
||||
args args
|
||||
wantPod func(basePod *corev1.Pod) *corev1.Pod
|
||||
wantFwPorts []api.ForwardedPort
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "basic component without command / forwardLocalhost=false",
|
||||
@@ -237,7 +240,10 @@ func Test_createPodFromComponent(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic component + memory limit / forwardLocalhost=false",
|
||||
name: "basic component + memory limit / forwardLocalhost=false, cgroup=v2",
|
||||
capabilities: podman.Capabilities{
|
||||
Cgroupv2: true,
|
||||
},
|
||||
args: args{
|
||||
devfileObj: func() parser.DevfileObj {
|
||||
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
||||
@@ -261,7 +267,34 @@ func Test_createPodFromComponent(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic component + memory limit / forwardLocalhost=true",
|
||||
name: "basic component + memory limit / forwardLocalhost=false, cgroup=v1",
|
||||
capabilities: podman.Capabilities{
|
||||
Cgroupv2: false,
|
||||
},
|
||||
args: args{
|
||||
devfileObj: func() parser.DevfileObj {
|
||||
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
||||
_ = data.AddCommands([]v1alpha2.Command{command})
|
||||
cmp := baseComponent.DeepCopy()
|
||||
cmp.Container.MemoryLimit = "1Gi"
|
||||
_ = data.AddComponents([]v1alpha2.Component{*cmp})
|
||||
return parser.DevfileObj{
|
||||
Data: data,
|
||||
}
|
||||
},
|
||||
componentName: devfileName,
|
||||
appName: appName,
|
||||
},
|
||||
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
|
||||
pod := basePod.DeepCopy()
|
||||
return pod
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic component + memory limit / forwardLocalhost=true, cgroup=v2",
|
||||
capabilities: podman.Capabilities{
|
||||
Cgroupv2: true,
|
||||
},
|
||||
args: args{
|
||||
devfileObj: func() parser.DevfileObj {
|
||||
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
||||
@@ -1412,7 +1445,13 @@ func Test_createPodFromComponent(t *testing.T) {
|
||||
ctx = odocontext.WithApplication(ctx, tt.args.appName)
|
||||
ctx = odocontext.WithComponentName(ctx, tt.args.componentName)
|
||||
ctx = odocontext.WithWorkingDirectory(ctx, "/tmp/dir")
|
||||
got, gotFwPorts, err := createPodFromComponent(
|
||||
ctrl := gomock.NewController(t)
|
||||
podmanClient := podman.NewMockClient(ctrl)
|
||||
podmanClient.EXPECT().GetCapabilities().Return(tt.capabilities, nil)
|
||||
client := NewDevClient(
|
||||
nil, podmanClient, nil, nil, nil, nil, nil, nil,
|
||||
)
|
||||
got, gotFwPorts, err := client.createPodFromComponent(
|
||||
ctx,
|
||||
tt.args.debug,
|
||||
tt.args.buildCommand,
|
||||
|
||||
@@ -233,7 +233,7 @@ func (o *DevClient) deployPod(ctx context.Context, options dev.StartOptions, dev
|
||||
spinner := log.Spinner("Deploying pod")
|
||||
defer spinner.End(false)
|
||||
|
||||
pod, fwPorts, err := createPodFromComponent(
|
||||
pod, fwPorts, err := o.createPodFromComponent(
|
||||
ctx,
|
||||
options.Debug,
|
||||
options.BuildCommand,
|
||||
|
||||
17
pkg/podman/capabilities.go
Normal file
17
pkg/podman/capabilities.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package podman
|
||||
|
||||
type Capabilities struct {
|
||||
Cgroupv2 bool
|
||||
}
|
||||
|
||||
func (o *PodmanCli) GetCapabilities() (Capabilities, error) {
|
||||
var result Capabilities
|
||||
info, err := o.getInfo()
|
||||
if err != nil {
|
||||
return Capabilities{}, err
|
||||
}
|
||||
if info.Host.CgroupsVersion == "v2" {
|
||||
result.Cgroupv2 = true
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
35
pkg/podman/info.go
Normal file
35
pkg/podman/info.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package podman
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// podmanInfo originates from https://github.com/containers/podman/blob/main/libpod/define/info.go
|
||||
type podmanInfo struct {
|
||||
Host *HostInfo `json:"host"`
|
||||
}
|
||||
|
||||
type HostInfo struct {
|
||||
CgroupsVersion string `json:"cgroupVersion"`
|
||||
}
|
||||
|
||||
func (o *PodmanCli) getInfo() (podmanInfo, error) {
|
||||
cmd := exec.Command(o.podmanCmd, append(o.containerRunGlobalExtraArgs, "info", "--format", "json")...)
|
||||
klog.V(3).Infof("executing %v", cmd.Args)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||
err = fmt.Errorf("%s: %s", err, string(exiterr.Stderr))
|
||||
}
|
||||
return podmanInfo{}, err
|
||||
}
|
||||
|
||||
var result podmanInfo
|
||||
|
||||
err = json.Unmarshal(out, &result)
|
||||
return result, err
|
||||
}
|
||||
@@ -39,4 +39,7 @@ type Client interface {
|
||||
ListAllComponents() ([]api.ComponentAbstract, error)
|
||||
|
||||
Version(ctx context.Context) (SystemVersionReport, error)
|
||||
|
||||
// GetCapabilities returns the capabilities of the underlying system
|
||||
GetCapabilities() (Capabilities, error)
|
||||
}
|
||||
|
||||
15
pkg/podman/mock.go
generated
15
pkg/podman/mock.go
generated
@@ -97,6 +97,21 @@ func (mr *MockClientMockRecorder) GetAllResourcesFromSelector(selector, ns inter
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllResourcesFromSelector", reflect.TypeOf((*MockClient)(nil).GetAllResourcesFromSelector), selector, ns)
|
||||
}
|
||||
|
||||
// GetCapabilities mocks base method.
|
||||
func (m *MockClient) GetCapabilities() (Capabilities, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetCapabilities")
|
||||
ret0, _ := ret[0].(Capabilities)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetCapabilities indicates an expected call of GetCapabilities.
|
||||
func (mr *MockClientMockRecorder) GetCapabilities() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCapabilities", reflect.TypeOf((*MockClient)(nil).GetCapabilities))
|
||||
}
|
||||
|
||||
// GetPodLogs mocks base method.
|
||||
func (m *MockClient) GetPodLogs(podName, containerName string, followLog bool) (io.ReadCloser, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Reference in New Issue
Block a user