github.com/lalkh/containerd@v1.4.3/cmd/containerd/command/publish.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package command
    18  
    19  import (
    20  	gocontext "context"
    21  	"io"
    22  	"io/ioutil"
    23  	"net"
    24  	"os"
    25  	"time"
    26  
    27  	eventsapi "github.com/containerd/containerd/api/services/events/v1"
    28  	"github.com/containerd/containerd/errdefs"
    29  	"github.com/containerd/containerd/namespaces"
    30  	"github.com/containerd/containerd/pkg/dialer"
    31  	"github.com/gogo/protobuf/types"
    32  	"github.com/pkg/errors"
    33  	"github.com/urfave/cli"
    34  	"google.golang.org/grpc"
    35  	"google.golang.org/grpc/backoff"
    36  )
    37  
    38  var publishCommand = cli.Command{
    39  	Name:  "publish",
    40  	Usage: "binary to publish events to containerd",
    41  	Flags: []cli.Flag{
    42  		cli.StringFlag{
    43  			Name:  "namespace",
    44  			Usage: "namespace to publish to",
    45  		},
    46  		cli.StringFlag{
    47  			Name:  "topic",
    48  			Usage: "topic of the event",
    49  		},
    50  	},
    51  	Action: func(context *cli.Context) error {
    52  		ctx := namespaces.WithNamespace(gocontext.Background(), context.String("namespace"))
    53  		topic := context.String("topic")
    54  		if topic == "" {
    55  			return errors.Wrap(errdefs.ErrInvalidArgument, "topic required to publish event")
    56  		}
    57  		payload, err := getEventPayload(os.Stdin)
    58  		if err != nil {
    59  			return err
    60  		}
    61  		client, err := connectEvents(context.GlobalString("address"))
    62  		if err != nil {
    63  			return err
    64  		}
    65  		if _, err := client.Publish(ctx, &eventsapi.PublishRequest{
    66  			Topic: topic,
    67  			Event: payload,
    68  		}); err != nil {
    69  			return errdefs.FromGRPC(err)
    70  		}
    71  		return nil
    72  	},
    73  }
    74  
    75  func getEventPayload(r io.Reader) (*types.Any, error) {
    76  	data, err := ioutil.ReadAll(r)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	var any types.Any
    81  	if err := any.Unmarshal(data); err != nil {
    82  		return nil, err
    83  	}
    84  	return &any, nil
    85  }
    86  
    87  func connectEvents(address string) (eventsapi.EventsClient, error) {
    88  	conn, err := connect(address, dialer.ContextDialer)
    89  	if err != nil {
    90  		return nil, errors.Wrapf(err, "failed to dial %q", address)
    91  	}
    92  	return eventsapi.NewEventsClient(conn), nil
    93  }
    94  
    95  func connect(address string, d func(gocontext.Context, string) (net.Conn, error)) (*grpc.ClientConn, error) {
    96  	backoffConfig := backoff.DefaultConfig
    97  	backoffConfig.MaxDelay = 3 * time.Second
    98  	connParams := grpc.ConnectParams{
    99  		Backoff: backoffConfig,
   100  	}
   101  	gopts := []grpc.DialOption{
   102  		grpc.WithBlock(),
   103  		grpc.WithInsecure(),
   104  		grpc.WithContextDialer(d),
   105  		grpc.FailOnNonTempDialError(true),
   106  		grpc.WithConnectParams(connParams),
   107  	}
   108  	ctx, cancel := gocontext.WithTimeout(gocontext.Background(), 2*time.Second)
   109  	defer cancel()
   110  	conn, err := grpc.DialContext(ctx, dialer.DialAddress(address), gopts...)
   111  	if err != nil {
   112  		return nil, errors.Wrapf(err, "failed to dial %q", address)
   113  	}
   114  	return conn, nil
   115  }