~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/resource/context/cmd/get.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 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package cmd
 
5
 
 
6
import (
 
7
        "fmt"
 
8
 
 
9
        "github.com/juju/cmd"
 
10
        "github.com/juju/errors"
 
11
)
 
12
 
 
13
// GetCmdName is the name of the resource-get command.
 
14
const GetCmdName = "resource-get"
 
15
 
 
16
// NewGetCmd creates a new GetCmd for the given hook context.
 
17
func NewGetCmd(c HookContext) (*GetCmd, error) {
 
18
        return &GetCmd{
 
19
                hookContext: c,
 
20
        }, nil
 
21
}
 
22
 
 
23
// GetCmd provides the functionality of the resource-get command.
 
24
type GetCmd struct {
 
25
        cmd.CommandBase
 
26
 
 
27
        hookContext  HookContext
 
28
        resourceName string
 
29
}
 
30
 
 
31
// TODO(ericsnow) Also provide an indicator of whether or not
 
32
// the resource has changed (in addition to the file path)?
 
33
 
 
34
// Info implements cmd.Command.
 
35
func (c GetCmd) Info() *cmd.Info {
 
36
        return &cmd.Info{
 
37
                Name:    GetCmdName,
 
38
                Args:    "<resource name>",
 
39
                Purpose: "get the path to the locally cached resource file",
 
40
                Doc: `
 
41
"resource-get" is used while a hook is running to get the local path
 
42
to the file for the identified resource. This file is an fs-local copy,
 
43
unique to the unit for which the hook is running. It is downloaded from
 
44
the controller, if necessary.
 
45
 
 
46
If "resource-get" for a resource has not been run before (for the unit)
 
47
then the resource is downloaded from the controller at the revision
 
48
associated with the unit's application. That file is stored in the unit's
 
49
local cache. If "resource-get" *has* been run before then each
 
50
subsequent run syncs the resource with the controller. This ensures
 
51
that the revision of the unit-local copy of the resource matches the
 
52
revision of the resource associated with the unit's application.
 
53
 
 
54
Either way, the path provided by "resource-get" references the
 
55
up-to-date file for the resource. Note that the resource may get
 
56
updated on the controller for the application at any time, meaning the
 
57
cached copy *may* be out of date at any time after you call
 
58
"resource-get". Consequently, the command should be run at every
 
59
point where it is critical that the resource be up to date.
 
60
 
 
61
The "upgrade-charm" hook is useful for keeping your charm's resources
 
62
on a unit up to date.  Run "resource-get" there for each of your
 
63
charm's resources to do so. The hook fires whenever the the file for
 
64
one of the application's resources changes on the controller (in addition
 
65
to when the charm itself changes). That means it happens in response
 
66
to "juju upgrade-charm" as well as to "juju push-resource".
 
67
 
 
68
Note that the "upgrade-charm" hook does not run when the unit is
 
69
started up. So be sure to run "resource-get" for your resources in the
 
70
"install" hook (or "config-changed", etc.).
 
71
 
 
72
Note that "resource-get" only provides an FS path to the resource file.
 
73
It does not provide any information about the resource (e.g. revision).
 
74
`,
 
75
        }
 
76
}
 
77
 
 
78
// Init implements cmd.Command.
 
79
func (c *GetCmd) Init(args []string) error {
 
80
        if len(args) < 1 {
 
81
                return errors.Errorf("missing required resource name")
 
82
        } else if err := cmd.CheckEmpty(args[1:]); err != nil {
 
83
                return errors.Trace(err)
 
84
        }
 
85
        c.resourceName = args[0]
 
86
        return nil
 
87
}
 
88
 
 
89
// Run implements cmd.Command.
 
90
func (c GetCmd) Run(ctx *cmd.Context) error {
 
91
        filePath, err := c.hookContext.Download(c.resourceName)
 
92
        if err != nil {
 
93
                return errors.Annotate(err, "could not download resource")
 
94
        }
 
95
 
 
96
        if _, err := fmt.Fprintf(ctx.Stdout, filePath); err != nil {
 
97
                return errors.Annotate(err, "could not write resource path to stdout")
 
98
        }
 
99
        return nil
 
100
}