Skip to content

Commit

Permalink
Removes ExecCMDInContainer() and ExtractProjectToComponent() from the…
Browse files Browse the repository at this point in the history
… occlient. (#4291)

* Removes ExecCMDInContainer() and ExtractProjectToComponent() from the occlient. The callers now use the kclient version.

Signed-off-by: mik-dass <mrinald7@gmail.com>

* Removes imports of common package from kclient and lclient

* Adds SupervisordVolumeName in occlient.go and removes import of common package from occlient
  • Loading branch information
mik-dass authored Dec 9, 2020
1 parent f990de6 commit 9ae7540
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 123 deletions.
23 changes: 21 additions & 2 deletions pkg/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ var validSourceTypes = map[string]bool{
"binary": true,
}

type componentAdapter struct {
client occlient.Client
}

func (a componentAdapter) ExecCMDInContainer(componentInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
return a.client.GetKubeClient().ExecCMDInContainer(componentInfo.ContainerName, componentInfo.PodName, cmd, stdout, stderr, stdin, tty)
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (a componentAdapter) ExtractProjectToComponent(componentInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
return a.client.GetKubeClient().ExtractProjectToComponent(componentInfo.ContainerName, componentInfo.PodName, targetPath, stdin)
}

// GetComponentDir returns source repo name
// Parameters:
// path: git url or source path or binary path
Expand Down Expand Up @@ -714,12 +727,16 @@ func PushLocal(client *occlient.Client, componentName string, applicationName st
}
}

adapter := componentAdapter{
client: *client,
}

if isForcePush || len(files) > 0 {
klog.V(4).Infof("Copying files %s to pod", strings.Join(files, " "))
compInfo := common.ComponentInfo{
PodName: pod.Name,
}
err = sync.CopyFile(client, path, compInfo, targetPath, files, globExps)
err = sync.CopyFile(adapter, path, compInfo, targetPath, files, globExps)
if err != nil {
s.End(false)
return errors.Wrap(err, "unable push files to pod")
Expand All @@ -735,10 +752,12 @@ func PushLocal(client *occlient.Client, componentName string, applicationName st

// We will use the assemble-and-restart script located within the supervisord container we've created
cmdArr := []string{"/opt/odo/bin/assemble-and-restart"}

compInfo := common.ComponentInfo{
PodName: pod.Name,
}
err = common.ExecuteCommand(client, compInfo, cmdArr, show, nil, nil)

err = common.ExecuteCommand(adapter, compInfo, cmdArr, show, nil, nil)

if err != nil {
s.End(false)
Expand Down
14 changes: 12 additions & 2 deletions pkg/devfile/adapters/docker/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
// New instantiates a component adapter
func New(adapterContext common.AdapterContext, client lclient.Client) Adapter {
adapter := Adapter{Client: client}
adapter.GenericAdapter = common.NewGenericAdapter(&client, adapterContext)
adapter.GenericAdapter = common.NewGenericAdapter(&adapter, adapterContext)
adapter.GenericAdapter.InitWith(adapter)
return adapter
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) {

log.Infof("\nSyncing to component %s", a.ComponentName)
// Get a sync adapter. Check if project files have changed and sync accordingly
syncAdapter := sync.New(a.AdapterContext, &a.Client)
syncAdapter := sync.New(a.AdapterContext, &a)

// podChanged is defaulted to false, since docker volume is always present even if container goes down
compInfo := common.ComponentInfo{
Expand Down Expand Up @@ -410,3 +410,13 @@ func (a Adapter) Exec(command []string) error {

return a.ExecuteCommand(componentInfo, command, true, nil, nil)
}

//ExecCMDInContainer executes the command in the container with containerID
func (a Adapter) ExecCMDInContainer(componentInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
return a.Client.ExecCMDInContainer(componentInfo.ContainerName, cmd, stdout, stderr, stdin, tty)
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (a Adapter) ExtractProjectToComponent(componentInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
return a.Client.ExtractProjectToComponent(componentInfo.ContainerName, targetPath, stdin)
}
2 changes: 1 addition & 1 deletion pkg/devfile/adapters/docker/component/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func getSupervisordStatusInContainer(containerID string, a Adapter) []supervisor
stdoutWriter, stdoutOutputChannel := common.CreateConsoleOutputWriterAndChannel()
stderrWriter, stderrOutputChannel := common.CreateConsoleOutputWriterAndChannel()

err := common.ExecuteCommand(&a.Client, compInfo, command, false, stdoutWriter, stderrWriter)
err := common.ExecuteCommand(&a, compInfo, command, false, stdoutWriter, stderrWriter)

// Close the writer and wait the console output
stdoutWriter.Close()
Expand Down
13 changes: 11 additions & 2 deletions pkg/devfile/adapters/kubernetes/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
func New(adapterContext common.AdapterContext, client kclient.Client) Adapter {

adapter := Adapter{Client: client}
adapter.GenericAdapter = common.NewGenericAdapter(&client, adapterContext)
adapter.GenericAdapter = common.NewGenericAdapter(&adapter, adapterContext)
adapter.GenericAdapter.InitWith(adapter)
return adapter
}
Expand Down Expand Up @@ -193,7 +193,7 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) {

log.Infof("\nSyncing to component %s", a.ComponentName)
// Get a sync adapter. Check if project files have changed and sync accordingly
syncAdapter := sync.New(a.AdapterContext, &a.Client)
syncAdapter := sync.New(a.AdapterContext, &a)
compInfo := common.ComponentInfo{
ContainerName: containerName,
PodName: pod.GetName(),
Expand Down Expand Up @@ -581,3 +581,12 @@ func (a Adapter) Exec(command []string) error {

return a.ExecuteCommand(componentInfo, command, true, nil, nil)
}

func (a Adapter) ExecCMDInContainer(componentInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
return a.Client.ExecCMDInContainer(componentInfo.ContainerName, componentInfo.PodName, cmd, stdout, stderr, stdin, tty)
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (a Adapter) ExtractProjectToComponent(componentInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
return a.Client.ExtractProjectToComponent(componentInfo.ContainerName, componentInfo.PodName, targetPath, stdin)
}
2 changes: 1 addition & 1 deletion pkg/devfile/adapters/kubernetes/component/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func getSupervisordStatusInContainer(podName string, containerName string, a Ada
stdoutWriter, stdoutOutputChannel := common.CreateConsoleOutputWriterAndChannel()
stderrWriter, stderrOutputChannel := common.CreateConsoleOutputWriterAndChannel()

err := common.ExecuteCommand(&a.Client, compInfo, command, false, stdoutWriter, stderrWriter)
err := common.ExecuteCommand(&a, compInfo, command, false, stdoutWriter, stderrWriter)

// Close the writer and wait the console output
stdoutWriter.Close()
Expand Down
13 changes: 6 additions & 7 deletions pkg/kclient/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
"time"

"github.com/openshift/odo/pkg/devfile/adapters/common"
"github.com/openshift/odo/pkg/log"
"github.com/pkg/errors"
"k8s.io/klog"
Expand Down Expand Up @@ -127,7 +126,7 @@ See below for a list of failed events that occured more than %d times during dep
}

// ExecCMDInContainer execute command in the container of a pod, pass an empty string for containerName to execute in the first container of the pod
func (c *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
func (c *Client) ExecCMDInContainer(containerName, podName string, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
podExecOptions := corev1.PodExecOptions{
Command: cmd,
Stdin: stdin != nil,
Expand All @@ -137,15 +136,15 @@ func (c *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string,
}

// If a container name was passed in, set it in the exec options, otherwise leave it blank
if compInfo.ContainerName != "" {
podExecOptions.Container = compInfo.ContainerName
if containerName != "" {
podExecOptions.Container = containerName
}

req := c.KubeClient.CoreV1().RESTClient().
Post().
Namespace(c.Namespace).
Resource("pods").
Name(compInfo.PodName).
Name(podName).
SubResource("exec").
VersionedParams(&podExecOptions, scheme.ParameterCodec)

Expand Down Expand Up @@ -174,13 +173,13 @@ func (c *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string,
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (c *Client) ExtractProjectToComponent(compInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
func (c *Client) ExtractProjectToComponent(containerName, podName string, targetPath string, stdin io.Reader) error {
// cmdArr will run inside container
cmdArr := []string{"tar", "xf", "-", "-C", targetPath}
var stdout bytes.Buffer
var stderr bytes.Buffer
klog.V(3).Infof("Executing command %s", strings.Join(cmdArr, " "))
err := c.ExecCMDInContainer(compInfo, cmdArr, &stdout, &stderr, stdin, false)
err := c.ExecCMDInContainer(containerName, podName, cmdArr, &stdout, &stderr, stdin, false)
if err != nil {
log.Errorf("Command '%s' in container failed.\n", strings.Join(cmdArr, " "))
log.Errorf("stdout: %s\n", stdout.String())
Expand Down
9 changes: 4 additions & 5 deletions pkg/lclient/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/pkg/stdcopy"
"github.com/openshift/odo/pkg/devfile/adapters/common"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -105,7 +104,7 @@ func (dc *Client) GetContainerConfigHostConfigAndMounts(containerID string) (*co
}

//ExecCMDInContainer executes the command in the container with containerID
func (dc *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
func (dc *Client) ExecCMDInContainer(containerName string, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {

execConfig := types.ExecConfig{
AttachStdin: stdin != nil,
Expand All @@ -115,7 +114,7 @@ func (dc *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string
Tty: tty,
}

resp, err := dc.Client.ContainerExecCreate(dc.Context, compInfo.ContainerName, execConfig)
resp, err := dc.Client.ContainerExecCreate(dc.Context, containerName, execConfig)
if err != nil {
return err
}
Expand Down Expand Up @@ -145,9 +144,9 @@ func (dc *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (dc *Client) ExtractProjectToComponent(compInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
func (dc *Client) ExtractProjectToComponent(containerName string, targetPath string, stdin io.Reader) error {

err := dc.Client.CopyToContainer(dc.Context, compInfo.ContainerName, targetPath, stdin, types.CopyToContainerOptions{})
err := dc.Client.CopyToContainer(dc.Context, containerName, targetPath, stdin, types.CopyToContainerOptions{})
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/lclient/containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func TestExtractProjectToComponent(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.client.ExtractProjectToComponent(compInfo, targetPath, r)
err := tt.client.ExtractProjectToComponent(compInfo.ContainerName, targetPath, r)
if !tt.wantErr == (err != nil) {
t.Errorf("got %v, wanted %v", err, tt.wantErr)
}
Expand Down Expand Up @@ -394,7 +394,7 @@ func TestExecCMDInContainer(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.client.ExecCMDInContainer(compInfo, cmd, writer, writer, nil, false)
err := tt.client.ExecCMDInContainer(compInfo.ContainerName, cmd, writer, writer, nil, false)
if !tt.wantErr == (err != nil) {
t.Errorf("got %v, wanted %v", err, tt.wantErr)
}
Expand Down
88 changes: 6 additions & 82 deletions pkg/occlient/occlient.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package occlient

import (
"bytes"
"encoding/json"
"fmt"
"io"
Expand All @@ -14,9 +13,7 @@ import (
"github.com/pkg/errors"

"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/devfile/adapters/common"
"github.com/openshift/odo/pkg/kclient"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/preference"
"github.com/openshift/odo/pkg/util"

Expand All @@ -37,9 +34,7 @@ import (

"k8s.io/apimachinery/pkg/version"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/remotecommand"
"k8s.io/klog"
)

Expand Down Expand Up @@ -72,6 +67,9 @@ const (
// The length of the string to be generated for names of resources
nameLength = 5

// SupervisordVolumeName Create a custom name and (hope) that users don't use the *exact* same name in their deploymentConfig
SupervisordVolumeName = "odo-supervisord-shared-data"

// EnvS2IScriptsURL is an env var exposed to https://github.com/openshift/odo-init-image/blob/master/assemble-and-restart to indicate location of s2i scripts in this case assemble script
EnvS2IScriptsURL = "ODO_S2I_SCRIPTS_URL"

Expand Down Expand Up @@ -807,7 +805,7 @@ func copyVolumesAndVolumeMounts(dc appsv1.DeploymentConfig, currentDC *appsv1.De
// Loop through all the volumes
for _, volume := range matchingContainer.VolumeMounts {
// If it's the supervisord volume, ignore it.
if volume.Name == common.SupervisordVolumeName {
if volume.Name == SupervisordVolumeName {
continue
} else {
// check if we are appending the same volume mount again or not
Expand All @@ -830,7 +828,7 @@ func copyVolumesAndVolumeMounts(dc appsv1.DeploymentConfig, currentDC *appsv1.De

// Now the same with Volumes, again, ignoring the supervisord volume.
for _, volume := range currentDC.Spec.Template.Spec.Volumes {
if volume.Name == common.SupervisordVolumeName {
if volume.Name == SupervisordVolumeName {
continue
} else {
// check if we are appending the same volume again or not
Expand Down Expand Up @@ -1223,77 +1221,6 @@ func (c *Client) GetServerVersion() (*ServerInfo, error) {
return &info, nil
}

// ExecCMDInContainer execute command in the specified container of a pod. If `containerName` is blank, it execs in the first container.
func (c *Client) ExecCMDInContainer(compInfo common.ComponentInfo, cmd []string, stdout io.Writer, stderr io.Writer, stdin io.Reader, tty bool) error {
podExecOptions := corev1.PodExecOptions{
Command: cmd,
Stdin: stdin != nil,
Stdout: stdout != nil,
Stderr: stderr != nil,
TTY: tty,
}

// If a container name was passed in, set it in the exec options, otherwise leave it blank
if compInfo.ContainerName != "" {
podExecOptions.Container = compInfo.ContainerName
}

req := c.kubeClient.KubeClient.CoreV1().RESTClient().
Post().
Namespace(c.Namespace).
Resource("pods").
Name(compInfo.PodName).
SubResource("exec").
VersionedParams(&corev1.PodExecOptions{
Command: cmd,
Stdin: stdin != nil,
Stdout: stdout != nil,
Stderr: stderr != nil,
TTY: tty,
}, scheme.ParameterCodec)

config, err := c.KubeConfig.ClientConfig()
if err != nil {
return errors.Wrapf(err, "unable to get Kubernetes client config")
}

// Connect to url (constructed from req) using SPDY (HTTP/2) protocol which allows bidirectional streams.
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return errors.Wrapf(err, "unable execute command via SPDY")
}
// initialize the transport of the standard shell streams
err = exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
Tty: tty,
})
if err != nil {
return errors.Wrapf(err, "error while streaming command")
}

return nil
}

// ExtractProjectToComponent extracts the project archive(tar) to the target path from the reader stdin
func (c *Client) ExtractProjectToComponent(compInfo common.ComponentInfo, targetPath string, stdin io.Reader) error {
// cmdArr will run inside container
cmdArr := []string{"tar", "xf", "-", "-C", targetPath}
var stdout bytes.Buffer
var stderr bytes.Buffer
klog.V(3).Infof("Executing command %s", strings.Join(cmdArr, " "))
err := c.ExecCMDInContainer(compInfo, cmdArr, &stdout, &stderr, stdin, false)
if err != nil {
log.Errorf("Command '%s' in container failed.\n", strings.Join(cmdArr, " "))
log.Errorf("stdout: %s\n", stdout.String())
log.Errorf("stderr: %s\n", stderr.String())
log.Errorf("err: %s\n", err.Error())
return err
}
return nil
}

func (c *Client) GetKubeClient() *kclient.Client {
return c.kubeClient
}
Expand Down Expand Up @@ -1339,11 +1266,8 @@ func (c *Client) PropagateDeletes(targetPodName string, delSrcRelPaths []string,
klog.V(3).Infof("s2ipaths marked for deletion are %+v", rmPaths)
cmdArr := []string{"rm", "-rf"}
cmdArr = append(cmdArr, rmPaths...)
compInfo := common.ComponentInfo{
PodName: targetPodName,
}

err := c.ExecCMDInContainer(compInfo, cmdArr, writer, writer, reader, false)
err := c.GetKubeClient().ExecCMDInContainer("", targetPodName, cmdArr, writer, writer, reader, false)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 9ae7540

Please sign in to comment.