github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/dmplugin/plugin.go (about)

     1  // Copyright (c) 2018 DDN. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package dmplugin
     6  
     7  import (
     8  	"net"
     9  	"path"
    10  	"sync"
    11  	"time"
    12  
    13  	"github.com/pkg/errors"
    14  
    15  	"golang.org/x/net/context"
    16  
    17  	pb "github.com/intel-hpdd/lemur/pdm"
    18  	"github.com/intel-hpdd/lemur/pkg/fsroot"
    19  	"google.golang.org/grpc"
    20  )
    21  
    22  // Plugin manages communication between the HSM agent and the datamover
    23  type Plugin struct {
    24  	name          string
    25  	ctx           context.Context
    26  	cancelContext context.CancelFunc
    27  	rpcConn       *grpc.ClientConn
    28  	cli           pb.DataMoverClient
    29  	movers        []*DataMoverClient
    30  	fsClient      fsroot.Client
    31  	config        *pluginConfig
    32  }
    33  
    34  func unixDialer(addr string, timeout time.Duration) (net.Conn, error) {
    35  	return net.DialTimeout("unix", addr, timeout)
    36  }
    37  
    38  // New returns a new *Plugin, or error
    39  func New(name string, initClient func(string) (fsroot.Client, error)) (*Plugin, error) {
    40  	config := mustInitConfig()
    41  
    42  	fsClient, err := initClient(config.ClientRoot)
    43  	if err != nil {
    44  		return nil, errors.Wrap(err, "client init failed")
    45  	}
    46  
    47  	ctx, cancel := context.WithCancel(context.Background())
    48  	conn, err := grpc.Dial(config.AgentAddress, grpc.WithDialer(unixDialer), grpc.WithInsecure())
    49  	if err != nil {
    50  		return nil, errors.Wrap(err, "dial gprc server failed")
    51  	}
    52  	return &Plugin{
    53  		name:          name,
    54  		rpcConn:       conn,
    55  		ctx:           ctx,
    56  		cancelContext: cancel,
    57  		cli:           pb.NewDataMoverClient(conn),
    58  		fsClient:      fsClient,
    59  		config:        config,
    60  	}, nil
    61  }
    62  
    63  // FsName returns the associated Lustre filesystem name
    64  func (a *Plugin) FsName() string {
    65  	return a.fsClient.FsName()
    66  }
    67  
    68  // Base returns the root directory for plugin.
    69  func (a *Plugin) Base() string {
    70  	return a.fsClient.Path()
    71  }
    72  
    73  // ConfigFile returns path to the plugin config file.
    74  func (a *Plugin) ConfigFile() string {
    75  	return path.Join(a.config.ConfigDir, a.name)
    76  }
    77  
    78  // AddMover registers a new data mover with the plugin
    79  func (a *Plugin) AddMover(config *Config) {
    80  	dm := NewMover(a, a.cli, config)
    81  	a.movers = append(a.movers, dm)
    82  }
    83  
    84  // Run starts the data mover threads and blocks until they complete.
    85  func (a *Plugin) Run() {
    86  	var wg sync.WaitGroup
    87  	for _, dm := range a.movers {
    88  		wg.Add(1)
    89  		go func(dm *DataMoverClient) {
    90  			dm.Run(a.ctx)
    91  			wg.Done()
    92  		}(dm)
    93  	}
    94  	wg.Wait()
    95  }
    96  
    97  // Stop signals to all registered data movers that they should stop processing
    98  // and shut down
    99  func (a *Plugin) Stop() {
   100  	a.cancelContext()
   101  }
   102  
   103  // Close closes the connection to the agent
   104  func (a *Plugin) Close() error {
   105  	return errors.Wrap(a.rpcConn.Close(), "closed failed")
   106  }