github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/provisioner/container_initialisation_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provisioner
     5  
     6  import (
     7  	"errors"
     8  	"sync"
     9  
    10  	"github.com/juju/names/v5"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils/v3"
    13  	"go.uber.org/mock/gomock"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/agent"
    17  	apiprovisioner "github.com/juju/juju/api/agent/provisioner"
    18  	provisionermocks "github.com/juju/juju/api/agent/provisioner/mocks"
    19  	apimocks "github.com/juju/juju/api/base/mocks"
    20  	"github.com/juju/juju/container"
    21  	"github.com/juju/juju/container/factory"
    22  	"github.com/juju/juju/container/testing"
    23  	"github.com/juju/juju/core/instance"
    24  	"github.com/juju/juju/core/machinelock"
    25  	"github.com/juju/juju/core/network"
    26  	"github.com/juju/juju/rpc/params"
    27  	coretesting "github.com/juju/juju/testing"
    28  	jujuversion "github.com/juju/juju/version"
    29  )
    30  
    31  type containerSetupSuite struct {
    32  	coretesting.BaseSuite
    33  
    34  	modelUUID      utils.UUID
    35  	controllerUUID utils.UUID
    36  
    37  	initialiser  *testing.MockInitialiser
    38  	facadeCaller *apimocks.MockFacadeCaller
    39  	machine      *provisionermocks.MockMachineProvisioner
    40  	manager      *testing.MockManager
    41  
    42  	machineLock *fakeMachineLock
    43  }
    44  
    45  func (s *containerSetupSuite) SetUpTest(c *gc.C) {
    46  	s.BaseSuite.SetUpTest(c)
    47  
    48  	s.modelUUID = utils.MustNewUUID()
    49  	s.controllerUUID = utils.MustNewUUID()
    50  
    51  	s.machineLock = &fakeMachineLock{}
    52  }
    53  
    54  var _ = gc.Suite(&containerSetupSuite{})
    55  
    56  func (s *containerSetupSuite) TestInitialiseContainersKVM(c *gc.C) {
    57  	s.testInitialiseContainers(c, instance.KVM)
    58  }
    59  
    60  func (s *containerSetupSuite) TestInitialiseContainersLXD(c *gc.C) {
    61  	s.testInitialiseContainers(c, instance.LXD)
    62  }
    63  
    64  func (s *containerSetupSuite) testInitialiseContainers(c *gc.C, containerType instance.ContainerType) {
    65  	defer s.patch(c).Finish()
    66  
    67  	s.expectContainerManagerConfig(containerType)
    68  	s.initialiser.EXPECT().Initialise().Return(nil)
    69  
    70  	s.PatchValue(
    71  		&factory.NewContainerManager,
    72  		func(forType instance.ContainerType, conf container.ManagerConfig) (container.Manager, error) {
    73  			return s.manager, nil
    74  		})
    75  
    76  	cs := s.setUpContainerSetup(c, containerType)
    77  	abort := make(chan struct{})
    78  	close(abort)
    79  	err := cs.initialiseContainers(abort)
    80  	c.Assert(err, jc.ErrorIsNil)
    81  }
    82  
    83  func (s *containerSetupSuite) TestInitialiseContainerProvisionerKVM(c *gc.C) {
    84  	s.testInitialiseContainers(c, instance.KVM)
    85  }
    86  
    87  func (s *containerSetupSuite) TestInitialiseContainerProvisonerLXD(c *gc.C) {
    88  	s.testInitialiseContainers(c, instance.LXD)
    89  }
    90  
    91  func (s *containerSetupSuite) TestContainerManagerConfigError(c *gc.C) {
    92  	defer s.patch(c).Finish()
    93  
    94  	s.facadeCaller.EXPECT().FacadeCall(
    95  		"ContainerManagerConfig", params.ContainerManagerConfigParams{Type: "lxd"}, gomock.Any()).Return(
    96  		errors.New("boom"))
    97  
    98  	cs := s.setUpContainerSetup(c, instance.LXD)
    99  	abort := make(chan struct{})
   100  	close(abort)
   101  	err := cs.initialiseContainers(abort)
   102  	c.Assert(err, gc.ErrorMatches, ".*generating container manager config: boom")
   103  }
   104  
   105  func (s *containerSetupSuite) setUpContainerSetup(c *gc.C, containerType instance.ContainerType) *ContainerSetup {
   106  	pState := apiprovisioner.NewStateFromFacade(s.facadeCaller)
   107  
   108  	cfg, err := agent.NewAgentConfig(
   109  		agent.AgentConfigParams{
   110  			Paths:             agent.DefaultPaths,
   111  			Tag:               s.machine.MachineTag(),
   112  			UpgradedToVersion: jujuversion.Current,
   113  			Password:          "password",
   114  			Nonce:             "nonce",
   115  			APIAddresses:      []string{"0.0.0.0:12345"},
   116  			CACert:            coretesting.CACert,
   117  			Controller:        names.NewControllerTag(s.controllerUUID.String()),
   118  			Model:             names.NewModelTag(s.modelUUID.String()),
   119  		})
   120  	c.Assert(err, jc.ErrorIsNil)
   121  
   122  	args := ContainerSetupParams{
   123  		Logger:        &noOpLogger{},
   124  		ContainerType: containerType,
   125  		MachineZone:   s.machine,
   126  		MTag:          s.machine.MachineTag(),
   127  		Provisioner:   pState,
   128  		Config:        cfg,
   129  		MachineLock:   s.machineLock,
   130  		CredentialAPI: &credentialAPIForTest{},
   131  		GetNetConfig: func(_ network.ConfigSource) (network.InterfaceInfos, error) {
   132  			return nil, nil
   133  		},
   134  	}
   135  
   136  	return NewContainerSetup(args)
   137  }
   138  
   139  func (s *containerSetupSuite) patch(c *gc.C) *gomock.Controller {
   140  	ctrl := gomock.NewController(c)
   141  
   142  	s.initialiser = testing.NewMockInitialiser(ctrl)
   143  	s.facadeCaller = apimocks.NewMockFacadeCaller(ctrl)
   144  	s.machine = provisionermocks.NewMockMachineProvisioner(ctrl)
   145  	s.manager = testing.NewMockManager(ctrl)
   146  
   147  	s.machine.EXPECT().MachineTag().Return(names.NewMachineTag("0")).AnyTimes()
   148  
   149  	s.PatchValue(GetContainerInitialiser, func(instance.ContainerType, map[string]string, string) container.Initialiser {
   150  		return s.initialiser
   151  	})
   152  
   153  	return ctrl
   154  }
   155  
   156  // expectContainerManagerConfig sets up expectations associated with
   157  // acquisition and decoration of container manager configuration.
   158  func (s *containerSetupSuite) expectContainerManagerConfig(cType instance.ContainerType) {
   159  	resultSource := params.ContainerManagerConfig{
   160  		ManagerConfig: map[string]string{"model-uuid": s.modelUUID.String()},
   161  	}
   162  	s.facadeCaller.EXPECT().FacadeCall(
   163  		"ContainerManagerConfig", params.ContainerManagerConfigParams{Type: cType}, gomock.Any(),
   164  	).SetArg(2, resultSource).MinTimes(1)
   165  }
   166  
   167  type credentialAPIForTest struct{}
   168  
   169  func (*credentialAPIForTest) InvalidateModelCredential(reason string) error {
   170  	return nil
   171  }
   172  
   173  type fakeMachineLock struct {
   174  	mu sync.Mutex
   175  }
   176  
   177  func (f *fakeMachineLock) Acquire(spec machinelock.Spec) (func(), error) {
   178  	f.mu.Lock()
   179  	return func() {
   180  		f.mu.Unlock()
   181  	}, nil
   182  }
   183  
   184  func (f *fakeMachineLock) Report(opts ...machinelock.ReportOption) (string, error) {
   185  	return "", nil
   186  }
   187  
   188  type noOpLogger struct {
   189  }
   190  
   191  func (noOpLogger) Errorf(format string, values ...interface{})   {}
   192  func (noOpLogger) Warningf(format string, values ...interface{}) {}
   193  func (noOpLogger) Infof(format string, values ...interface{})    {}
   194  func (noOpLogger) Debugf(format string, values ...interface{})   {}
   195  func (noOpLogger) Tracef(format string, values ...interface{})   {}
   196  func (noOpLogger) IsTraceEnabled() bool                          { return false }