mirror of
https://github.com/token2/snapd.git
synced 2026-03-13 11:15:47 -07:00
introduce sysconfig.Device (similar to boot.Device) have sysconfig.ApplyFilesystemOnlyDefaults and sysconfig.ConfigureTargetSystem take the model and pass down a sysconfig.Device for these two we assume that mode is not run
600 lines
18 KiB
Go
600 lines
18 KiB
Go
// -*- Mode: Go; indent-tabs-mode: t -*-
|
|
|
|
/*
|
|
* Copyright (C) 2020 Canonical Ltd
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
package sysconfig_test
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
. "gopkg.in/check.v1"
|
|
|
|
"github.com/snapcore/snapd/boot"
|
|
"github.com/snapcore/snapd/dirs"
|
|
"github.com/snapcore/snapd/sysconfig"
|
|
"github.com/snapcore/snapd/testutil"
|
|
)
|
|
|
|
// Hook up check.v1 into the "go test" runner
|
|
func Test(t *testing.T) { TestingT(t) }
|
|
|
|
type sysconfigSuite struct {
|
|
testutil.BaseTest
|
|
|
|
tmpdir string
|
|
}
|
|
|
|
var _ = Suite(&sysconfigSuite{})
|
|
|
|
func (s *sysconfigSuite) SetUpTest(c *C) {
|
|
s.BaseTest.SetUpTest(c)
|
|
|
|
s.tmpdir = c.MkDir()
|
|
dirs.SetRootDir(s.tmpdir)
|
|
s.AddCleanup(func() { dirs.SetRootDir("/") })
|
|
}
|
|
|
|
func (s *sysconfigSuite) makeCloudCfgSrcDirFiles(c *C) string {
|
|
cloudCfgSrcDir := c.MkDir()
|
|
for _, mockCfg := range []string{"foo.cfg", "bar.cfg"} {
|
|
err := ioutil.WriteFile(filepath.Join(cloudCfgSrcDir, mockCfg), []byte(fmt.Sprintf("%s config", mockCfg)), 0644)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
return cloudCfgSrcDir
|
|
}
|
|
|
|
func (s *sysconfigSuite) makeGadgetCloudConfFile(c *C) string {
|
|
gadgetDir := c.MkDir()
|
|
gadgetCloudConf := filepath.Join(gadgetDir, "cloud.conf")
|
|
err := ioutil.WriteFile(gadgetCloudConf, []byte("gadget cloud config"), 0644)
|
|
c.Assert(err, IsNil)
|
|
|
|
return gadgetDir
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestHasGadgetCloudConf(c *C) {
|
|
// no cloud.conf is false
|
|
c.Assert(sysconfig.HasGadgetCloudConf("non-existent-dir-place"), Equals, false)
|
|
|
|
// the dir is not enough
|
|
gadgetDir := c.MkDir()
|
|
c.Assert(sysconfig.HasGadgetCloudConf(gadgetDir), Equals, false)
|
|
|
|
// creating one now is true
|
|
gadgetCloudConf := filepath.Join(gadgetDir, "cloud.conf")
|
|
err := ioutil.WriteFile(gadgetCloudConf, []byte("gadget cloud config"), 0644)
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Assert(sysconfig.HasGadgetCloudConf(gadgetDir), Equals, true)
|
|
}
|
|
|
|
// this test is for initramfs calls that disable cloud-init for the ephemeral
|
|
// writable partition that is used while running during install or recover mode
|
|
func (s *sysconfigSuite) TestEphemeralModeInitramfsCloudInitDisables(c *C) {
|
|
writableDefaultsDir := sysconfig.WritableDefaultsDir(boot.InitramfsWritableDir)
|
|
err := sysconfig.DisableCloudInit(writableDefaultsDir)
|
|
c.Assert(err, IsNil)
|
|
|
|
ubuntuDataCloudDisabled := filepath.Join(boot.InitramfsWritableDir, "_writable_defaults/etc/cloud/cloud-init.disabled")
|
|
c.Check(ubuntuDataCloudDisabled, testutil.FilePresent)
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitDisablesByDefaultRunMode(c *C) {
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
ubuntuDataCloudDisabled := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud-init.disabled")
|
|
c.Check(ubuntuDataCloudDisabled, testutil.FilePresent)
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitDisallowedIgnoresOtherOptions(c *C) {
|
|
cloudCfgSrcDir := s.makeCloudCfgSrcDirFiles(c)
|
|
gadgetDir := s.makeGadgetCloudConfFile(c)
|
|
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
AllowCloudInit: false,
|
|
CloudInitSrcDir: cloudCfgSrcDir,
|
|
GadgetDir: gadgetDir,
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
ubuntuDataCloudDisabled := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud-init.disabled")
|
|
c.Check(ubuntuDataCloudDisabled, testutil.FilePresent)
|
|
|
|
// did not copy ubuntu-seed src files
|
|
ubuntuDataCloudCfg := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud.cfg.d/")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "foo.cfg"), testutil.FileAbsent)
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "bar.cfg"), testutil.FileAbsent)
|
|
|
|
// also did not copy gadget cloud.conf
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "80_device_gadget.cfg"), testutil.FileAbsent)
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitAllowedDoesNotDisable(c *C) {
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
AllowCloudInit: true,
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
ubuntuDataCloudDisabled := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud-init.disabled")
|
|
c.Check(ubuntuDataCloudDisabled, testutil.FileAbsent)
|
|
}
|
|
|
|
// this test is the same as the logic from install mode devicestate, where we
|
|
// want to install cloud-init configuration not onto the running, ephemeral
|
|
// writable, but rather the host writable partition that will be used upon
|
|
// reboot into run mode
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitInstallsOntoHostRunMode(c *C) {
|
|
cloudCfgSrcDir := s.makeCloudCfgSrcDirFiles(c)
|
|
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
AllowCloudInit: true,
|
|
CloudInitSrcDir: cloudCfgSrcDir,
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
// and did copy the cloud-init files
|
|
ubuntuDataCloudCfg := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud.cfg.d/")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "90_foo.cfg"), testutil.FileEquals, "foo.cfg config")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "90_bar.cfg"), testutil.FileEquals, "bar.cfg config")
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitInstallsOntoHostRunModeWithGadgetCloudConf(c *C) {
|
|
gadgetDir := s.makeGadgetCloudConfFile(c)
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
AllowCloudInit: true,
|
|
GadgetDir: gadgetDir,
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
// and did copy the gadget cloud-init file
|
|
ubuntuDataCloudCfg := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud.cfg.d/")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "80_device_gadget.cfg"), testutil.FileEquals, "gadget cloud config")
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestInstallModeCloudInitInstallsOntoHostRunModeWithGadgetCloudConfAlsoInstallsUbuntuSeedConfig(c *C) {
|
|
cloudCfgSrcDir := s.makeCloudCfgSrcDirFiles(c)
|
|
gadgetDir := s.makeGadgetCloudConfFile(c)
|
|
|
|
err := sysconfig.ConfigureTargetSystem(nil, &sysconfig.Options{
|
|
AllowCloudInit: true,
|
|
CloudInitSrcDir: cloudCfgSrcDir,
|
|
GadgetDir: gadgetDir,
|
|
TargetRootDir: boot.InstallHostWritableDir,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
|
|
// we did copy the gadget cloud-init file
|
|
ubuntuDataCloudCfg := filepath.Join(boot.InstallHostWritableDir, "_writable_defaults/etc/cloud/cloud.cfg.d/")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "80_device_gadget.cfg"), testutil.FileEquals, "gadget cloud config")
|
|
|
|
// and we also copied the ubuntu-seed files with a new prefix such that they
|
|
// take precedence over the gadget file by being ordered lexically after the
|
|
// gadget file
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "90_foo.cfg"), testutil.FileEquals, "foo.cfg config")
|
|
c.Check(filepath.Join(ubuntuDataCloudCfg, "90_bar.cfg"), testutil.FileEquals, "bar.cfg config")
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestCloudInitStatusUnhappy(c *C) {
|
|
cmd := testutil.MockCommand(c, "cloud-init", `
|
|
echo cloud-init borken
|
|
exit 1
|
|
`)
|
|
|
|
status, err := sysconfig.CloudInitStatus()
|
|
c.Assert(err, ErrorMatches, "cloud-init borken")
|
|
c.Assert(status, Equals, sysconfig.CloudInitErrored)
|
|
c.Assert(cmd.Calls(), DeepEquals, [][]string{
|
|
{"cloud-init", "status"},
|
|
})
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestCloudInitStatus(c *C) {
|
|
tt := []struct {
|
|
comment string
|
|
cloudInitOutput string
|
|
exp sysconfig.CloudInitState
|
|
restrictedFile bool
|
|
disabledFile bool
|
|
expError string
|
|
}{
|
|
{
|
|
comment: "done",
|
|
cloudInitOutput: "status: done",
|
|
exp: sysconfig.CloudInitDone,
|
|
},
|
|
{
|
|
comment: "running",
|
|
cloudInitOutput: "status: running",
|
|
exp: sysconfig.CloudInitEnabled,
|
|
},
|
|
{
|
|
comment: "not run",
|
|
cloudInitOutput: "status: not run",
|
|
exp: sysconfig.CloudInitEnabled,
|
|
},
|
|
{
|
|
comment: "new unrecognized state",
|
|
cloudInitOutput: "status: newfangledstatus",
|
|
exp: sysconfig.CloudInitEnabled,
|
|
},
|
|
{
|
|
comment: "restricted by snapd",
|
|
restrictedFile: true,
|
|
exp: sysconfig.CloudInitRestrictedBySnapd,
|
|
},
|
|
{
|
|
comment: "disabled temporarily",
|
|
cloudInitOutput: "status: disabled",
|
|
exp: sysconfig.CloudInitUntriggered,
|
|
},
|
|
{
|
|
comment: "disabled permanently via file",
|
|
disabledFile: true,
|
|
exp: sysconfig.CloudInitDisabledPermanently,
|
|
},
|
|
{
|
|
comment: "errored",
|
|
cloudInitOutput: "status: error",
|
|
exp: sysconfig.CloudInitErrored,
|
|
},
|
|
{
|
|
comment: "broken cloud-init output",
|
|
cloudInitOutput: "broken cloud-init output",
|
|
expError: "invalid cloud-init output: broken cloud-init output",
|
|
},
|
|
}
|
|
|
|
for _, t := range tt {
|
|
old := dirs.GlobalRootDir
|
|
dirs.SetRootDir(c.MkDir())
|
|
defer func() { dirs.SetRootDir(old) }()
|
|
cmd := testutil.MockCommand(c, "cloud-init", fmt.Sprintf(`
|
|
if [ "$1" = "status" ]; then
|
|
echo '%s'
|
|
else
|
|
echo "unexpected args, $"
|
|
exit 1
|
|
fi
|
|
`, t.cloudInitOutput))
|
|
|
|
if t.disabledFile {
|
|
cloudDir := filepath.Join(dirs.GlobalRootDir, "etc/cloud")
|
|
err := os.MkdirAll(cloudDir, 0755)
|
|
c.Assert(err, IsNil)
|
|
err = ioutil.WriteFile(filepath.Join(cloudDir, "cloud-init.disabled"), nil, 0644)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
if t.restrictedFile {
|
|
cloudDir := filepath.Join(dirs.GlobalRootDir, "etc/cloud/cloud.cfg.d")
|
|
err := os.MkdirAll(cloudDir, 0755)
|
|
c.Assert(err, IsNil)
|
|
err = ioutil.WriteFile(filepath.Join(cloudDir, "zzzz_snapd.cfg"), nil, 0644)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
status, err := sysconfig.CloudInitStatus()
|
|
if t.expError != "" {
|
|
c.Assert(err, ErrorMatches, t.expError, Commentf(t.comment))
|
|
} else {
|
|
c.Assert(err, IsNil)
|
|
c.Assert(status, Equals, t.exp, Commentf(t.comment))
|
|
}
|
|
|
|
// if the restricted file was there we don't call cloud-init status
|
|
var expCalls [][]string
|
|
if !t.restrictedFile && !t.disabledFile {
|
|
expCalls = [][]string{
|
|
{"cloud-init", "status"},
|
|
}
|
|
}
|
|
|
|
c.Assert(cmd.Calls(), DeepEquals, expCalls, Commentf(t.comment))
|
|
cmd.Restore()
|
|
}
|
|
}
|
|
|
|
func (s *sysconfigSuite) TestCloudInitNotFoundStatus(c *C) {
|
|
emptyDir := c.MkDir()
|
|
oldPath := os.Getenv("PATH")
|
|
defer func() {
|
|
c.Assert(os.Setenv("PATH", oldPath), IsNil)
|
|
}()
|
|
os.Setenv("PATH", emptyDir)
|
|
|
|
status, err := sysconfig.CloudInitStatus()
|
|
c.Assert(err, IsNil)
|
|
c.Check(status, Equals, sysconfig.CloudInitNotFound)
|
|
}
|
|
|
|
var gceCloudInitStatusJSON = `{
|
|
"v1": {
|
|
"datasource": "DataSourceGCE",
|
|
"init": {
|
|
"errors": [],
|
|
"finished": 1591751113.4536479,
|
|
"start": 1591751112.130069
|
|
},
|
|
"stage": null
|
|
}
|
|
}
|
|
`
|
|
|
|
var multipassNoCloudCloudInitStatusJSON = `{
|
|
"v1": {
|
|
"datasource": "DataSourceNoCloud [seed=/dev/sr0][dsmode=net]",
|
|
"init": {
|
|
"errors": [],
|
|
"finished": 1591788514.4656117,
|
|
"start": 1591788514.2607572
|
|
},
|
|
"stage": null
|
|
}
|
|
}`
|
|
|
|
var localNoneCloudInitStatusJSON = `{
|
|
"v1": {
|
|
"datasource": "DataSourceNone",
|
|
"init": {
|
|
"errors": [],
|
|
"finished": 1591788514.4656117,
|
|
"start": 1591788514.2607572
|
|
},
|
|
"stage": null
|
|
}
|
|
}`
|
|
|
|
var lxdNoCloudCloudInitStatusJSON = `{
|
|
"v1": {
|
|
"datasource": "DataSourceNoCloud [seed=/var/lib/cloud/seed/nocloud-net][dsmode=net]",
|
|
"init": {
|
|
"errors": [],
|
|
"finished": 1591788737.3982718,
|
|
"start": 1591788736.9015596
|
|
},
|
|
"stage": null
|
|
}
|
|
}`
|
|
|
|
var restrictNoCloudYaml = `datasource_list: [NoCloud]
|
|
datasource:
|
|
NoCloud:
|
|
fs_label: null
|
|
manual_cache_clean: true
|
|
`
|
|
|
|
func (s *sysconfigSuite) TestRestrictCloudInit(c *C) {
|
|
tt := []struct {
|
|
comment string
|
|
state sysconfig.CloudInitState
|
|
sysconfOpts *sysconfig.CloudInitRestrictOptions
|
|
cloudInitStatusJSON string
|
|
expError string
|
|
expRestrictYamlWritten string
|
|
expDatasource string
|
|
expAction string
|
|
expDisableFile bool
|
|
}{
|
|
{
|
|
comment: "already disabled",
|
|
state: sysconfig.CloudInitDisabledPermanently,
|
|
expError: "cannot restrict cloud-init: already disabled",
|
|
},
|
|
{
|
|
comment: "already restricted",
|
|
state: sysconfig.CloudInitRestrictedBySnapd,
|
|
expError: "cannot restrict cloud-init: already restricted",
|
|
},
|
|
{
|
|
comment: "errored",
|
|
state: sysconfig.CloudInitErrored,
|
|
expError: "cannot restrict cloud-init in error or enabled state",
|
|
},
|
|
{
|
|
comment: "enable (not running)",
|
|
state: sysconfig.CloudInitEnabled,
|
|
expError: "cannot restrict cloud-init in error or enabled state",
|
|
},
|
|
{
|
|
comment: "errored w/ force disable",
|
|
state: sysconfig.CloudInitErrored,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
ForceDisable: true,
|
|
},
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "enable (not running) w/ force disable",
|
|
state: sysconfig.CloudInitEnabled,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
ForceDisable: true,
|
|
},
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "untriggered",
|
|
state: sysconfig.CloudInitUntriggered,
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "unknown status",
|
|
state: -1,
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "gce done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: gceCloudInitStatusJSON,
|
|
expDatasource: "GCE",
|
|
expAction: "restrict",
|
|
expRestrictYamlWritten: `datasource_list: [GCE]
|
|
`,
|
|
},
|
|
{
|
|
comment: "nocloud done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: multipassNoCloudCloudInitStatusJSON,
|
|
expDatasource: "NoCloud",
|
|
expAction: "restrict",
|
|
expRestrictYamlWritten: restrictNoCloudYaml,
|
|
},
|
|
{
|
|
comment: "nocloud uc20 done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: multipassNoCloudCloudInitStatusJSON,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
DisableAfterLocalDatasourcesRun: true,
|
|
},
|
|
expDatasource: "NoCloud",
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "none uc20 done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: localNoneCloudInitStatusJSON,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
DisableAfterLocalDatasourcesRun: true,
|
|
},
|
|
expDatasource: "None",
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
|
|
// the two cases for lxd and multipass are effectively the same, but as
|
|
// the largest known users of cloud-init w/ UC, we leave them as
|
|
// separate test cases for their different cloud-init status.json
|
|
// content
|
|
{
|
|
comment: "nocloud multipass done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: multipassNoCloudCloudInitStatusJSON,
|
|
expDatasource: "NoCloud",
|
|
expAction: "restrict",
|
|
expRestrictYamlWritten: restrictNoCloudYaml,
|
|
},
|
|
{
|
|
comment: "nocloud seed lxd done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: lxdNoCloudCloudInitStatusJSON,
|
|
expDatasource: "NoCloud",
|
|
expAction: "restrict",
|
|
expRestrictYamlWritten: restrictNoCloudYaml,
|
|
},
|
|
{
|
|
comment: "nocloud uc20 multipass done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: multipassNoCloudCloudInitStatusJSON,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
DisableAfterLocalDatasourcesRun: true,
|
|
},
|
|
expDatasource: "NoCloud",
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "nocloud uc20 seed lxd done",
|
|
state: sysconfig.CloudInitDone,
|
|
cloudInitStatusJSON: lxdNoCloudCloudInitStatusJSON,
|
|
sysconfOpts: &sysconfig.CloudInitRestrictOptions{
|
|
DisableAfterLocalDatasourcesRun: true,
|
|
},
|
|
expDatasource: "NoCloud",
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
{
|
|
comment: "no cloud-init in $PATH",
|
|
state: sysconfig.CloudInitNotFound,
|
|
expAction: "disable",
|
|
expDisableFile: true,
|
|
},
|
|
}
|
|
|
|
for _, t := range tt {
|
|
comment := Commentf("%s", t.comment)
|
|
// setup status.json
|
|
old := dirs.GlobalRootDir
|
|
dirs.SetRootDir(c.MkDir())
|
|
defer func() { dirs.SetRootDir(old) }()
|
|
statusJSONFile := filepath.Join(dirs.GlobalRootDir, "/run/cloud-init/status.json")
|
|
if t.cloudInitStatusJSON != "" {
|
|
err := os.MkdirAll(filepath.Dir(statusJSONFile), 0755)
|
|
c.Assert(err, IsNil, comment)
|
|
err = ioutil.WriteFile(statusJSONFile, []byte(t.cloudInitStatusJSON), 0644)
|
|
c.Assert(err, IsNil, comment)
|
|
}
|
|
|
|
// if we expect snapd to write a yaml config file for cloud-init, ensure
|
|
// the dir exists before hand
|
|
if t.expRestrictYamlWritten != "" {
|
|
err := os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "/etc/cloud/cloud.cfg.d"), 0755)
|
|
c.Assert(err, IsNil, comment)
|
|
}
|
|
|
|
res, err := sysconfig.RestrictCloudInit(t.state, t.sysconfOpts)
|
|
if t.expError == "" {
|
|
c.Assert(err, IsNil, comment)
|
|
c.Assert(res.DataSource, Equals, t.expDatasource, comment)
|
|
c.Assert(res.Action, Equals, t.expAction, comment)
|
|
if t.expRestrictYamlWritten != "" {
|
|
// check the snapd restrict yaml file that should have been written
|
|
c.Assert(
|
|
filepath.Join(dirs.GlobalRootDir, "/etc/cloud/cloud.cfg.d/zzzz_snapd.cfg"),
|
|
testutil.FileEquals,
|
|
t.expRestrictYamlWritten,
|
|
comment,
|
|
)
|
|
}
|
|
|
|
// if we expect the disable file to be written then check for it
|
|
// otherwise ensure it was not written accidentally
|
|
var fileCheck Checker
|
|
if t.expDisableFile {
|
|
fileCheck = testutil.FilePresent
|
|
} else {
|
|
fileCheck = testutil.FileAbsent
|
|
}
|
|
|
|
c.Assert(
|
|
filepath.Join(dirs.GlobalRootDir, "/etc/cloud/cloud-init.disabled"),
|
|
fileCheck,
|
|
comment,
|
|
)
|
|
|
|
} else {
|
|
c.Assert(err, ErrorMatches, t.expError, comment)
|
|
}
|
|
}
|
|
}
|