1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
15
"launchpad.net/juju-core/environs/config"
16
"launchpad.net/juju-core/environs/simplestreams"
20
defaultIndexFileName = "index.json"
21
defaultToolsFileName = "toolsmetadata.json"
22
streamsDir = "streams/v1"
25
// Boilerplate generates some basic simplestreams metadata using the specified cloud and tools details.
26
// If name is non-empty, it will be used as a prefix for the names of the generated index and tools files.
27
func Boilerplate(name, series string, tm *ToolsMetadata, cloudSpec *simplestreams.CloudSpec) ([]string, error) {
28
return MakeBoilerplate(name, series, tm, cloudSpec, true)
31
// MakeBoilerplate exists so it can be called by tests. See Boilerplate above. It provides an option to retain
32
// the streams directories when writing the generated metadata files.
33
func MakeBoilerplate(name, series string, tm *ToolsMetadata, cloudSpec *simplestreams.CloudSpec, flattenPath bool) ([]string, error) {
34
indexFileName := defaultIndexFileName
35
toolsFileName := defaultToolsFileName
37
indexFileName = fmt.Sprintf("%s-%s", name, indexFileName)
38
toolsFileName = fmt.Sprintf("%s-%s", name, toolsFileName)
41
imparams := toolsMetadataParams{
42
ToolsBinarySize: tm.Size,
43
ToolsBinaryPath: tm.Path,
44
ToolsBinaryHash: tm.Hash,
48
Region: cloudSpec.Region,
49
URL: cloudSpec.Endpoint,
51
ToolsFileName: toolsFileName,
52
Updated: now.Format(time.RFC1123Z),
53
VersionKey: now.Format("20060102"),
57
streamsPath := config.JujuHomePath(streamsDir)
58
if err := os.MkdirAll(streamsPath, 0755); err != nil {
61
indexFileName = filepath.Join(streamsDir, indexFileName)
62
toolsFileName = filepath.Join(streamsDir, toolsFileName)
64
err := writeJsonFile(imparams, indexFileName, indexBoilerplate)
68
err = writeJsonFile(imparams, toolsFileName, productBoilerplate)
72
return []string{indexFileName, toolsFileName}, nil
75
type toolsMetadataParams struct {
76
ToolsBinaryPath string
77
ToolsBinarySize float64
78
ToolsBinaryHash string
90
func writeJsonFile(imparams toolsMetadataParams, filename, boilerplate string) error {
91
t := template.Must(template.New("").Parse(boilerplate))
92
var metadata bytes.Buffer
93
if err := t.Execute(&metadata, imparams); err != nil {
94
panic(fmt.Errorf("cannot generate %s metdata: %v", filename, err))
96
data := metadata.Bytes()
97
path := config.JujuHomePath(filename)
98
if err := ioutil.WriteFile(path, data, 0666); err != nil {
104
var indexBoilerplate = `
107
"com.ubuntu.tools:custom": {
108
"updated": "{{.Updated}}",
111
"region": "{{.Region}}",
112
"endpoint": "{{.URL}}"
115
"cloudname": "custom",
116
"datatype": "juju-tools",
117
"format": "products:1.0",
119
"com.ubuntu.juju:{{.Version}}:{{.Arch}}"
121
"path": "{{.Path}}/{{.ToolsFileName}}"
124
"updated": "{{.Updated}}",
125
"format": "index:1.0"
129
var productBoilerplate = `
131
"content_id": "com.ubuntu.tools:custom",
132
"format": "products:1.0",
133
"updated": "{{.Updated}}",
134
"datatype": "juju-tools",
136
"com.ubuntu.juju:{{.Version}}:{{.Arch}}": {
137
"release": "{{.Series}}",
138
"version": "{{.Version}}",
143
"{{.Series}}{{.Version}}": {
144
"release": "{{.Series}}",
145
"size": {{.ToolsBinarySize}},
146
"path": "{{.ToolsBinaryPath}}",
148
"md5": "{{.ToolsBinaryHash}}"
151
"pubname": "juju-{{.Version}}-{{.Series}}-{{.Arch}}-{{.VersionKey}}",