github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/runtime/v2/logging/logging.go (about)

     1  // +build !windows
     2  
     3  /*
     4     Copyright The containerd Authors.
     5  
     6     Licensed under the Apache License, Version 2.0 (the "License");
     7     you may not use this file except in compliance with the License.
     8     You may obtain a copy of the License at
     9  
    10         http://www.apache.org/licenses/LICENSE-2.0
    11  
    12     Unless required by applicable law or agreed to in writing, software
    13     distributed under the License is distributed on an "AS IS" BASIS,
    14     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15     See the License for the specific language governing permissions and
    16     limitations under the License.
    17  */
    18  
    19  package logging
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  	"os/signal"
    27  
    28  	"golang.org/x/sys/unix"
    29  )
    30  
    31  // Config of the container logs
    32  type Config struct {
    33  	ID        string
    34  	Namespace string
    35  	Stdout    io.Reader
    36  	Stderr    io.Reader
    37  }
    38  
    39  // LoggerFunc is implemented by custom v2 logging binaries
    40  type LoggerFunc func(context.Context, *Config, func() error) error
    41  
    42  // Run the logging driver
    43  func Run(fn LoggerFunc) {
    44  	ctx, cancel := context.WithCancel(context.Background())
    45  	defer cancel()
    46  
    47  	config := &Config{
    48  		ID:        os.Getenv("CONTAINER_ID"),
    49  		Namespace: os.Getenv("CONTAINER_NAMESPACE"),
    50  		Stdout:    os.NewFile(3, "CONTAINER_STDOUT"),
    51  		Stderr:    os.NewFile(4, "CONTAINER_STDERR"),
    52  	}
    53  	var (
    54  		s     = make(chan os.Signal, 32)
    55  		errCh = make(chan error, 1)
    56  		wait  = os.NewFile(5, "CONTAINER_WAIT")
    57  	)
    58  	signal.Notify(s, unix.SIGTERM)
    59  
    60  	go func() {
    61  		errCh <- fn(ctx, config, wait.Close)
    62  	}()
    63  
    64  	for {
    65  		select {
    66  		case <-s:
    67  			cancel()
    68  		case err := <-errCh:
    69  			if err != nil {
    70  				fmt.Fprintln(os.Stderr, err)
    71  				os.Exit(1)
    72  			}
    73  			os.Exit(0)
    74  		}
    75  	}
    76  }