github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/backups/files_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  //go:build !windows
     5  
     6  package backups_test
     7  
     8  import (
     9  	"os"
    10  	"path/filepath"
    11  	"sort"
    12  	"syscall"
    13  
    14  	"github.com/juju/collections/set"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/state/backups"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  var _ = gc.Suite(&filesSuite{})
    23  
    24  type filesSuite struct {
    25  	testing.BaseSuite
    26  	root string
    27  }
    28  
    29  func (s *filesSuite) SetUpTest(c *gc.C) {
    30  	s.BaseSuite.SetUpTest(c)
    31  
    32  	// Set the process' umask to 0 so tests that check permission bits don't
    33  	// fail due to the users umask being an unexpected value.
    34  	oldUmask := syscall.Umask(0)
    35  	s.AddCleanup(func(_ *gc.C) {
    36  		syscall.Umask(oldUmask)
    37  	})
    38  
    39  	s.root = c.MkDir()
    40  }
    41  
    42  func (s *filesSuite) TearDownTest(c *gc.C) {
    43  	s.BaseSuite.TearDownTest(c)
    44  }
    45  
    46  // createFiles preps the fake FS. The files are all created relative to
    47  // the given root.
    48  func (s *filesSuite) createFiles(c *gc.C, paths backups.Paths, root, machineID string, snapPaths bool) {
    49  	mkdir := func(path string) string {
    50  		dirname := filepath.Join(root, path)
    51  		os.MkdirAll(dirname, 0777)
    52  		return dirname
    53  	}
    54  	touch := func(dirname, name string) {
    55  		path := filepath.Join(dirname, name)
    56  		file, err := os.Create(path)
    57  		c.Assert(err, jc.ErrorIsNil)
    58  		file.Close()
    59  	}
    60  
    61  	dirname := mkdir(paths.DataDir)
    62  	touch(dirname, "system-identity")
    63  	touch(dirname, "nonce.txt")
    64  	touch(dirname, "server.pem")
    65  	if snapPaths {
    66  		snapDirname := mkdir("/var/snap/juju-db/common")
    67  		touch(snapDirname, "shared-secret")
    68  	} else {
    69  		touch(dirname, "shared-secret")
    70  	}
    71  	mkdir(filepath.Join(paths.DataDir, "tools"))
    72  
    73  	dirname = mkdir(filepath.Join(paths.DataDir, "agents"))
    74  	touch(dirname, "machine-"+machineID+".conf")
    75  
    76  	dirname = mkdir("/home/ubuntu/.ssh")
    77  	touch(dirname, "authorized_keys")
    78  
    79  	dirname = mkdir(filepath.Join(paths.DataDir, "init", "juju-db"))
    80  	touch(dirname, "juju-db.service")
    81  }
    82  
    83  func (s *filesSuite) checkSameStrings(c *gc.C, actual, expected []string) {
    84  	sActual := set.NewStrings(actual...)
    85  	sExpected := set.NewStrings(expected...)
    86  
    87  	sActualOnly := sActual.Difference(sExpected)
    88  	sExpectedOnly := sExpected.Difference(sActual)
    89  
    90  	if !sActualOnly.IsEmpty() || !sExpectedOnly.IsEmpty() {
    91  		c.Error("strings mismatch")
    92  		onlyActual := sActualOnly.Values()
    93  		onlyExpected := sExpectedOnly.Values()
    94  		sort.Strings(onlyActual)
    95  		sort.Strings(onlyExpected)
    96  
    97  		if !sActualOnly.IsEmpty() {
    98  			c.Log("...unexpected values:")
    99  			for _, str := range onlyActual {
   100  				c.Log(" " + str)
   101  			}
   102  		}
   103  		if !sExpectedOnly.IsEmpty() {
   104  			c.Log("...missing values:")
   105  			for _, str := range onlyExpected {
   106  				c.Log(" " + str)
   107  			}
   108  		}
   109  	}
   110  }
   111  
   112  func (s *filesSuite) TestGetFilesToBackUp(c *gc.C) {
   113  	paths := backups.Paths{
   114  		DataDir: "/var/lib/juju",
   115  		LogsDir: "/var/log/juju",
   116  	}
   117  	s.createFiles(c, paths, s.root, "0", false)
   118  	s.createFiles(c, paths, s.root, "1", false)
   119  
   120  	files, err := backups.GetFilesToBackUp(s.root, &paths)
   121  	c.Assert(err, jc.ErrorIsNil)
   122  
   123  	expected := []string{
   124  		filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"),
   125  		filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"),
   126  		filepath.Join(s.root, "/var/lib/juju/agents/machine-1.conf"),
   127  		filepath.Join(s.root, "/var/lib/juju/nonce.txt"),
   128  		filepath.Join(s.root, "/var/lib/juju/server.pem"),
   129  		filepath.Join(s.root, "/var/lib/juju/shared-secret"),
   130  		filepath.Join(s.root, "/var/lib/juju/system-identity"),
   131  		filepath.Join(s.root, "/var/lib/juju/tools"),
   132  		filepath.Join(s.root, "/var/lib/juju/init/juju-db"),
   133  	}
   134  	c.Check(files, jc.SameContents, expected)
   135  	s.checkSameStrings(c, files, expected)
   136  }
   137  
   138  func (s *filesSuite) TestGetFilesToBackUpMissing(c *gc.C) {
   139  	paths := backups.Paths{
   140  		DataDir: "/var/lib/juju",
   141  		LogsDir: "/var/log/juju",
   142  	}
   143  	s.createFiles(c, paths, s.root, "0", false)
   144  
   145  	missing := []string{
   146  		"/var/lib/juju/nonce.txt",
   147  		"/home/ubuntu/.ssh/authorized_keys",
   148  	}
   149  	for _, filename := range missing {
   150  		err := os.Remove(filepath.Join(s.root, filename))
   151  		c.Assert(err, jc.ErrorIsNil)
   152  	}
   153  
   154  	files, err := backups.GetFilesToBackUp(s.root, &paths)
   155  	c.Assert(err, jc.ErrorIsNil)
   156  
   157  	expected := []string{
   158  		filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"),
   159  		filepath.Join(s.root, "/var/lib/juju/server.pem"),
   160  		filepath.Join(s.root, "/var/lib/juju/shared-secret"),
   161  		filepath.Join(s.root, "/var/lib/juju/system-identity"),
   162  		filepath.Join(s.root, "/var/lib/juju/tools"),
   163  		filepath.Join(s.root, "/var/lib/juju/init/juju-db"),
   164  	}
   165  	// This got re-created.
   166  	expected = append(expected, filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"))
   167  	c.Check(files, jc.SameContents, expected)
   168  	s.checkSameStrings(c, files, expected)
   169  }
   170  
   171  func (s *filesSuite) TestGetFilesToBackUpSnap(c *gc.C) {
   172  	paths := backups.Paths{
   173  		DataDir: "/var/lib/juju",
   174  		LogsDir: "/var/log/juju",
   175  	}
   176  	s.createFiles(c, paths, s.root, "0", true)
   177  
   178  	files, err := backups.GetFilesToBackUp(s.root, &paths)
   179  	c.Assert(err, jc.ErrorIsNil)
   180  
   181  	expected := []string{
   182  		filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"),
   183  		filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"),
   184  		filepath.Join(s.root, "/var/lib/juju/nonce.txt"),
   185  		filepath.Join(s.root, "/var/lib/juju/server.pem"),
   186  		filepath.Join(s.root, "/var/snap/juju-db/common/shared-secret"),
   187  		filepath.Join(s.root, "/var/lib/juju/system-identity"),
   188  		filepath.Join(s.root, "/var/lib/juju/tools"),
   189  		filepath.Join(s.root, "/var/lib/juju/init/juju-db"),
   190  	}
   191  	c.Check(files, jc.SameContents, expected)
   192  	s.checkSameStrings(c, files, expected)
   193  }