github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/modelworkermanager/manifold.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelworkermanager
     5  
     6  import (
     7  	"github.com/juju/clock"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/worker/v3"
    10  	"github.com/juju/worker/v3/dependency"
    11  
    12  	"github.com/juju/juju/agent"
    13  	"github.com/juju/juju/apiserver/apiserverhttp"
    14  	"github.com/juju/juju/pki"
    15  	jworker "github.com/juju/juju/worker"
    16  	"github.com/juju/juju/worker/common"
    17  	workerstate "github.com/juju/juju/worker/state"
    18  	"github.com/juju/juju/worker/syslogger"
    19  )
    20  
    21  // Logger defines the logging methods used by the worker.
    22  type Logger interface {
    23  	Debugf(string, ...interface{})
    24  	Warningf(string, ...interface{})
    25  	Errorf(string, ...interface{})
    26  	Infof(string, ...interface{})
    27  }
    28  
    29  // ManifoldConfig holds the information necessary to run a model worker manager
    30  // in a dependency.Engine.
    31  type ManifoldConfig struct {
    32  	AgentName      string
    33  	AuthorityName  string
    34  	StateName      string
    35  	MuxName        string
    36  	SyslogName     string
    37  	Clock          clock.Clock
    38  	NewWorker      func(Config) (worker.Worker, error)
    39  	NewModelWorker NewModelWorkerFunc
    40  	ModelMetrics   ModelMetrics
    41  	Logger         Logger
    42  }
    43  
    44  // Validate validates the manifold configuration.
    45  func (config ManifoldConfig) Validate() error {
    46  	if config.AgentName == "" {
    47  		return errors.NotValidf("empty AgentName")
    48  	}
    49  	if config.AuthorityName == "" {
    50  		return errors.NotValidf("empty AuthorityName")
    51  	}
    52  	if config.StateName == "" {
    53  		return errors.NotValidf("empty StateName")
    54  	}
    55  	if config.MuxName == "" {
    56  		return errors.NotValidf("empty MuxName")
    57  	}
    58  	if config.SyslogName == "" {
    59  		return errors.NotValidf("empty SyslogName")
    60  	}
    61  	if config.NewWorker == nil {
    62  		return errors.NotValidf("nil NewWorker")
    63  	}
    64  	if config.NewModelWorker == nil {
    65  		return errors.NotValidf("nil NewModelWorker")
    66  	}
    67  	if config.ModelMetrics == nil {
    68  		return errors.NotValidf("nil ModelMetrics")
    69  	}
    70  	if config.Logger == nil {
    71  		return errors.NotValidf("nil Logger")
    72  	}
    73  	return nil
    74  }
    75  
    76  // Manifold returns a dependency.Manifold that will run a model worker manager.
    77  func Manifold(config ManifoldConfig) dependency.Manifold {
    78  	return dependency.Manifold{
    79  		Inputs: []string{
    80  			config.AgentName,
    81  			config.AuthorityName,
    82  			config.MuxName,
    83  			config.StateName,
    84  			config.SyslogName,
    85  		},
    86  		Start: config.start,
    87  	}
    88  }
    89  
    90  // start is a method on ManifoldConfig because it's more readable than a closure.
    91  func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
    92  	if err := config.Validate(); err != nil {
    93  		return nil, errors.Trace(err)
    94  	}
    95  	var agent agent.Agent
    96  	if err := context.Get(config.AgentName, &agent); err != nil {
    97  		return nil, errors.Trace(err)
    98  	}
    99  
   100  	var authority pki.Authority
   101  	if err := context.Get(config.AuthorityName, &authority); err != nil {
   102  		return nil, errors.Trace(err)
   103  	}
   104  
   105  	var mux *apiserverhttp.Mux
   106  	if err := context.Get(config.MuxName, &mux); err != nil {
   107  		return nil, errors.Trace(err)
   108  	}
   109  
   110  	var sysLogger syslogger.SysLogger
   111  	if err := context.Get(config.SyslogName, &sysLogger); err != nil {
   112  		return nil, errors.Trace(err)
   113  	}
   114  
   115  	var stTracker workerstate.StateTracker
   116  	if err := context.Get(config.StateName, &stTracker); err != nil {
   117  		return nil, errors.Trace(err)
   118  	}
   119  	statePool, err := stTracker.Use()
   120  	if err != nil {
   121  		return nil, errors.Trace(err)
   122  	}
   123  
   124  	machineID := agent.CurrentConfig().Tag().Id()
   125  
   126  	systemState, err := statePool.SystemState()
   127  	if err != nil {
   128  		return nil, errors.Trace(err)
   129  	}
   130  	w, err := config.NewWorker(Config{
   131  		Authority:    authority,
   132  		Clock:        config.Clock,
   133  		Logger:       config.Logger,
   134  		MachineID:    machineID,
   135  		ModelWatcher: systemState,
   136  		ModelMetrics: config.ModelMetrics,
   137  		Mux:          mux,
   138  		Controller: StatePoolController{
   139  			StatePool: statePool,
   140  			SysLogger: sysLogger,
   141  		},
   142  		NewModelWorker: config.NewModelWorker,
   143  		ErrorDelay:     jworker.RestartDelay,
   144  	})
   145  	if err != nil {
   146  		_ = stTracker.Done()
   147  		return nil, errors.Trace(err)
   148  	}
   149  	return common.NewCleanupWorker(w, func() { _ = stTracker.Done() }), nil
   150  }