~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/backups/testing/file.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package testing
 
5
 
 
6
import (
 
7
        "archive/tar"
 
8
        "bytes"
 
9
        "compress/gzip"
 
10
        "io"
 
11
        "path"
 
12
        "strings"
 
13
 
 
14
        "github.com/juju/errors"
 
15
        "github.com/juju/utils/set"
 
16
 
 
17
        "github.com/juju/juju/state/backups"
 
18
)
 
19
 
 
20
// File represents a file during testing.
 
21
type File struct {
 
22
        // Name is the path to which the file will be identified in the archive.
 
23
        Name string
 
24
        // Content is the data that will be written to the archive for the file.
 
25
        Content string
 
26
        // IsDir determines if the file is a regular file or a directory.
 
27
        IsDir bool
 
28
}
 
29
 
 
30
// AddToArchive adds the file to the tar archive.
 
31
func (f *File) AddToArchive(archive *tar.Writer) error {
 
32
        hdr := &tar.Header{
 
33
                Name: f.Name,
 
34
        }
 
35
        if f.IsDir {
 
36
                hdr.Typeflag = tar.TypeDir
 
37
                hdr.Mode = 0777
 
38
        } else {
 
39
                hdr.Size = int64(len(f.Content))
 
40
                hdr.Mode = 0666
 
41
        }
 
42
 
 
43
        if err := archive.WriteHeader(hdr); err != nil {
 
44
                return errors.Trace(err)
 
45
        }
 
46
 
 
47
        if !f.IsDir {
 
48
                if _, err := archive.Write([]byte(f.Content)); err != nil {
 
49
                        return errors.Trace(err)
 
50
                }
 
51
        }
 
52
 
 
53
        return nil
 
54
}
 
55
 
 
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()
 
59
        var sysFiles []File
 
60
        for _, file := range files {
 
61
                var parent string
 
62
                for _, p := range strings.Split(path.Dir(file.Name), "/") {
 
63
                        if parent == "" {
 
64
                                parent = p
 
65
                        } else {
 
66
                                parent = path.Join(parent, p)
 
67
                        }
 
68
                        if !dirs.Contains(parent) {
 
69
                                sysFiles = append(sysFiles, File{
 
70
                                        Name:  parent,
 
71
                                        IsDir: true,
 
72
                                })
 
73
                                dirs.Add(parent)
 
74
                        }
 
75
                }
 
76
                if file.IsDir {
 
77
                        if !dirs.Contains(file.Name) {
 
78
                                sysFiles = append(sysFiles, file)
 
79
                                dirs.Add(file.Name)
 
80
                        }
 
81
                } else {
 
82
                        sysFiles = append(sysFiles, file)
 
83
                }
 
84
        }
 
85
 
 
86
        var rootFile bytes.Buffer
 
87
        if err := writeToTar(&rootFile, sysFiles); err != nil {
 
88
                return nil, errors.Trace(err)
 
89
        }
 
90
 
 
91
        topfiles := []File{{
 
92
                Name:  "juju-backup",
 
93
                IsDir: true,
 
94
        }}
 
95
 
 
96
        topfiles = append(topfiles, File{
 
97
                Name:  "juju-backup/dump",
 
98
                IsDir: true,
 
99
        })
 
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,
 
105
                })
 
106
        }
 
107
 
 
108
        topfiles = append(topfiles,
 
109
                File{
 
110
                        Name:    "juju-backup/root.tar",
 
111
                        Content: rootFile.String(),
 
112
                },
 
113
        )
 
114
 
 
115
        if meta != nil {
 
116
                metaFile, err := meta.AsJSONBuffer()
 
117
                if err != nil {
 
118
                        return nil, errors.Trace(err)
 
119
                }
 
120
                topfiles = append(topfiles,
 
121
                        File{
 
122
                                Name:    "juju-backup/metadata.json",
 
123
                                Content: metaFile.(*bytes.Buffer).String(),
 
124
                        },
 
125
                )
 
126
        }
 
127
 
 
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)
 
133
        }
 
134
 
 
135
        return &arFile, nil
 
136
}
 
137
 
 
138
// NewArchiveBasic returns a new archive file with a few files provided.
 
139
func NewArchiveBasic(meta *backups.Metadata) (*bytes.Buffer, error) {
 
140
        files := []File{
 
141
                {
 
142
                        Name:    "var/lib/juju/tools/1.21-alpha2.1-trusty-amd64/jujud",
 
143
                        Content: "<some binary data goes here>",
 
144
                },
 
145
                {
 
146
                        Name:    "var/lib/juju/system-identity",
 
147
                        Content: "<an ssh key goes here>",
 
148
                },
 
149
        }
 
150
        dump := []File{
 
151
                {
 
152
                        Name:    "juju/machines.bson",
 
153
                        Content: "<BSON data goes here>",
 
154
                },
 
155
                {
 
156
                        Name:    "oplog.bson",
 
157
                        Content: "<BSON data goes here>",
 
158
                },
 
159
        }
 
160
 
 
161
        arFile, err := NewArchive(meta, files, dump)
 
162
        if err != nil {
 
163
                return nil, errors.Trace(err)
 
164
        }
 
165
        return arFile, nil
 
166
}
 
167
 
 
168
func writeToTar(archive io.Writer, files []File) error {
 
169
        tarw := tar.NewWriter(archive)
 
170
        defer tarw.Close()
 
171
 
 
172
        for _, file := range files {
 
173
                if err := file.AddToArchive(tarw); err != nil {
 
174
                        return errors.Trace(err)
 
175
                }
 
176
        }
 
177
        return nil
 
178
}