github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/container/kvm/live_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package kvm_test
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"os/exec"
    11  	"runtime"
    12  
    13  	"github.com/juju/loggo"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/version/v2"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/cloudconfig/instancecfg"
    19  	"github.com/juju/juju/container"
    20  	"github.com/juju/juju/container/kvm"
    21  	"github.com/juju/juju/core/arch"
    22  	corebase "github.com/juju/juju/core/base"
    23  	"github.com/juju/juju/core/constraints"
    24  	"github.com/juju/juju/core/network"
    25  	"github.com/juju/juju/core/status"
    26  	"github.com/juju/juju/environs/config"
    27  	"github.com/juju/juju/environs/imagemetadata"
    28  	"github.com/juju/juju/environs/instances"
    29  	jujutesting "github.com/juju/juju/juju/testing"
    30  	coretesting "github.com/juju/juju/testing"
    31  	"github.com/juju/juju/tools"
    32  	jujuversion "github.com/juju/juju/version"
    33  )
    34  
    35  type LiveSuite struct {
    36  	coretesting.BaseSuite
    37  	ContainerDir string
    38  	RemovedDir   string
    39  }
    40  
    41  var _ = gc.Suite(&LiveSuite{})
    42  
    43  func (s *LiveSuite) SetUpTest(c *gc.C) {
    44  	s.BaseSuite.SetUpTest(c)
    45  	// Skip if not linux
    46  	if runtime.GOOS != "linux" {
    47  		c.Skip("not running linux")
    48  	}
    49  	// Skip if virsh is not installed.
    50  	if _, err := exec.LookPath("virsh"); err != nil {
    51  		c.Skip("virsh not found")
    52  	}
    53  	// Skip if not running as root.
    54  	if os.Getuid() != 0 {
    55  		c.Skip("not running as root")
    56  	}
    57  	s.ContainerDir = c.MkDir()
    58  	s.PatchValue(&container.ContainerDir, s.ContainerDir)
    59  	s.RemovedDir = c.MkDir()
    60  	s.PatchValue(&container.RemovedContainerDir, s.RemovedDir)
    61  	loggo.GetLogger("juju.container").SetLogLevel(loggo.TRACE)
    62  }
    63  
    64  func (s *LiveSuite) newManager(c *gc.C, name string) container.Manager {
    65  	manager, err := kvm.NewContainerManager(
    66  		container.ManagerConfig{
    67  			container.ConfigModelUUID: coretesting.ModelTag.Id(),
    68  			container.ConfigLogDir:    c.MkDir(),
    69  		})
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	return manager
    72  }
    73  
    74  func assertNumberOfContainers(c *gc.C, manager container.Manager, count int) {
    75  	containers, err := manager.ListContainers()
    76  	c.Assert(err, jc.ErrorIsNil)
    77  	c.Assert(containers, gc.HasLen, count)
    78  }
    79  
    80  func (s *LiveSuite) TestNoInitialContainers(c *gc.C) {
    81  	manager := s.newManager(c, "test")
    82  	assertNumberOfContainers(c, manager, 0)
    83  }
    84  
    85  func shutdownMachines(manager container.Manager) func(*gc.C) {
    86  	return func(c *gc.C) {
    87  		instances, err := manager.ListContainers()
    88  		c.Assert(err, jc.ErrorIsNil)
    89  		for _, instance := range instances {
    90  			err := manager.DestroyContainer(instance.Id())
    91  			c.Check(err, jc.ErrorIsNil)
    92  		}
    93  	}
    94  }
    95  
    96  func createContainer(c *gc.C, manager container.Manager, machineId string) instances.Instance {
    97  	machineNonce := "fake-nonce"
    98  	apiInfo := jujutesting.FakeAPIInfo(machineId)
    99  	instanceConfig, err := instancecfg.NewInstanceConfig(coretesting.ControllerTag, machineId, machineNonce,
   100  		imagemetadata.ReleasedStream, corebase.MakeDefaultBase("ubuntu", "22.04"), apiInfo)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  
   103  	nics := network.InterfaceInfos{{
   104  		InterfaceName: "eth0",
   105  		InterfaceType: network.EthernetDevice,
   106  		ConfigType:    network.ConfigDHCP,
   107  	}}
   108  	net := container.BridgeNetworkConfig(0, nics)
   109  
   110  	err = instanceConfig.SetTools(tools.List{
   111  		&tools.Tools{
   112  			Version: version.MustParseBinary("2.3.4-foo-bar"),
   113  			URL:     "http://tools.testing.invalid/2.3.4-foo-bar.tgz",
   114  		},
   115  	})
   116  	c.Assert(err, jc.ErrorIsNil)
   117  	environConfig := dummyConfig(c)
   118  	err = instancecfg.FinishInstanceConfig(instanceConfig, environConfig)
   119  	c.Assert(err, jc.ErrorIsNil)
   120  	callback := func(settableStatus status.Status, info string, data map[string]interface{}) error { return nil }
   121  	inst, hardware, err := manager.CreateContainer(context.Background(), instanceConfig, constraints.Value{}, corebase.MakeDefaultBase("ubuntu", "12.04"), net, nil, callback)
   122  	c.Assert(err, jc.ErrorIsNil)
   123  	c.Assert(hardware, gc.NotNil)
   124  	expected := fmt.Sprintf("arch=%s cores=1 mem=512M root-disk=8192M", arch.HostArch())
   125  	c.Assert(hardware.String(), gc.Equals, expected)
   126  	return inst
   127  }
   128  
   129  func (s *LiveSuite) TestShutdownMachines(c *gc.C) {
   130  	manager := s.newManager(c, "test")
   131  	createContainer(c, manager, "1/kvm/0")
   132  	createContainer(c, manager, "1/kvm/1")
   133  	assertNumberOfContainers(c, manager, 2)
   134  
   135  	shutdownMachines(manager)(c)
   136  	assertNumberOfContainers(c, manager, 0)
   137  }
   138  
   139  func (s *LiveSuite) TestManagerIsolation(c *gc.C) {
   140  	firstManager := s.newManager(c, "first")
   141  	s.AddCleanup(shutdownMachines(firstManager))
   142  
   143  	createContainer(c, firstManager, "1/kvm/0")
   144  	createContainer(c, firstManager, "1/kvm/1")
   145  
   146  	secondManager := s.newManager(c, "second")
   147  	s.AddCleanup(shutdownMachines(secondManager))
   148  
   149  	createContainer(c, secondManager, "1/kvm/0")
   150  
   151  	assertNumberOfContainers(c, firstManager, 2)
   152  	assertNumberOfContainers(c, secondManager, 1)
   153  }
   154  
   155  func dummyConfig(c *gc.C) *config.Config {
   156  	testConfig, err := config.New(config.UseDefaults, coretesting.FakeConfig())
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	testConfig, err = testConfig.Apply(map[string]interface{}{
   159  		"type":          "dummy",
   160  		"controller":    false,
   161  		"agent-version": jujuversion.Current.String(),
   162  	})
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	return testConfig
   165  }