Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Getting rid of nsenter and socat #691

Merged
merged 4 commits into from
Apr 9, 2018
Merged

Conversation

abhi
Copy link
Member

@abhi abhi commented Mar 22, 2018

This commit removes the usage of nsenter and uses netns
to perform socat operation.
Fixes #144

Signed-off-by: abhi [email protected]

@Random-Liu
Copy link
Member

Random-Liu commented Mar 22, 2018

@abhi Can we remove socat as well? I think we just need a goroutine to a tcp connection to the port and forward traffic.

@abhi
Copy link
Member Author

abhi commented Mar 22, 2018

@Random-Liu yes. Just raising the PR for e2e.

@Random-Liu Random-Liu added this to the v1.0.0-rc.0 milestone Mar 22, 2018
@Random-Liu
Copy link
Member

@abhi I see. Will review it when it is ready. :)

@Random-Liu Random-Liu self-assigned this Mar 22, 2018
@abhi abhi changed the title [WIP] Using netns to perform socat Getting rid of nsenter and socat Mar 24, 2018
nsenter, err := exec.LookPath("nsenter")
if err != nil {
return errors.Wrap(err, "failed to find nsenter")
if s.NetNS == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

|| s.NetNS.Closed()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats already checked by netns.Do

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wg.Done()
}()
wg.Wait()
logrus.Infof("Finish copy port forward input for %q port %d: %v", id, port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a log for both input copy and output copy, and move them into goroutine?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

go func() {
if _, err := io.Copy(client, stream); err != nil {
logrus.WithError(err).Errorf("Failed to copy port forward input from %q port %d", id, port)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

client.Close()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a defer on top

logrus.WithError(err).Errorf("Failed to copy port forward output for %q port %d", id, port)
}
wg.Done()
}()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stream.Close()?

Are these 2 Close() are necessary?
If dst is closed, src is open, but there is no new input, will io.Copy stop?

  • If it does, we don't need the 2 Close().
  • If it doesn't, I think we'll probably need them.

@@ -17,24 +17,22 @@ limitations under the License.
package server
Copy link
Member

@Random-Liu Random-Liu Mar 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update dependencies in README.md and travis.

@abhi abhi force-pushed the socat branch 3 times, most recently from 19eb7a6 to 57790c7 Compare March 24, 2018 15:57
@abhi
Copy link
Member Author

abhi commented Mar 24, 2018

@Random-Liu done.

@Random-Liu
Copy link
Member

Random-Liu commented Mar 26, 2018

@abhi We need to start 2 goroutines to copy stream. However, the 2 goroutines may not be in the same network namespace. We are not sure whether it will work or not. The test result shows that it works, but we need to double check with the golang team.

I don't think we have time to figure that out before the coming rc.0 release. @abhi Let's only remove nsenter and still use socat in this PR. We can remove socat in rc.1 release.

@abhi
Copy link
Member Author

abhi commented Mar 26, 2018

@Random-Liu yes I am of the same opinion as well. I will remove the socat commits.

@Random-Liu
Copy link
Member

@abhi also pointed me to another potential issue containernetworking/plugins#98.

Given so, let's move this issue to next release, so that we have more time to investigate this.

It is safe to move this PR to next release, because there is no actual functionality change, we just get rid of 2 binary dependencies nsenter and socat in this PR.

@Random-Liu
Copy link
Member

We plan to cut an early rc.1 release today to carry several fix and improvement. Move this to rc.2.

@Random-Liu Random-Liu modified the milestones: v1.0.0-rc.1, v1.0.0-rc.2 Apr 3, 2018
@Random-Liu
Copy link
Member

Random-Liu commented Apr 5, 2018

@abhi Here is a piece of code:

package main

import (
	"fmt"
	"io"
	"os"
	"sync"
	"time"
)

func main() {
	f, err := os.OpenFile("io", os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		panic(err)
	}
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		io.Copy(os.Stdout, f)
		fmt.Println("file -> stdout done")
		wg.Done()
	}()
	go func() {
		io.Copy(f, os.Stdin)
		fmt.Println("stdin -> file done")
		wg.Done()
	}()
	time.Sleep(5 * time.Second)
	f.Close()
	wg.Wait()
	fmt.Println("all done")
}

You will see, after 5 seconds, the program won't exit even though f is closed. Because there is no input from os.Stdin to drive the io.Copy to write once, and io.Copy won't know f has been closed. Once you input something into stdin, the problem will exit.

So basically io.Copy will stop immediately when input is closed, but when output is closed, it won't stop until there is something from input.

To fix this, we should explicitly close input of the other io.Copy when one io.Copy is done. This is what I suggested in #691 (comment).

This commit removes the usage of nsenter and uses netns
to perform socat operation.

Signed-off-by: abhi <[email protected]>
nsenter, err := exec.LookPath("nsenter")
if err != nil {
return errors.Wrap(err, "failed to find nsenter")
if s.NetNS == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if err != nil {
return errors.Wrap(err, "failed to find nsenter")
if s.NetNS == nil {
return errors.Errorf("failed to find network namespace fo sandbox %q in store", id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

network namespace for sandbox %q is closed

var wg sync.WaitGroup
client, err := net.Dial("tcp4", fmt.Sprintf("localhost:%d", port))
if err != nil {
return errors.Wrap(err, "failed to dial")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "failed to dial %q", port

go func() {
defer client.Close()
if _, err := io.Copy(client, stream); err != nil {
logrus.WithError(err).Errorf("Failed to copy port forward input from %q port %d", id, port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/from/for?

if _, err := io.Copy(client, stream); err != nil {
logrus.WithError(err).Errorf("Failed to copy port forward input from %q port %d", id, port)
}
logrus.Infof("Finish copy port forward input for %q port %d: %v", id, port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove %v

if _, err := io.Copy(stream, client); err != nil {
logrus.WithError(err).Errorf("Failed to copy port forward output for %q port %d", id, port)
}
logrus.Infof("Finish copy port forward output for %q port %d: %v", id, port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto.

@Random-Liu
Copy link
Member

/lgtm

@Random-Liu Random-Liu merged commit 3d0706c into containerd:master Apr 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants