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 }