1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
14
"github.com/juju/errors"
15
"github.com/juju/utils/set"
17
"github.com/juju/juju/state/backups"
20
// File represents a file during testing.
22
// Name is the path to which the file will be identified in the archive.
24
// Content is the data that will be written to the archive for the file.
26
// IsDir determines if the file is a regular file or a directory.
30
// AddToArchive adds the file to the tar archive.
31
func (f *File) AddToArchive(archive *tar.Writer) error {
36
hdr.Typeflag = tar.TypeDir
39
hdr.Size = int64(len(f.Content))
43
if err := archive.WriteHeader(hdr); err != nil {
44
return errors.Trace(err)
48
if _, err := archive.Write([]byte(f.Content)); err != nil {
49
return errors.Trace(err)
56
// NewArchive returns a new archive file containing the files.
57
func NewArchive(meta *backups.Metadata, files, dump []File) (*bytes.Buffer, error) {
58
dirs := set.NewStrings()
60
for _, file := range files {
62
for _, p := range strings.Split(path.Dir(file.Name), "/") {
66
parent = path.Join(parent, p)
68
if !dirs.Contains(parent) {
69
sysFiles = append(sysFiles, File{
77
if !dirs.Contains(file.Name) {
78
sysFiles = append(sysFiles, file)
82
sysFiles = append(sysFiles, file)
86
var rootFile bytes.Buffer
87
if err := writeToTar(&rootFile, sysFiles); err != nil {
88
return nil, errors.Trace(err)
96
topfiles = append(topfiles, File{
97
Name: "juju-backup/dump",
100
for _, dumpFile := range dump {
101
topfiles = append(topfiles, File{
102
Name: "juju-backup/dump/" + dumpFile.Name,
103
Content: dumpFile.Content,
104
IsDir: dumpFile.IsDir,
108
topfiles = append(topfiles,
110
Name: "juju-backup/root.tar",
111
Content: rootFile.String(),
116
metaFile, err := meta.AsJSONBuffer()
118
return nil, errors.Trace(err)
120
topfiles = append(topfiles,
122
Name: "juju-backup/metadata.json",
123
Content: metaFile.(*bytes.Buffer).String(),
128
var arFile bytes.Buffer
129
compressed := gzip.NewWriter(&arFile)
130
defer compressed.Close()
131
if err := writeToTar(compressed, topfiles); err != nil {
132
return nil, errors.Trace(err)
138
// NewArchiveBasic returns a new archive file with a few files provided.
139
func NewArchiveBasic(meta *backups.Metadata) (*bytes.Buffer, error) {
142
Name: "var/lib/juju/tools/1.21-alpha2.1-trusty-amd64/jujud",
143
Content: "<some binary data goes here>",
146
Name: "var/lib/juju/system-identity",
147
Content: "<an ssh key goes here>",
152
Name: "juju/machines.bson",
153
Content: "<BSON data goes here>",
157
Content: "<BSON data goes here>",
161
arFile, err := NewArchive(meta, files, dump)
163
return nil, errors.Trace(err)
168
func writeToTar(archive io.Writer, files []File) error {
169
tarw := tar.NewWriter(archive)
172
for _, file := range files {
173
if err := file.AddToArchive(tarw); err != nil {
174
return errors.Trace(err)