-
Notifications
You must be signed in to change notification settings - Fork 200
/
action.go
140 lines (119 loc) · 4.08 KB
/
action.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package cnabprovider
import (
"encoding/json"
"fmt"
"get.porter.sh/porter/pkg/config"
"github.com/cnabio/cnab-go/action"
"github.com/cnabio/cnab-go/claim"
"github.com/cnabio/cnab-go/driver"
"github.com/cnabio/cnab-go/valuesource"
"github.com/cnabio/cnab-to-oci/relocation"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
// Shared arguments for all CNAB actions
type ActionArguments struct {
// Name of the instance.
Instance string
// Either a filepath to the bundle or the name of the bundle.
BundlePath string
// Additional files to copy into the bundle
// Target Path => File Contents
Files map[string]string
// Params is the set of user-specified parameter values to pass to the bundle.
Params map[string]string
// ParameterSets is a list of strings representing either a filepath to a
// parameter set file or the name of a set of a parameters.
ParameterSets []string
// Either a filepath to a credential file or the name of a set of a credentials.
CredentialIdentifiers []string
// Driver is the CNAB-compliant driver used to run bundle actions.
Driver string
// Path to an optional relocation mapping file
RelocationMapping string
// Give the bundle privileged access to the docker daemon.
AllowDockerHostAccess bool
}
func (r *Runtime) ApplyConfig(args ActionArguments) action.OperationConfigs {
return action.OperationConfigs{
r.SetOutput(),
r.AddFiles(args),
r.AddRelocation(args),
}
}
func (r *Runtime) SetOutput() action.OperationConfigFunc {
return func(op *driver.Operation) error {
op.Out = r.Out
return nil
}
}
func (r *Runtime) AddFiles(args ActionArguments) action.OperationConfigFunc {
return func(op *driver.Operation) error {
for k, v := range args.Files {
op.Files[k] = v
}
// Add claim.json to file list as well, if exists
claim, err := r.claims.ReadLastClaim(args.Instance)
if err == nil {
claimBytes, err := yaml.Marshal(claim)
if err != nil {
return errors.Wrapf(err, "could not marshal claim %s for instance %s", claim.ID, args.Instance)
}
op.Files[config.ClaimFilepath] = string(claimBytes)
}
return nil
}
}
// AddRelocation operates on an ActionArguments and adds any provided relocation mapping
// to the operation's files.
func (r *Runtime) AddRelocation(args ActionArguments) action.OperationConfigFunc {
return func(op *driver.Operation) error {
if args.RelocationMapping != "" {
b, err := r.FileSystem.ReadFile(args.RelocationMapping)
if err != nil {
return errors.Wrap(err, "unable to add relocation mapping")
}
op.Files["/cnab/app/relocation-mapping.json"] = string(b)
var reloMap relocation.ImageRelocationMap
err = json.Unmarshal(b, &reloMap)
// If the invocation image is present in the relocation mapping, we need
// to update the operation and set the new image reference. Unfortunately,
// the relocation mapping is just reference => reference, so there isn't a
// great way to check for the invocation image.
if mappedInvo, ok := reloMap[op.Image.Image]; ok {
op.Image.Image = mappedInvo
}
}
return nil
}
}
// appendFailedResult creates a failed result from the operation error and accumulates
// the error(s).
func (r *Runtime) appendFailedResult(opErr error, c claim.Claim) error {
saveResult := func() error {
result, err := c.NewResult(claim.StatusFailed)
if err != nil {
return err
}
return r.claims.SaveResult(result)
}
resultErr := saveResult()
// Accumulate any errors from the operation with the persistence errors
return multierror.Append(opErr, resultErr).ErrorOrNil()
}
func (r *Runtime) printDebugInfo(creds valuesource.Set, params map[string]interface{}) {
if r.Debug {
// only print out the names of the credentials, not the contents, cuz they big and sekret
credKeys := make([]string, 0, len(creds))
for k := range creds {
credKeys = append(credKeys, k)
}
// param values may also be sensitive, so just print names
paramKeys := make([]string, 0, len(params))
for k := range params {
paramKeys = append(paramKeys, k)
}
fmt.Fprintf(r.Err, "params: %v\ncreds: %v\n", paramKeys, credKeys)
}
}