enable podman-remote on windows

build a podman-remote binary for windows that allows users to use the
remote client on windows and interact with podman on linux system.

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2019-04-22 16:01:31 -05:00
parent b5af10ce5a
commit 0b6bb6a3d3
38 changed files with 3020 additions and 2820 deletions

View File

@@ -44,8 +44,8 @@ func NewBridge(bridge string) (*Connection, error) {
}
c.conn = PipeCon{nil, cmd, &r, &w}
c.address = ""
c.reader = bufio.NewReader(r)
c.writer = bufio.NewWriter(w)
c.Reader = bufio.NewReader(r)
c.Writer = bufio.NewWriter(w)
err = cmd.Start()
if err != nil {

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"net"
"strings"
)
@@ -14,36 +15,38 @@ import (
type Call struct {
*bufio.Reader
*bufio.Writer
in *serviceCall
Conn *net.Conn
Request *[]byte
In *serviceCall
Continues bool
Upgrade bool
}
// WantsMore indicates if the calling client accepts more than one reply to this method call.
func (c *Call) WantsMore() bool {
return c.in.More
return c.In.More
}
// WantsUpgrade indicates that the calling client wants the connection to be upgraded.
func (c *Call) WantsUpgrade() bool {
return c.in.Upgrade
return c.In.Upgrade
}
// IsOneway indicate that the calling client does not expect a reply.
func (c *Call) IsOneway() bool {
return c.in.Oneway
return c.In.Oneway
}
// GetParameters retrieves the method call parameters.
func (c *Call) GetParameters(p interface{}) error {
if c.in.Parameters == nil {
if c.In.Parameters == nil {
return fmt.Errorf("empty parameters")
}
return json.Unmarshal(*c.in.Parameters, p)
return json.Unmarshal(*c.In.Parameters, p)
}
func (c *Call) sendMessage(r *serviceReply) error {
if c.in.Oneway {
if c.In.Oneway {
return nil
}
@@ -75,7 +78,7 @@ func (c *Call) Reply(parameters interface{}) error {
})
}
if !c.in.More {
if !c.In.More {
return fmt.Errorf("call did not set more, it does not expect continues")
}

View File

@@ -74,7 +74,7 @@ func (s *Service) getInterfaceDescription(c Call, name string) error {
return c.replyGetInterfaceDescription(description)
}
func (s *Service) handleMessage(reader *bufio.Reader, writer *bufio.Writer, request []byte) error {
func (s *Service) HandleMessage(conn *net.Conn, reader *bufio.Reader, writer *bufio.Writer, request []byte) error {
var in serviceCall
err := json.Unmarshal(request, &in)
@@ -84,9 +84,11 @@ func (s *Service) handleMessage(reader *bufio.Reader, writer *bufio.Writer, requ
}
c := Call{
Reader: reader,
Writer: writer,
in: &in,
Conn: conn,
Reader: reader,
Writer: writer,
In: &in,
Request: &request,
}
r := strings.LastIndex(in.Method, ".")
@@ -131,7 +133,7 @@ func (s *Service) handleConnection(conn net.Conn, wg *sync.WaitGroup) {
break
}
err = s.handleMessage(reader, writer, request[:len(request)-1])
err = s.HandleMessage(&conn, reader, writer, request[:len(request)-1])
if err != nil {
// FIXME: report error
//fmt.Fprintf(os.Stderr, "handleMessage: %v", err)
@@ -179,25 +181,36 @@ func (s *Service) parseAddress(address string) error {
return nil
}
func getListener(protocol string, address string) (net.Listener, error) {
func (s *Service) GetListener() (*net.Listener, error) {
s.mutex.Lock()
l := s.listener
s.mutex.Unlock()
return &l, nil
}
func (s *Service) setListener() error {
l := activationListener()
if l == nil {
if protocol == "unix" && address[0] != '@' {
os.Remove(address)
if s.protocol == "unix" && s.address[0] != '@' {
os.Remove(s.address)
}
var err error
l, err = net.Listen(protocol, address)
l, err = net.Listen(s.protocol, s.address)
if err != nil {
return nil, err
return err
}
if protocol == "unix" && address[0] != '@' {
if s.protocol == "unix" && s.address[0] != '@' {
l.(*net.UnixListener).SetUnlinkOnClose(true)
}
}
return l, nil
s.mutex.Lock()
s.listener = l
s.mutex.Unlock()
return nil
}
func (s *Service) refreshTimeout(timeout time.Duration) error {
@@ -216,26 +229,84 @@ func (s *Service) refreshTimeout(timeout time.Duration) error {
}
// Listen starts a Service.
func (s *Service) Listen(address string, timeout time.Duration) error {
var wg sync.WaitGroup
defer func() { s.teardown(); wg.Wait() }()
func (s *Service) Bind(address string) error {
s.mutex.Lock()
if s.running {
s.mutex.Unlock()
return fmt.Errorf("Listen(): already running")
return fmt.Errorf("Init(): already running")
}
s.mutex.Unlock()
s.parseAddress(address)
l, err := getListener(s.protocol, s.address)
err := s.setListener()
if err != nil {
return err
}
return nil
}
// Listen starts a Service.
func (s *Service) Listen(address string, timeout time.Duration) error {
var wg sync.WaitGroup
defer func() { s.teardown(); wg.Wait() }()
err := s.Bind(address)
if err != nil {
return err
}
s.mutex.Lock()
s.listener = l
s.running = true
l := s.listener
s.mutex.Unlock()
for s.running {
if timeout != 0 {
if err := s.refreshTimeout(timeout); err != nil {
return err
}
}
conn, err := l.Accept()
if err != nil {
if err.(net.Error).Timeout() {
s.mutex.Lock()
if s.conncounter == 0 {
s.mutex.Unlock()
return ServiceTimeoutError{}
}
s.mutex.Unlock()
continue
}
if !s.running {
return nil
}
return err
}
s.mutex.Lock()
s.conncounter++
s.mutex.Unlock()
wg.Add(1)
go s.handleConnection(conn, &wg)
}
return nil
}
// Listen starts a Service.
func (s *Service) DoListen(timeout time.Duration) error {
var wg sync.WaitGroup
defer func() { s.teardown(); wg.Wait() }()
s.mutex.Lock()
l := s.listener
s.mutex.Unlock()
if l == nil {
return fmt.Errorf("No listener set")
}
s.mutex.Lock()
s.running = true
s.mutex.Unlock()

View File

@@ -31,7 +31,7 @@ func TestService(t *testing.T) {
r := bufio.NewReader(&br)
var b bytes.Buffer
w := bufio.NewWriter(&b)
if err := service.handleMessage(r, w, []byte{0}); err == nil {
if err := service.HandleMessage(nil, r, w, []byte{0}); err == nil {
t.Fatal("HandleMessage returned non-error")
}
})
@@ -42,7 +42,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"foo.GetInterfaceDescription" fdgdfg}`)
if err := service.handleMessage(r, w, msg); err == nil {
if err := service.HandleMessage(nil, r, w, msg); err == nil {
t.Fatal("HandleMessage returned no error on invalid json")
}
})
@@ -53,7 +53,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"foo.GetInterfaceDescription"}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatal("HandleMessage returned error on wrong interface")
}
expect(t, `{"parameters":{"interface":"foo"},"error":"org.varlink.service.InterfaceNotFound"}`+"\000",
@@ -66,7 +66,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"InvalidMethod"}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatal("HandleMessage returned error on invalid method")
}
expect(t, `{"parameters":{"parameter":"method"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
@@ -79,7 +79,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.WrongMethod"}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatal("HandleMessage returned error on wrong method")
}
expect(t, `{"parameters":{"method":"WrongMethod"},"error":"org.varlink.service.MethodNotFound"}`+"\000",
@@ -92,7 +92,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters": null}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"parameter":"parameters"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
@@ -105,7 +105,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{}}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"parameter":"interface"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
@@ -118,7 +118,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{"interface":"foo"}}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"parameter":"interface"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
@@ -131,7 +131,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{"interface":"org.varlink.service"}}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"description":"# The Varlink Service Interface is provided by every varlink service. It\n# describes the service and the interfaces it implements.\ninterface org.varlink.service\n\n# Get a list of all the interfaces a service provides and information\n# about the implementation.\nmethod GetInfo() -\u003e (\n vendor: string,\n product: string,\n version: string,\n url: string,\n interfaces: []string\n)\n\n# Get the description of an interface that is implemented by this service.\nmethod GetInterfaceDescription(interface: string) -\u003e (description: string)\n\n# The requested interface was not found.\nerror InterfaceNotFound (interface: string)\n\n# The requested method was not found\nerror MethodNotFound (method: string)\n\n# The interface defines the requested method, but the service does not\n# implement it.\nerror MethodNotImplemented (method: string)\n\n# One of the passed parameters is invalid.\nerror InvalidParameter (parameter: string)"}}`+"\000",
@@ -144,7 +144,7 @@ func TestService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.varlink.service.GetInfo"}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"vendor":"Varlink","product":"Varlink Test","version":"1","url":"https://github.com/varlink/go/varlink","interfaces":["org.varlink.service"]}}`+"\000",
@@ -224,7 +224,7 @@ func TestMoreService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.example.test.Pingf"}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"parameters":{"method":"Pingf"},"error":"org.varlink.service.MethodNotImplemented"}`+"\000",
@@ -237,7 +237,7 @@ func TestMoreService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.example.test.PingError", "more" : true}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"error":"org.example.test.PingError"}`+"\000",
@@ -249,7 +249,7 @@ func TestMoreService(t *testing.T) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
msg := []byte(`{"method":"org.example.test.Ping", "more" : true}`)
if err := service.handleMessage(r, w, msg); err != nil {
if err := service.HandleMessage(nil, r, w, msg); err != nil {
t.Fatalf("HandleMessage returned error: %v", err)
}
expect(t, `{"continues":true}`+"\000"+`{"continues":true}`+"\000"+`{}`+"\000",