~ubuntu-branches/ubuntu/trusty/juju-core/trusty

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/environs/filestorage/filestorage.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-03-24 16:05:44 UTC
  • mfrom: (1.1.20)
  • Revision ID: package-import@ubuntu.com-20140324160544-g8lsfufby18d5fj4
Tags: 1.17.6-0ubuntu1
* New upstream point release, including fixes for:
  - br0 not bought up by cloud-init with MAAS provider (LP: #1271144).
  - ppc64el enablement for juju/lxc (LP: #1273769).
  - juju userdata should not restart networking (LP: #1248283).
  - error detecting hardware characteristics (LP: #1276909).
  - juju instances not including the default security group (LP: #1129720).
  - juju bootstrap does not honor https_proxy (LP: #1240260).
* d/control,rules: Drop BD on bash-completion, install bash-completion
  direct from upstream source code.
* d/rules: Set HOME prior to generating man pages.
* d/control: Drop alternative dependency on mongodb-server; juju now only
  works on trusty with juju-mongodb.

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
// Get implements storage.StorageReader.Get.
51
51
func (f *fileStorageReader) Get(name string) (io.ReadCloser, error) {
 
52
        if isInternalPath(name) {
 
53
                return nil, &os.PathError{
 
54
                        Op:   "Get",
 
55
                        Path: name,
 
56
                        Err:  os.ErrNotExist,
 
57
                }
 
58
        }
52
59
        filename := f.fullPath(name)
53
60
        fi, err := os.Stat(filename)
54
61
        if err != nil {
66
73
        return file, nil
67
74
}
68
75
 
 
76
// isInternalPath returns true if a path should be hidden from user visibility
 
77
// filestorage uses ".tmp/" as a staging directory for uploads, so we don't
 
78
// want it to be visible
 
79
func isInternalPath(path string) bool {
 
80
        // This blocks both ".tmp", ".tmp/foo" but also ".tmpdir", better to be
 
81
        // overly restrictive to start with
 
82
        return strings.HasPrefix(path, ".tmp")
 
83
}
 
84
 
69
85
// List implements storage.StorageReader.List.
70
86
func (f *fileStorageReader) List(prefix string) ([]string, error) {
 
87
        var names []string
 
88
        if isInternalPath(prefix) {
 
89
                return names, nil
 
90
        }
71
91
        prefix = filepath.Join(f.path, prefix)
72
92
        dir := filepath.Dir(prefix)
73
 
        var names []string
74
93
        err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
75
94
                if err != nil {
76
95
                        return err
104
123
 
105
124
type fileStorageWriter struct {
106
125
        fileStorageReader
107
 
        tmpdir string
108
126
}
109
127
 
110
 
// UseDefaultTmpDir may be passed into NewFileStorageWriter
111
 
// for the tmpdir argument, to signify that the default
112
 
// value should be used. See NewFileStorageWriter for more.
113
 
const UseDefaultTmpDir = ""
114
 
 
115
128
// NewFileStorageWriter returns a new read/write storag for
116
129
// a directory inside the local file system.
117
 
//
118
 
// A temporary directory may be specified, in which files will be written
119
 
// to before moving to the final destination. If specified, the temporary
120
 
// directory should be on the same filesystem as the storage directory
121
 
// to ensure atomicity. If tmpdir == UseDefaultTmpDir (""), then path+".tmp"
122
 
// will be used.
123
 
//
124
 
// If tmpdir == UseDefaultTmpDir, it will be created when Put is invoked,
125
 
// and will be removed afterwards. If tmpdir != UseDefaultTmpDir, it must
126
 
// already exist, and will never be removed.
127
 
func NewFileStorageWriter(path, tmpdir string) (storage.Storage, error) {
 
130
func NewFileStorageWriter(path string) (storage.Storage, error) {
128
131
        reader, err := NewFileStorageReader(path)
129
132
        if err != nil {
130
133
                return nil, err
131
134
        }
132
 
        return &fileStorageWriter{*reader.(*fileStorageReader), tmpdir}, nil
 
135
        return &fileStorageWriter{*reader.(*fileStorageReader)}, nil
133
136
}
134
137
 
135
138
func (f *fileStorageWriter) Put(name string, r io.Reader, length int64) error {
 
139
        if isInternalPath(name) {
 
140
                return &os.PathError{
 
141
                        Op:   "Put",
 
142
                        Path: name,
 
143
                        Err:  os.ErrPermission,
 
144
                }
 
145
        }
136
146
        fullpath := f.fullPath(name)
137
147
        dir := filepath.Dir(fullpath)
138
 
        tmpdir := f.tmpdir
139
 
        if tmpdir == UseDefaultTmpDir {
140
 
                tmpdir = f.path + ".tmp"
141
 
                if err := os.MkdirAll(tmpdir, 0755); err != nil && !os.IsExist(err) {
142
 
                        return err
143
 
                }
144
 
                defer os.Remove(tmpdir)
145
 
        }
146
 
        if err := os.MkdirAll(dir, 0755); err != nil && !os.IsExist(err) {
147
 
                return err
148
 
        }
 
148
        if err := os.MkdirAll(dir, 0755); err != nil {
 
149
                return err
 
150
        }
 
151
        tmpdir := filepath.Join(f.path, ".tmp")
 
152
        if err := os.MkdirAll(tmpdir, 0755); err != nil {
 
153
                return err
 
154
        }
 
155
        defer os.Remove(tmpdir)
149
156
        // Write to a temporary file first, and then move (atomically).
150
157
        file, err := ioutil.TempFile(tmpdir, "juju-filestorage-")
151
158
        if err != nil {