github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/cmd/lhsm-plugin-posix/main.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 main
     6  
     7  import (
     8  	"os"
     9  	"os/signal"
    10  	"path"
    11  	"syscall"
    12  
    13  	"github.com/pkg/errors"
    14  
    15  	"github.com/intel-hpdd/lemur/cmd/lhsm-plugin-posix/posix"
    16  	"github.com/intel-hpdd/lemur/dmplugin"
    17  	"github.com/intel-hpdd/lemur/pkg/fsroot"
    18  	"github.com/intel-hpdd/logging/alert"
    19  	"github.com/intel-hpdd/logging/debug"
    20  )
    21  
    22  type (
    23  	posixConfig struct {
    24  		NumThreads int                   `hcl:"num_threads"`
    25  		Archives   posix.ArchiveSet      `hcl:"archive"`
    26  		Checksums  *posix.ChecksumConfig `hcl:"checksums"`
    27  	}
    28  )
    29  
    30  func (c *posixConfig) String() string {
    31  	return dmplugin.DisplayConfig(c)
    32  }
    33  
    34  func (c *posixConfig) Merge(other *posixConfig) *posixConfig {
    35  	result := new(posixConfig)
    36  
    37  	if other.NumThreads > 0 {
    38  		result.NumThreads = other.NumThreads
    39  	} else {
    40  		result.NumThreads = c.NumThreads
    41  
    42  	}
    43  
    44  	result.Archives = c.Archives.Merge(other.Archives)
    45  	result.Checksums = c.Checksums.Merge(other.Checksums)
    46  
    47  	return result
    48  }
    49  
    50  func start(plugin *dmplugin.Plugin, cfg *posixConfig) {
    51  	// All base filesystem operations will be relative to current directory
    52  	err := os.Chdir(plugin.Base())
    53  	if err != nil {
    54  		alert.Abort(errors.Wrap(err, "chdir failed"))
    55  	}
    56  
    57  	interruptHandler(func() {
    58  		plugin.Stop()
    59  	})
    60  
    61  	for _, a := range cfg.Archives {
    62  		mover, err := posix.NewMover(a)
    63  		if err != nil {
    64  			alert.Abort(errors.Wrap(err, "Unable to create new POSIX mover"))
    65  		}
    66  
    67  		plugin.AddMover(&dmplugin.Config{
    68  			Mover:      mover,
    69  			NumThreads: cfg.NumThreads,
    70  			ArchiveID:  uint32(a.ID),
    71  		})
    72  	}
    73  
    74  	plugin.Run()
    75  }
    76  
    77  func getMergedConfig(plugin *dmplugin.Plugin) (*posixConfig, error) {
    78  	baseCfg := &posixConfig{
    79  		Checksums: &posix.ChecksumConfig{},
    80  	}
    81  
    82  	var cfg posixConfig
    83  	err := dmplugin.LoadConfig(plugin.ConfigFile(), &cfg)
    84  	if err != nil {
    85  		return nil, errors.Errorf("Failed to load config: %s", err)
    86  	}
    87  
    88  	return baseCfg.Merge(&cfg), nil
    89  }
    90  
    91  func main() {
    92  	plugin, err := dmplugin.New(path.Base(os.Args[0]), func(path string) (fsroot.Client, error) {
    93  		return fsroot.New(path)
    94  	})
    95  	if err != nil {
    96  		alert.Abort(errors.Wrap(err, "failed to initialize plugin"))
    97  	}
    98  	defer plugin.Close()
    99  
   100  	cfg, err := getMergedConfig(plugin)
   101  	if err != nil {
   102  		alert.Abort(errors.Wrap(err, "Unable to determine plugin configuration"))
   103  	}
   104  
   105  	debug.Printf("PosixMover configuration:\n%v", cfg)
   106  
   107  	if len(cfg.Archives) == 0 {
   108  		alert.Abort(errors.New("Invalid configuration: No archives defined"))
   109  	}
   110  
   111  	for _, archive := range cfg.Archives {
   112  		debug.Print(archive)
   113  		if err := archive.CheckValid(); err != nil {
   114  			alert.Abort(errors.Wrap(err, "Invalid configuration"))
   115  		}
   116  	}
   117  
   118  	posix.DefaultChecksums = *cfg.Checksums
   119  
   120  	start(plugin, cfg)
   121  }
   122  
   123  func interruptHandler(once func()) {
   124  	c := make(chan os.Signal, 1)
   125  	signal.Notify(c, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM)
   126  
   127  	go func() {
   128  		stopping := false
   129  		for sig := range c {
   130  			debug.Printf("signal received: %s", sig)
   131  			if !stopping {
   132  				stopping = true
   133  				once()
   134  			}
   135  		}
   136  	}()
   137  }