Merge a2ed15ffb2
into 1544488a10
This commit is contained in:
commit
0c4591ed55
7 changed files with 403 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
||||||
/docs/*.[158]
|
/docs/*.[158]
|
||||||
/docs/*.[158].gz
|
/docs/*.[158].gz
|
||||||
/kpod
|
/kpod
|
||||||
|
/crio-release
|
||||||
/crioctl
|
/crioctl
|
||||||
/crio
|
/crio
|
||||||
/crio.conf
|
/crio.conf
|
||||||
|
|
9
Makefile
9
Makefile
|
@ -45,7 +45,7 @@ help:
|
||||||
@echo "Usage: make <target>"
|
@echo "Usage: make <target>"
|
||||||
@echo
|
@echo
|
||||||
@echo " * 'install' - Install binaries to system locations"
|
@echo " * 'install' - Install binaries to system locations"
|
||||||
@echo " * 'binaries' - Build crio, conmon and crioctl"
|
@echo " * 'binaries' - Build crio, conmon, crio-release and crioctl"
|
||||||
@echo " * 'integration' - Execute integration tests"
|
@echo " * 'integration' - Execute integration tests"
|
||||||
@echo " * 'clean' - Clean artifacts"
|
@echo " * 'clean' - Clean artifacts"
|
||||||
@echo " * 'lint' - Execute the source code linter"
|
@echo " * 'lint' - Execute the source code linter"
|
||||||
|
@ -86,6 +86,9 @@ crio: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crio $(PROJECT))
|
||||||
crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT))
|
crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT))
|
||||||
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/crioctl
|
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/crioctl
|
||||||
|
|
||||||
|
crio-release: .gopathok
|
||||||
|
$(GO) build -o $@ $(PROJECT)/cmd/crio-release
|
||||||
|
|
||||||
kpod: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/kpod $(PROJECT))
|
kpod: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/kpod $(PROJECT))
|
||||||
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/kpod
|
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/kpod
|
||||||
|
|
||||||
|
@ -101,7 +104,7 @@ endif
|
||||||
rm -fr test/testdata/redis-image
|
rm -fr test/testdata/redis-image
|
||||||
find . -name \*~ -delete
|
find . -name \*~ -delete
|
||||||
find . -name \#\* -delete
|
find . -name \#\* -delete
|
||||||
rm -f crioctl crio kpod
|
rm -f crioctl crio kpod crio-release
|
||||||
make -C conmon clean
|
make -C conmon clean
|
||||||
make -C pause clean
|
make -C pause clean
|
||||||
rm -f test/bin2img/bin2img
|
rm -f test/bin2img/bin2img
|
||||||
|
@ -123,7 +126,7 @@ testunit:
|
||||||
localintegration: clean binaries
|
localintegration: clean binaries
|
||||||
./test/test_runner.sh ${TESTFLAGS}
|
./test/test_runner.sh ${TESTFLAGS}
|
||||||
|
|
||||||
binaries: crio crioctl kpod conmon pause test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
|
binaries: crio crio-release crioctl kpod conmon pause test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
|
||||||
|
|
||||||
MANPAGES_MD := $(wildcard docs/*.md)
|
MANPAGES_MD := $(wildcard docs/*.md)
|
||||||
MANPAGES := $(MANPAGES_MD:%.md=%)
|
MANPAGES := $(MANPAGES_MD:%.md=%)
|
||||||
|
|
43
cmd/crio-release/build.go
Normal file
43
cmd/crio-release/build.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func build() error {
|
||||||
|
out, err := exec.Command("make").CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %s", err, out)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const tarFormat = "cri-o-%s.%s-%s.tar.gz"
|
||||||
|
|
||||||
|
func tarRelease(tag string) (string, error) {
|
||||||
|
path := fmt.Sprintf(tarFormat, tag, runtime.GOOS, runtime.GOARCH)
|
||||||
|
out, err := exec.Command("tar", "-zcf", path, "bin/").CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%s: %s", err, out)
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(path string) (string, error) {
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
s := sha256.New()
|
||||||
|
if _, err := io.Copy(s, f); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(s.Sum(nil)), nil
|
||||||
|
}
|
115
cmd/crio-release/main.go
Normal file
115
cmd/crio-release/main.go
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
const vendorConf = "vendor.conf"
|
||||||
|
|
||||||
|
type note struct {
|
||||||
|
Title string `toml:"title"`
|
||||||
|
Description string `toml:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type change struct {
|
||||||
|
Commit string `toml:"commit"`
|
||||||
|
Description string `toml:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type dependency struct {
|
||||||
|
Name string
|
||||||
|
Commit string
|
||||||
|
Previous string
|
||||||
|
}
|
||||||
|
|
||||||
|
type download struct {
|
||||||
|
Filename string
|
||||||
|
Hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
type release struct {
|
||||||
|
Commit string `toml:"commit"`
|
||||||
|
Previous string `toml:"previous"`
|
||||||
|
PreRelease bool `toml:"pre_release"`
|
||||||
|
Preface string `toml:"preface"`
|
||||||
|
Notes map[string]note `toml:"notes"`
|
||||||
|
BreakingChanges map[string]change `toml:"breaking"`
|
||||||
|
// generated fields
|
||||||
|
Changes []change
|
||||||
|
Contributors []string
|
||||||
|
Dependencies []dependency
|
||||||
|
Version string
|
||||||
|
Downloads []download
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "crio-release"
|
||||||
|
app.Description = `release tooling for CRI-O.
|
||||||
|
|
||||||
|
This tool should be ran from the root of the CRI-O repository for a new release.
|
||||||
|
`
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "dry,n",
|
||||||
|
Usage: "run the release tooling as a dry run to print the release notes to stdout",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
app.Action = func(context *cli.Context) error {
|
||||||
|
logrus.Info("Welcome to the CRI-O release tool...")
|
||||||
|
var (
|
||||||
|
path = context.Args().First()
|
||||||
|
tag = parseTag(path)
|
||||||
|
)
|
||||||
|
r, err := loadRelease(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
previous, err := getPreviousDeps(r.Previous)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
changes, err := changelog(r.Previous, r.Commit)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logrus.Infof("creating new release %s with %d new changes...", tag, len(changes))
|
||||||
|
rd, err := fileFromRev(r.Commit, vendorConf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
deps, err := parseDependencies(rd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updatedDeps := updatedDeps(previous, deps)
|
||||||
|
contributors, err := getContributors(r.Previous, r.Commit)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// update the release fields with generated data
|
||||||
|
r.Contributors = contributors
|
||||||
|
r.Dependencies = updatedDeps
|
||||||
|
r.Changes = changes
|
||||||
|
r.Version = tag
|
||||||
|
|
||||||
|
if context.Bool("dry") {
|
||||||
|
t, err := template.New("release-notes").Parse(releaseNotes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.Execute(os.Stdout, r)
|
||||||
|
}
|
||||||
|
logrus.Info("release complete!")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
fmt.Fprint(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
35
cmd/crio-release/template.go
Normal file
35
cmd/crio-release/template.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
const releaseNotes = `Welcome to the release of CRI-O {{.Version}}!
|
||||||
|
{{if .PreRelease}}
|
||||||
|
*This is a pre-release of CRI-O*
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
{{.Preface}}
|
||||||
|
|
||||||
|
Please try out the release binaries and report any issues at
|
||||||
|
https://github.com/kubernetes-incubator/cri-o/issues.
|
||||||
|
|
||||||
|
{{range $note := .Notes}}
|
||||||
|
### {{$note.Title}}
|
||||||
|
|
||||||
|
{{$note.Description}}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
### Contributors
|
||||||
|
{{range $contributor := .Contributors}}
|
||||||
|
* {{$contributor}}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
{{range $change := .Changes}}
|
||||||
|
* {{$change.Commit}} {{$change.Description}}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
### Dependency Changes
|
||||||
|
|
||||||
|
Previous release can be found at [{{.Previous}}](https://github.com/kubernetes-incubator/cri-o/releases/tag/{{.Previous}})
|
||||||
|
{{range $dep := .Dependencies}}
|
||||||
|
* {{$dep.Previous}} -> {{$dep.Commit}} **{{$dep.Name}}**
|
||||||
|
{{- end}}
|
||||||
|
`
|
165
cmd/crio-release/util.go
Normal file
165
cmd/crio-release/util.go
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadRelease(path string) (*release, error) {
|
||||||
|
var r release
|
||||||
|
if _, err := toml.DecodeFile(path, &r); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, errors.New("please specify the release file as the first argument")
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTag(path string) string {
|
||||||
|
return strings.TrimSuffix(filepath.Base(path), ".toml")
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDependencies(r io.Reader) ([]dependency, error) {
|
||||||
|
var deps []dependency
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
for s.Scan() {
|
||||||
|
ln := strings.TrimSpace(s.Text())
|
||||||
|
if strings.HasPrefix(ln, "#") || ln == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cidx := strings.Index(ln, "#")
|
||||||
|
if cidx > 0 {
|
||||||
|
ln = ln[:cidx]
|
||||||
|
}
|
||||||
|
ln = strings.TrimSpace(ln)
|
||||||
|
parts := strings.Fields(ln)
|
||||||
|
if len(parts) != 2 && len(parts) != 3 {
|
||||||
|
return nil, fmt.Errorf("invalid config format: %s", ln)
|
||||||
|
}
|
||||||
|
deps = append(deps, dependency{
|
||||||
|
Name: parts[0],
|
||||||
|
Commit: parts[1],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return deps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPreviousDeps(previous string) ([]dependency, error) {
|
||||||
|
r, err := fileFromRev(previous, vendorConf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return parseDependencies(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func changelog(previous, commit string) ([]change, error) {
|
||||||
|
raw, err := getChangelog(previous, commit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return parseChangelog(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getChangelog(previous, commit string) ([]byte, error) {
|
||||||
|
return git("log", "--oneline", fmt.Sprintf("%s..%s", previous, commit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseChangelog(changelog []byte) ([]change, error) {
|
||||||
|
var (
|
||||||
|
changes []change
|
||||||
|
s = bufio.NewScanner(bytes.NewReader(changelog))
|
||||||
|
)
|
||||||
|
for s.Scan() {
|
||||||
|
fields := strings.Fields(s.Text())
|
||||||
|
changes = append(changes, change{
|
||||||
|
Commit: fields[0],
|
||||||
|
Description: strings.Join(fields[1:], " "),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return changes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileFromRev(rev, file string) (io.Reader, error) {
|
||||||
|
p, err := git("show", fmt.Sprintf("%s:%s", rev, file))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.NewReader(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func git(args ...string) ([]byte, error) {
|
||||||
|
o, err := exec.Command("git", args...).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("%s: %s", err, o)
|
||||||
|
}
|
||||||
|
return o, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatedDeps(previous, deps []dependency) []dependency {
|
||||||
|
var updated []dependency
|
||||||
|
pm, cm := toDepMap(previous), toDepMap(deps)
|
||||||
|
for name, c := range cm {
|
||||||
|
d, ok := pm[name]
|
||||||
|
if !ok {
|
||||||
|
// it is a new dep and should be noted
|
||||||
|
updated = append(updated, c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// it exists, see if its updated
|
||||||
|
if d.Commit != c.Commit {
|
||||||
|
// set the previous commit
|
||||||
|
c.Previous = d.Commit
|
||||||
|
updated = append(updated, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updated
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDepMap(deps []dependency) map[string]dependency {
|
||||||
|
out := make(map[string]dependency)
|
||||||
|
for _, d := range deps {
|
||||||
|
out[d.Name] = d
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func getContributors(previous, commit string) ([]string, error) {
|
||||||
|
raw, err := git("log", "--format=%aN", fmt.Sprintf("%s..%s", previous, commit))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
set = make(map[string]struct{})
|
||||||
|
s = bufio.NewScanner(bytes.NewReader(raw))
|
||||||
|
out []string
|
||||||
|
)
|
||||||
|
for s.Scan() {
|
||||||
|
set[s.Text()] = struct{}{}
|
||||||
|
}
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for name := range set {
|
||||||
|
out = append(out, name)
|
||||||
|
}
|
||||||
|
sort.Strings(out)
|
||||||
|
return out, nil
|
||||||
|
}
|
38
releases/v1.0.1.toml
Normal file
38
releases/v1.0.1.toml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# commit to be tagged for new release
|
||||||
|
commit = "HEAD"
|
||||||
|
|
||||||
|
# previous release
|
||||||
|
previous = "v1.0.0"
|
||||||
|
|
||||||
|
pre_release = false
|
||||||
|
|
||||||
|
preface = """\
|
||||||
|
This releases is the first patch release in the v1.0.0 release. It includes
|
||||||
|
bugfixes and performance fixes. No new features have been added."""
|
||||||
|
|
||||||
|
# notable prs to include in the release notes, 1234 is the pr number
|
||||||
|
#[notes]
|
||||||
|
#[notes.gc]
|
||||||
|
#title = "Garbage Collection"
|
||||||
|
#description = """\
|
||||||
|
#Full garbage collection support for cleaning up content, snapshots and metadata
|
||||||
|
#for containerd resources. The implementation is based on well-known concurrent
|
||||||
|
#mark and sweep and the approach allows for extensibility in collection
|
||||||
|
#policies.
|
||||||
|
|
||||||
|
#The GC is triggered `Container.Delete and Image.Delete. Note that images may
|
||||||
|
#need to be re-pulled for proper support."""
|
||||||
|
|
||||||
|
#[notes.migrations]
|
||||||
|
#title = "Migrations"
|
||||||
|
#description = """\
|
||||||
|
#A lightweight migration framework is now part of containerd. This allows us to
|
||||||
|
#safely evolve the schema between releases with the groundwork laid early.
|
||||||
|
|
||||||
|
#As part of this release, a migration will be run to add back references in
|
||||||
|
#support of garbage collection."""
|
||||||
|
|
||||||
|
#[breaking]
|
||||||
|
#[breaking.metrics]
|
||||||
|
#pr = 1235
|
||||||
|
#description = """ """
|
Loading…
Add table
Add a link
Reference in a new issue