github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/apiserver/backups/backups.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 "io" 8 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/state" 15 "github.com/juju/juju/state/backups" 16 ) 17 18 func init() { 19 common.RegisterStandardFacade("Backups", 0, NewAPI) 20 } 21 22 var logger = loggo.GetLogger("juju.apiserver.backups") 23 24 // API serves backup-specific API methods. 25 type API struct { 26 st *state.State 27 paths *backups.Paths 28 29 // machineID is the ID of the machine where the API server is running. 30 machineID string 31 } 32 33 // NewAPI creates a new instance of the Backups API facade. 34 func NewAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*API, error) { 35 if !authorizer.AuthClient() { 36 return nil, errors.Trace(common.ErrPerm) 37 } 38 39 // For now, backup operations are only permitted on the system environment. 40 if !st.IsStateServer() { 41 return nil, errors.New("backups are not supported for hosted environments") 42 } 43 44 // Get the backup paths. 45 dataDir, err := extractResourceValue(resources, "dataDir") 46 if err != nil { 47 return nil, errors.Trace(err) 48 } 49 logsDir, err := extractResourceValue(resources, "logDir") 50 if err != nil { 51 return nil, errors.Trace(err) 52 } 53 paths := backups.Paths{ 54 DataDir: dataDir, 55 LogsDir: logsDir, 56 } 57 58 // Build the API. 59 machineID, err := extractResourceValue(resources, "machineID") 60 if err != nil { 61 return nil, errors.Trace(err) 62 } 63 b := API{ 64 st: st, 65 paths: &paths, 66 machineID: machineID, 67 } 68 return &b, nil 69 } 70 71 func extractResourceValue(resources *common.Resources, key string) (string, error) { 72 res := resources.Get(key) 73 strRes, ok := res.(common.StringResource) 74 if !ok { 75 if res == nil { 76 strRes = "" 77 } else { 78 return "", errors.Errorf("invalid %s resource: %v", key, res) 79 } 80 } 81 return strRes.String(), nil 82 } 83 84 var newBackups = func(st *state.State) (backups.Backups, io.Closer) { 85 stor := backups.NewStorage(st) 86 return backups.NewBackups(stor), stor 87 } 88 89 // ResultFromMetadata updates the result with the information in the 90 // metadata value. 91 func ResultFromMetadata(meta *backups.Metadata) params.BackupsMetadataResult { 92 var result params.BackupsMetadataResult 93 94 result.ID = meta.ID() 95 96 result.Checksum = meta.Checksum() 97 result.ChecksumFormat = meta.ChecksumFormat() 98 result.Size = meta.Size() 99 if meta.Stored() != nil { 100 result.Stored = *(meta.Stored()) 101 } 102 103 result.Started = meta.Started 104 if meta.Finished != nil { 105 result.Finished = *meta.Finished 106 } 107 result.Notes = meta.Notes 108 109 result.Environment = meta.Origin.Environment 110 result.Machine = meta.Origin.Machine 111 result.Hostname = meta.Origin.Hostname 112 result.Version = meta.Origin.Version 113 114 return result 115 } 116 117 // MetadataFromResult returns a new Metadata based on the result. The ID 118 // of the metadata is not set. Call meta.SetID() if that is desired. 119 // Likewise with Stored and meta.SetStored(). 120 func MetadataFromResult(result params.BackupsMetadataResult) *backups.Metadata { 121 meta := backups.NewMetadata() 122 meta.Started = result.Started 123 if !result.Finished.IsZero() { 124 meta.Finished = &result.Finished 125 } 126 meta.Origin.Environment = result.Environment 127 meta.Origin.Machine = result.Machine 128 meta.Origin.Hostname = result.Hostname 129 meta.Origin.Version = result.Version 130 meta.Notes = result.Notes 131 meta.SetFileInfo(result.Size, result.Checksum, result.ChecksumFormat) 132 return meta 133 }