~rogpeppe/juju-core/axwalk-lp1300889-disable-mongo-keyfile

« back to all changes in this revision

Viewing changes to environs/tools/boilerplate.go

  • Committer: Ian Booth
  • Date: 2013-08-13 04:55:12 UTC
  • mto: (1603.8.2 simplify-tools-search)
  • mto: This revision was merged to the branch mainline in revision 1680.
  • Revision ID: ian.booth@canonical.com-20130813045512-e68m4emfaoyn01h9
Add support for parsing and validating tools metadata

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package tools
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "fmt"
 
9
        "io/ioutil"
 
10
        "os"
 
11
        "path/filepath"
 
12
        "text/template"
 
13
        "time"
 
14
 
 
15
        "launchpad.net/juju-core/environs/config"
 
16
        "launchpad.net/juju-core/environs/simplestreams"
 
17
)
 
18
 
 
19
const (
 
20
        defaultIndexFileName = "index.json"
 
21
        defaultToolsFileName = "toolsmetadata.json"
 
22
        streamsDir           = "streams/v1"
 
23
)
 
24
 
 
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)
 
29
}
 
30
 
 
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
 
36
        if name != "" {
 
37
                indexFileName = fmt.Sprintf("%s-%s", name, indexFileName)
 
38
                toolsFileName = fmt.Sprintf("%s-%s", name, toolsFileName)
 
39
        }
 
40
        now := time.Now()
 
41
        imparams := toolsMetadataParams{
 
42
                ToolsBinarySize: tm.Size,
 
43
                ToolsBinaryPath: tm.Path,
 
44
                ToolsBinaryHash: tm.Hash,
 
45
                Version:         tm.Version,
 
46
                Arch:            tm.Arch,
 
47
                Series:          tm.Release,
 
48
                Region:          cloudSpec.Region,
 
49
                URL:             cloudSpec.Endpoint,
 
50
                Path:            streamsDir,
 
51
                ToolsFileName:   toolsFileName,
 
52
                Updated:         now.Format(time.RFC1123Z),
 
53
                VersionKey:      now.Format("20060102"),
 
54
        }
 
55
 
 
56
        if !flattenPath {
 
57
                streamsPath := config.JujuHomePath(streamsDir)
 
58
                if err := os.MkdirAll(streamsPath, 0755); err != nil {
 
59
                        return nil, err
 
60
                }
 
61
                indexFileName = filepath.Join(streamsDir, indexFileName)
 
62
                toolsFileName = filepath.Join(streamsDir, toolsFileName)
 
63
        }
 
64
        err := writeJsonFile(imparams, indexFileName, indexBoilerplate)
 
65
        if err != nil {
 
66
                return nil, err
 
67
        }
 
68
        err = writeJsonFile(imparams, toolsFileName, productBoilerplate)
 
69
        if err != nil {
 
70
                return nil, err
 
71
        }
 
72
        return []string{indexFileName, toolsFileName}, nil
 
73
}
 
74
 
 
75
type toolsMetadataParams struct {
 
76
        ToolsBinaryPath string
 
77
        ToolsBinarySize float64
 
78
        ToolsBinaryHash string
 
79
        Region          string
 
80
        URL             string
 
81
        Updated         string
 
82
        Arch            string
 
83
        Path            string
 
84
        Series          string
 
85
        Version         string
 
86
        VersionKey      string
 
87
        ToolsFileName   string
 
88
}
 
89
 
 
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))
 
95
        }
 
96
        data := metadata.Bytes()
 
97
        path := config.JujuHomePath(filename)
 
98
        if err := ioutil.WriteFile(path, data, 0666); err != nil {
 
99
                return err
 
100
        }
 
101
        return nil
 
102
}
 
103
 
 
104
var indexBoilerplate = `
 
105
{
 
106
 "index": {
 
107
   "com.ubuntu.tools:custom": {
 
108
     "updated": "{{.Updated}}",
 
109
     "clouds": [
 
110
       {
 
111
         "region": "{{.Region}}",
 
112
         "endpoint": "{{.URL}}"
 
113
       }
 
114
     ],
 
115
     "cloudname": "custom",
 
116
     "datatype": "juju-tools",
 
117
     "format": "products:1.0",
 
118
     "products": [
 
119
       "com.ubuntu.juju:{{.Version}}:{{.Arch}}"
 
120
     ],
 
121
     "path": "{{.Path}}/{{.ToolsFileName}}"
 
122
   }
 
123
 },
 
124
 "updated": "{{.Updated}}",
 
125
 "format": "index:1.0"
 
126
}
 
127
`
 
128
 
 
129
var productBoilerplate = `
 
130
{
 
131
  "content_id": "com.ubuntu.tools:custom",
 
132
  "format": "products:1.0",
 
133
  "updated": "{{.Updated}}",
 
134
  "datatype": "juju-tools",
 
135
  "products": {
 
136
    "com.ubuntu.juju:{{.Version}}:{{.Arch}}": {
 
137
      "release": "{{.Series}}",
 
138
      "version": "{{.Version}}",
 
139
      "arch": "{{.Arch}}",
 
140
      "versions": {
 
141
        "{{.VersionKey}}": {
 
142
          "items": {
 
143
            "{{.Series}}{{.Version}}": {
 
144
              "release": "{{.Series}}",
 
145
              "size": {{.ToolsBinarySize}},
 
146
              "path": "{{.ToolsBinaryPath}}",
 
147
              "ftype": "tar.gz",
 
148
              "md5": "{{.ToolsBinaryHash}}"
 
149
            }
 
150
          },
 
151
          "pubname": "juju-{{.Version}}-{{.Series}}-{{.Arch}}-{{.VersionKey}}",
 
152
          "label": "custom"
 
153
        }
 
154
      }
 
155
    }
 
156
  }
 
157
}
 
158
`