github.com/rootless-containers/rootlesskit/v2@v2.3.4/pkg/messages/messages.go (about) 1 package messages 2 3 import ( 4 "fmt" 5 "io" 6 "reflect" 7 8 "github.com/rootless-containers/rootlesskit/v2/pkg/lowlevelmsgutil" 9 "github.com/sirupsen/logrus" 10 ) 11 12 // Message for parent-child communication. 13 // Sent as JSON, with uint32le length header. 14 type Message struct { 15 Name string // Name is like "MessageParentHello". Automatically filled on [Send. 16 U 17 } 18 19 func (m *Message) FulfillName() error { 20 uT := reflect.TypeOf(m.U) 21 uV := reflect.ValueOf(m.U) 22 uN := uT.NumField() 23 for i := 0; i < uN; i++ { 24 uTF := uT.Field(i) 25 uVF := uV.Field(i) 26 if !uVF.IsNil() { 27 m.Name = uTF.Name 28 return nil 29 } 30 } 31 return fmt.Errorf("failed to fulfill the name for message %+v", m) 32 } 33 34 // U is a union. 35 type U struct { 36 *ParentHello 37 *ChildHello 38 *ParentInitIdmapCompleted 39 *ChildInitUserNSCompleted 40 *ParentInitNetworkDriverCompleted 41 *ParentInitPortDriverCompleted 42 } 43 44 type ParentHello struct { 45 } 46 47 type ChildHello struct { 48 } 49 50 type ParentInitIdmapCompleted struct { 51 } 52 53 type ChildInitUserNSCompleted struct { 54 } 55 56 type ParentInitNetworkDriverCompleted struct { 57 // Fields are empty for HostNetwork. 58 Dev string 59 IP string 60 Netmask int 61 Gateway string 62 DNS []string 63 MTU int 64 // NetworkDriverOpaque strings are specific to driver 65 NetworkDriverOpaque map[string]string 66 } 67 68 type ParentInitPortDriverCompleted struct { 69 // Fields are empty for port driver "none" 70 PortDriverOpaque map[string]string 71 } 72 73 func Send(w io.Writer, m *Message) error { 74 if m.Name == "" { 75 if err := m.FulfillName(); err != nil { 76 return err 77 } 78 } 79 logrus.Debugf("Sending %+v", m) 80 if _, err := lowlevelmsgutil.MarshalToWriter(w, m); err != nil { 81 return fmt.Errorf("failed to send message %+v: %w", m, err) 82 } 83 return nil 84 } 85 86 func Recv(r io.Reader) (*Message, error) { 87 var m Message 88 if _, err := lowlevelmsgutil.UnmarshalFromReader(r, &m); err != nil { 89 return nil, err 90 } 91 logrus.Debugf("Received %+v", m) 92 if m.Name == "" { 93 return nil, fmt.Errorf("failed to parse message %+v", m) 94 } 95 return &m, nil 96 } 97 98 func WaitFor(r io.Reader, name string) (*Message, error) { 99 msg, err := Recv(r) 100 if err != nil { 101 return nil, err 102 } 103 if msg.Name != name { 104 return nil, fmt.Errorf("expected %q, got %+v", name, msg) 105 } 106 return msg, nil 107 } 108 109 func Name(x interface{}) string { 110 t := reflect.TypeOf(x) 111 if t.Kind() == reflect.Ptr { 112 return t.Elem().Name() 113 } 114 return t.Name() 115 }