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

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package backups
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/juju/errors"
    11  
    12  	"github.com/juju/juju/mongo"
    13  )
    14  
    15  // TODO(ericsnow) lp-1392876
    16  // Pull these from authoritative sources (see
    17  // github.com/juju/juju/juju/paths, etc.):
    18  const (
    19  	sshDir = "/home/ubuntu/.ssh"
    20  
    21  	agentsDir   = "agents"
    22  	agentsConfs = "machine-*"
    23  	toolsDir    = "tools"
    24  	initDir     = "init"
    25  
    26  	sshIdentFile = "system-identity"
    27  	nonceFile    = "nonce.txt"
    28  	authKeysFile = "authorized_keys"
    29  
    30  	dbPEM           = mongo.FileNameDBSSLKey
    31  	dbSecret        = "shared-secret"
    32  	dbSecretSnapDir = "/var/snap/juju-db/common"
    33  )
    34  
    35  // BackupDirToUse returns the desired backup staging dir.
    36  func BackupDirToUse(configuredDir string) string {
    37  	if configuredDir != "" {
    38  		return configuredDir
    39  	}
    40  	return os.TempDir()
    41  }
    42  
    43  // Paths holds the paths that backups needs.
    44  type Paths struct {
    45  	BackupDir string
    46  	DataDir   string
    47  	LogsDir   string
    48  }
    49  
    50  // DiskUsage instances are used to find disk usage for a path.
    51  type DiskUsage interface {
    52  	Available(path string) uint64
    53  }
    54  
    55  // GetFilesToBackUp returns the paths that should be included in the
    56  // backup archive.
    57  func GetFilesToBackUp(rootDir string, paths *Paths) ([]string, error) {
    58  	var glob string
    59  
    60  	glob = filepath.Join(rootDir, paths.DataDir, agentsDir, agentsConfs)
    61  	agentConfs, err := filepath.Glob(glob)
    62  	if err != nil {
    63  		return nil, errors.Annotate(err, "failed to fetch agent config files")
    64  	}
    65  
    66  	glob = filepath.Join(rootDir, paths.DataDir, initDir, "*")
    67  	serviceConfs, err := filepath.Glob(glob)
    68  	if err != nil {
    69  		return nil, errors.Annotate(err, "failed to fetch service config files")
    70  	}
    71  
    72  	backupFiles := []string{
    73  		filepath.Join(rootDir, paths.DataDir, toolsDir),
    74  		filepath.Join(rootDir, paths.DataDir, sshIdentFile),
    75  		filepath.Join(rootDir, paths.DataDir, dbPEM),
    76  	}
    77  
    78  	// Handle shared-secret (may be in /var/lib/juju or /var/snap/juju-db/common).
    79  	secret := filepath.Join(rootDir, paths.DataDir, dbSecret)
    80  	if _, err := os.Stat(secret); err != nil {
    81  		if !os.IsNotExist(err) {
    82  			return nil, errors.Trace(err)
    83  		}
    84  		secretSnap := filepath.Join(rootDir, dbSecretSnapDir, dbSecret)
    85  		logger.Tracef("shared-secret not found at %q, trying %q", secret, secretSnap)
    86  		if _, err := os.Stat(secretSnap); err != nil {
    87  			return nil, errors.Trace(err)
    88  		}
    89  		secret = secretSnap
    90  	}
    91  	backupFiles = append(backupFiles, secret)
    92  
    93  	backupFiles = append(backupFiles, agentConfs...)
    94  	backupFiles = append(backupFiles, serviceConfs...)
    95  
    96  	// Handle nonce.txt (might not exist).
    97  	nonce := filepath.Join(rootDir, paths.DataDir, nonceFile)
    98  	if _, err := os.Stat(nonce); err != nil {
    99  		if !os.IsNotExist(err) {
   100  			return nil, errors.Trace(err)
   101  		}
   102  		logger.Errorf("skipping missing file %q", nonce)
   103  	} else {
   104  		backupFiles = append(backupFiles, nonce)
   105  	}
   106  
   107  	// Handle user SSH files (might not exist).
   108  	SSHDir := filepath.Join(rootDir, sshDir)
   109  	if _, err := os.Stat(SSHDir); err != nil {
   110  		if !os.IsNotExist(err) {
   111  			return nil, errors.Trace(err)
   112  		}
   113  		logger.Errorf("skipping missing dir %q", SSHDir)
   114  	} else {
   115  		backupFiles = append(backupFiles, filepath.Join(SSHDir, authKeysFile))
   116  	}
   117  
   118  	return backupFiles, nil
   119  }