add builder

This commit is contained in:
David Dollar 2019-08-21 12:41:07 -04:00
parent c1774a5f27
commit be379ea870
No known key found for this signature in database
GPG Key ID: AFAF263FB45B2124
84 changed files with 2898 additions and 8256 deletions

View File

@ -2,6 +2,9 @@
FROM golang:1.12 AS development
RUN curl -s https://download.docker.com/linux/static/stable/x86_64/docker-18.03.1-ce.tgz | \
tar -C /usr/bin --strip-components 1 -xz
RUN curl -Ls https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl -o /usr/bin/kubectl && \
chmod +x /usr/bin/kubectl

View File

@ -1,6 +1,6 @@
.PHONY: all build clean clean-package compress dev-aws package release test
commands = api atom router
commands = api atom build router
binaries = $(addprefix $(GOPATH)/bin/, $(commands))
sources = $(shell find . -name '*.go')

8
cmd/build/Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM golang:1.11
RUN curl -s https://download.docker.com/linux/static/stable/x86_64/docker-18.03.1-ce.tgz | \
tar -C /usr/bin --strip-components 1 -xz
COPY . $GOPATH/src/github.com/convox/convox
RUN go install github.com/convox/convox/cmd/build

125
cmd/build/main.go Normal file
View File

@ -0,0 +1,125 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/convox/convox/pkg/build"
"github.com/convox/convox/pkg/structs"
"github.com/convox/convox/sdk"
)
var (
flagApp string
flagAuth string
flagCache string
flagDevelopment string
flagEnvWrapper string
flagGeneration string
flagID string
flagManifest string
flagMethod string
flagPush string
flagRack string
flagUrl string
currentBuild *structs.Build
currentLogs string
currentManifest string
rack *sdk.Client
)
func main() {
if err := execute(); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
os.Exit(1)
}
}
func execute() error {
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
fs.StringVar(&flagApp, "app", "example", "app name")
fs.StringVar(&flagAuth, "auth", "", "docker auth data (json)")
fs.StringVar(&flagCache, "cache", "true", "use docker cache")
fs.StringVar(&flagDevelopment, "development", "false", "create a development build")
fs.StringVar(&flagEnvWrapper, "env-wrapper", "false", "wrap with convox-env")
fs.StringVar(&flagGeneration, "generation", "", "app generation")
fs.StringVar(&flagID, "id", "latest", "build id")
fs.StringVar(&flagManifest, "manifest", "", "path to app manifest")
fs.StringVar(&flagMethod, "method", "", "source method")
fs.StringVar(&flagPush, "push", "", "push to registry")
fs.StringVar(&flagRack, "rack", "convox", "rack name")
fs.StringVar(&flagUrl, "url", "", "source url")
if err := fs.Parse(os.Args[1:]); err != nil {
return err
}
if v := os.Getenv("BUILD_APP"); v != "" {
flagApp = v
}
if v := os.Getenv("BUILD_AUTH"); v != "" {
flagAuth = v
}
if v := os.Getenv("BUILD_DEVELOPMENT"); v != "" {
flagDevelopment = v
}
if v := os.Getenv("BUILD_ENV_WRAPPER"); v != "" {
flagEnvWrapper = v
}
if v := os.Getenv("BUILD_GENERATION"); v != "" {
flagGeneration = v
}
if v := os.Getenv("BUILD_ID"); v != "" {
flagID = v
}
if v := os.Getenv("BUILD_MANIFEST"); v != "" {
flagManifest = v
}
if v := os.Getenv("BUILD_PUSH"); v != "" {
flagPush = v
}
if v := os.Getenv("BUILD_RACK"); v != "" {
flagRack = v
}
if v := os.Getenv("BUILD_URL"); v != "" {
flagUrl = v
}
opts := build.Options{
App: flagApp,
Auth: flagAuth,
Cache: flagCache == "true",
Development: flagDevelopment == "true",
EnvWrapper: flagEnvWrapper == "true",
Generation: flagGeneration,
Id: flagID,
Manifest: flagManifest,
Push: flagPush,
Rack: flagRack,
Source: flagUrl,
}
b, err := build.New(opts)
if err != nil {
return err
}
if err := b.Execute(); err != nil {
return err
}
return nil
}

6
go.mod
View File

@ -6,6 +6,7 @@ require (
github.com/Microsoft/hcsshim v0.8.7-0.20190801035247-8694eade7dd3 // indirect
github.com/PuerkitoBio/goquery v1.5.0
github.com/aws/aws-sdk-go v1.21.10
github.com/convox/exec v0.0.0-20180905012044-cc13d277f897
github.com/convox/logger v0.0.0-20180522214415-e39179955b52
github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680
github.com/convox/stdcli v0.0.0-20190326115454-b78bee159e98
@ -14,7 +15,6 @@ require (
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 // indirect
github.com/dustin/go-humanize v1.0.0
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/fsouza/go-dockerclient v1.4.2
github.com/gobuffalo/packr v1.30.1
github.com/gobwas/glob v0.2.3
@ -29,8 +29,6 @@ require (
github.com/imdario/mergo v0.3.7 // indirect
github.com/json-iterator/go v1.1.7 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/miekg/dns v1.1.15
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
@ -43,12 +41,10 @@ require (
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
google.golang.org/appengine v1.4.0 // indirect
gopkg.in/cheggaaa/pb.v1 v1.0.28
gopkg.in/inf.v0 v0.9.0 // indirect
gopkg.in/yaml.v2 v2.2.2
k8s.io/api v0.0.0-20190118113203-912cbe2bfef3
k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841
k8s.io/client-go v0.0.0-20190117233410-4022682532b3
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 // indirect
k8s.io/metrics v0.0.0-20181204004050-3d8dd1c3a53c
)

13
go.sum
View File

@ -35,6 +35,8 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20180920185216-2a805f718635/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/convox/exec v0.0.0-20180905012044-cc13d277f897 h1:8SnSpocZ8I5RlRo8NFKYrAa6pQYZp+4T/pWyD3GrwIk=
github.com/convox/exec v0.0.0-20180905012044-cc13d277f897/go.mod h1:GAxysqvg1ZSl42aLnvLXmFkXkacF4AGql5ZKT7s1DGc=
github.com/convox/logger v0.0.0-20180522214415-e39179955b52 h1:HTaloo6by+4NE1A1mRYprWzsOy1PGH2tPGfgZ60dyHU=
github.com/convox/logger v0.0.0-20180522214415-e39179955b52/go.mod h1:IcbSD+Pq+bQV2z/otiMCHLAYBrDR/jPFopFatrWjlMM=
github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680 h1:IRgaDO4+YanUYcvBlXkzJrgwFh/3BcQOYoI5gEUz2wQ=
@ -372,13 +374,7 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN
github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc=
github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
@ -565,7 +561,6 @@ golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -627,8 +622,6 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@ -657,6 +650,4 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 h1:di3XCwddOR9cWBNpfgXaskhh6cgJuwcK54rvtwUaC10=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/metrics v0.0.0-20181204004050-3d8dd1c3a53c h1:C5pPzP70ZI2ZxBm/5YHVwcIFZzxJ7lhW/5qOXgQIc+E=
k8s.io/metrics v0.0.0-20181204004050-3d8dd1c3a53c/go.mod h1:a25VAbm3QT3xiVl1jtoF1ueAKQM149UdZ+L93ePfV3M=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=

353
pkg/build/build.go Normal file
View File

@ -0,0 +1,353 @@
package build
import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"sort"
// "os/exec"
"path/filepath"
"strings"
"time"
"github.com/convox/convox/pkg/common"
"github.com/convox/convox/pkg/manifest"
"github.com/convox/convox/pkg/options"
"github.com/convox/convox/pkg/structs"
"github.com/convox/convox/sdk"
"github.com/convox/exec"
)
type Options struct {
App string
Auth string
Cache bool
Development bool
EnvWrapper bool
Generation string
Id string
Manifest string
Output io.Writer
Push string
Rack string
Source string
}
type Build struct {
Options
Exec exec.Interface
Provider structs.Provider
logs bytes.Buffer
writer io.Writer
}
func New(opts Options) (*Build, error) {
b := &Build{Options: opts}
b.Exec = &exec.Exec{}
if b.Manifest == "" {
switch b.Generation {
case "2":
b.Manifest = "convox.yml"
default:
b.Manifest = "docker-compose.yml"
}
}
r, err := sdk.NewFromEnv()
if err != nil {
return nil, err
}
b.Provider = r
b.logs = bytes.Buffer{}
if opts.Output != nil {
b.writer = io.MultiWriter(opts.Output, &b.logs)
} else {
b.writer = io.MultiWriter(os.Stdout, &b.logs)
}
return b, nil
}
func (bb *Build) Execute() error {
if err := bb.execute(); err != nil {
return bb.fail(err)
}
return nil
}
func (bb *Build) Printf(format string, args ...interface{}) {
fmt.Fprintf(bb.writer, format, args...)
}
func (bb *Build) execute() error {
if _, err := bb.Provider.BuildGet(bb.App, bb.Id); err != nil {
return err
}
if err := bb.login(); err != nil {
return err
}
dir, err := ioutil.TempDir("", "")
if err != nil {
return err
}
cwd, err := os.Getwd()
if err != nil {
return err
}
if err := os.Chdir(dir); err != nil {
return err
}
defer os.Chdir(cwd)
u, err := url.Parse(bb.Source)
if err != nil {
return err
}
if u.Scheme != "object" {
return fmt.Errorf("only object:// sources are supported")
}
r, err := bb.Provider.ObjectFetch(u.Host, u.Path)
if err != nil {
return err
}
gz, err := gzip.NewReader(r)
if err != nil {
return err
}
if err := common.Unarchive(gz, "."); err != nil {
return err
}
data, err := ioutil.ReadFile(bb.Manifest)
if err != nil {
return err
}
if _, err := bb.Provider.BuildUpdate(bb.App, bb.Id, structs.BuildUpdateOptions{Manifest: options.String(string(data))}); err != nil {
return err
}
switch bb.Generation {
case "2":
if err := bb.buildGeneration2("."); err != nil {
return err
}
default:
return fmt.Errorf("generation 1 is no longer supported")
}
if err := bb.success(); err != nil {
return err
}
return nil
}
func (bb *Build) login() error {
var auth map[string]struct {
Username string
Password string
}
if err := json.Unmarshal([]byte(bb.Auth), &auth); err != nil {
return err
}
for host, entry := range auth {
buf := &bytes.Buffer{}
err := bb.Exec.Stream(buf, strings.NewReader(entry.Password), "docker", "login", "-u", entry.Username, "--password-stdin", host)
bb.Printf("Authenticating %s: %s\n", host, strings.TrimSpace(buf.String()))
if err != nil {
return err
}
}
return nil
}
func (bb *Build) buildGeneration2(dir string) error {
config := filepath.Join(dir, bb.Manifest)
if _, err := os.Stat(config); os.IsNotExist(err) {
return fmt.Errorf("no such file: %s", bb.Manifest)
}
data, err := ioutil.ReadFile(config)
if err != nil {
return err
}
env, err := common.AppEnvironment(bb.Provider, bb.App)
if err != nil {
return err
}
m, err := manifest.Load(data, env)
if err != nil {
return err
}
prefix := fmt.Sprintf("%s/%s", bb.Rack, bb.App)
builds := map[string]manifest.ServiceBuild{}
pulls := map[string]bool{}
pushes := map[string]string{}
tags := map[string][]string{}
for _, s := range m.Services {
hash := s.BuildHash(bb.Id)
to := fmt.Sprintf("%s:%s.%s", prefix, s.Name, bb.Id)
if s.Image != "" {
pulls[s.Image] = true
tags[s.Image] = append(tags[s.Image], to)
} else {
builds[hash] = s.Build
tags[hash] = append(tags[hash], to)
}
if bb.Push != "" {
pushes[to] = fmt.Sprintf("%s:%s.%s", bb.Push, s.Name, bb.Id)
}
}
for hash, b := range builds {
bb.Printf("Building: %s\n", b.Path)
if err := bb.build(filepath.Join(dir, b.Path), b.Manifest, hash, env); err != nil {
return err
}
}
for image := range pulls {
if err := bb.pull(image); err != nil {
return err
}
}
tagfroms := []string{}
for from := range tags {
tagfroms = append(tagfroms, from)
}
sort.Strings(tagfroms)
for _, from := range tagfroms {
tos := tags[from]
for _, to := range tos {
if err := bb.tag(from, to); err != nil {
return err
}
if bb.EnvWrapper {
if err := bb.injectConvoxEnv(to); err != nil {
return err
}
}
}
}
pushfroms := []string{}
for from := range pushes {
pushfroms = append(pushfroms, from)
}
sort.Strings(pushfroms)
for _, from := range pushfroms {
to := pushes[from]
if err := bb.tag(from, to); err != nil {
return err
}
if err := bb.push(to); err != nil {
return err
}
}
return nil
}
func (bb *Build) success() error {
logs, err := bb.Provider.ObjectStore(bb.App, fmt.Sprintf("build/%s/logs", bb.Id), bytes.NewReader(bb.logs.Bytes()), structs.ObjectStoreOptions{})
if err != nil {
return err
}
opts := structs.BuildUpdateOptions{
Ended: options.Time(time.Now().UTC()),
Logs: options.String(logs.Url),
}
if _, err := bb.Provider.BuildUpdate(bb.App, bb.Id, opts); err != nil {
return err
}
r, err := bb.Provider.ReleaseCreate(bb.App, structs.ReleaseCreateOptions{Build: options.String(bb.Id)})
if err != nil {
return err
}
opts = structs.BuildUpdateOptions{
Release: options.String(r.Id),
Status: options.String("complete"),
}
if _, err := bb.Provider.BuildUpdate(bb.App, bb.Id, opts); err != nil {
return err
}
bb.Provider.EventSend("build:create", structs.EventSendOptions{Data: map[string]string{"app": bb.App, "id": bb.Id, "release_id": r.Id}})
return nil
}
func (bb *Build) fail(buildError error) error {
bb.Printf("ERROR: %s\n", buildError)
bb.Provider.EventSend("build:create", structs.EventSendOptions{Data: map[string]string{"app": bb.App, "id": bb.Id}, Error: options.String(buildError.Error())})
logs, err := bb.Provider.ObjectStore(bb.App, fmt.Sprintf("build/%s/logs", bb.Id), bytes.NewReader(bb.logs.Bytes()), structs.ObjectStoreOptions{})
if err != nil {
return err
}
opts := structs.BuildUpdateOptions{
Ended: options.Time(time.Now().UTC()),
Logs: options.String(logs.Url),
Status: options.String("failed"),
}
if _, err := bb.Provider.BuildUpdate(bb.App, bb.Id, opts); err != nil {
return err
}
return buildError
}

388
pkg/build/build_test.go Normal file
View File

@ -0,0 +1,388 @@
package build_test
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"
"testing"
"time"
"github.com/convox/exec"
"github.com/convox/convox/pkg/build"
"github.com/convox/convox/pkg/options"
"github.com/convox/convox/pkg/structs"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestBuildGeneration2(t *testing.T) {
opts := build.Options{
App: "app1",
Auth: "{}",
Cache: true,
Generation: "2",
Id: "build1",
Rack: "rack1",
Source: "object://app1/object.tgz",
}
testBuild(t, opts, func(b *build.Build, p *structs.MockProvider, e *exec.MockInterface, out *bytes.Buffer) {
p.On("BuildGet", "app1", "build1").Return(fxBuildStarted(), nil).Once()
bdata, err := ioutil.ReadFile("testdata/httpd.tgz")
require.NoError(t, err)
p.On("ObjectFetch", "app1", "/object.tgz").Return(ioutil.NopCloser(bytes.NewReader(bdata)), nil)
mdata, err := ioutil.ReadFile("testdata/httpd/convox.yml")
require.NoError(t, err)
p.On("ReleaseList", "app1", structs.ReleaseListOptions{Limit: options.Int(1)}).Return(structs.Releases{*fxRelease()}, nil)
p.On("ReleaseGet", "app1", "release1").Return(fxRelease(), nil)
e.On("Run", mock.Anything, "docker", "build", "-t", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "-f", "Dockerfile", "--network", "host", ".").Return(nil).Run(func(args mock.Arguments) {
fmt.Fprintf(args.Get(0).(io.Writer), "build1\nbuild2\n")
})
e.On("Execute", "docker", "inspect", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "--format", "{{json .Config.Entrypoint}}").Return([]byte("[]"), nil)
e.On("Execute", "docker", "pull", "httpd").Return([]byte("pulling\n"), nil)
e.On("Execute", "docker", "tag", "httpd", "rack1/app1:web.build1").Return([]byte("tagging\n"), nil)
e.On("Execute", "docker", "tag", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "rack1/app1:web2.build1").Return([]byte("tagging\n"), nil)
p.On("ObjectStore", "app1", "build/build1/logs", mock.Anything, structs.ObjectStoreOptions{}).Return(fxObject(), nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(2).(io.Reader))
require.NoError(t, err)
require.Equal(t, "Building: .\nbuild1\nbuild2\nRunning: docker pull httpd\nRunning: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web2.build1\nRunning: docker tag httpd rack1/app1:web.build1\n", string(data))
})
p.On("BuildUpdate", "app1", "build1", mock.Anything).Return(fxBuildStarted(), nil).Run(func(args mock.Arguments) {
opts := args.Get(2).(structs.BuildUpdateOptions)
if opts.Ended != nil {
require.False(t, opts.Ended.IsZero())
}
if opts.Logs != nil {
require.NotNil(t, opts.Logs)
}
if opts.Manifest != nil {
require.Equal(t, string(mdata), *opts.Manifest)
}
})
p.On("ReleaseCreate", "app1", structs.ReleaseCreateOptions{Build: options.String("build1")}).Return(fxRelease2(), nil)
p.On("EventSend", "build:create", structs.EventSendOptions{Data: map[string]string{"app": "app1", "id": "build1", "release_id": "release2"}}).Return(nil)
err = b.Execute()
require.NoError(t, err)
require.Equal(t,
[]string{
"Building: .",
"build1",
"build2",
"Running: docker pull httpd",
"Running: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web2.build1",
"Running: docker tag httpd rack1/app1:web.build1",
},
strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n"),
)
})
}
func TestBuildGeneration2Development(t *testing.T) {
opts := build.Options{
App: "app1",
Auth: "{}",
Cache: true,
Development: true,
Generation: "2",
Id: "build1",
Rack: "rack1",
Source: "object://app1/object.tgz",
}
testBuild(t, opts, func(b *build.Build, p *structs.MockProvider, e *exec.MockInterface, out *bytes.Buffer) {
p.On("BuildGet", "app1", "build1").Return(fxBuildStarted(), nil).Once()
bdata, err := ioutil.ReadFile("testdata/httpd-dev.tgz")
require.NoError(t, err)
p.On("ObjectFetch", "app1", "/object.tgz").Return(ioutil.NopCloser(bytes.NewReader(bdata)), nil)
mdata, err := ioutil.ReadFile("testdata/httpd-dev/convox.yml")
require.NoError(t, err)
p.On("ReleaseList", "app1", structs.ReleaseListOptions{Limit: options.Int(1)}).Return(structs.Releases{*fxRelease()}, nil)
p.On("ReleaseGet", "app1", "release1").Return(fxRelease(), nil)
e.On("Run", mock.Anything, "docker", "build", "-t", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "-f", "Dockerfile", "--network", "host", "--target", "development", ".").Return(nil).Run(func(args mock.Arguments) {
fmt.Fprintf(args.Get(0).(io.Writer), "build1\nbuild2\n")
})
e.On("Execute", "docker", "inspect", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "--format", "{{json .Config.Entrypoint}}").Return([]byte("[]"), nil)
e.On("Execute", "docker", "tag", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "rack1/app1:web.build1").Return([]byte("tagging\n"), nil)
p.On("ObjectStore", "app1", "build/build1/logs", mock.Anything, structs.ObjectStoreOptions{}).Return(fxObject(), nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(2).(io.Reader))
require.NoError(t, err)
require.Equal(t, "Building: .\nbuild1\nbuild2\nRunning: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web.build1\n", string(data))
})
p.On("BuildUpdate", "app1", "build1", mock.Anything).Return(fxBuildStarted(), nil).Run(func(args mock.Arguments) {
opts := args.Get(2).(structs.BuildUpdateOptions)
if opts.Ended != nil {
require.False(t, opts.Ended.IsZero())
}
if opts.Logs != nil {
require.NotNil(t, opts.Logs)
}
if opts.Manifest != nil {
require.Equal(t, string(mdata), *opts.Manifest)
}
})
p.On("ReleaseCreate", "app1", structs.ReleaseCreateOptions{Build: options.String("build1")}).Return(fxRelease2(), nil)
p.On("EventSend", "build:create", structs.EventSendOptions{Data: map[string]string{"app": "app1", "id": "build1", "release_id": "release2"}}).Return(nil)
err = b.Execute()
require.NoError(t, err)
require.Equal(t,
[]string{
"Building: .",
"build1",
"build2",
"Running: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web.build1",
},
strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n"),
)
})
}
func TestBuildGeneration2Entrypoint(t *testing.T) {
opts := build.Options{
App: "app1",
Auth: "{}",
Cache: true,
Generation: "2",
Id: "build1",
Rack: "rack1",
Source: "object://app1/object.tgz",
}
testBuild(t, opts, func(b *build.Build, p *structs.MockProvider, e *exec.MockInterface, out *bytes.Buffer) {
p.On("BuildGet", "app1", "build1").Return(fxBuildStarted(), nil).Once()
bdata, err := ioutil.ReadFile("testdata/httpd.tgz")
require.NoError(t, err)
p.On("ObjectFetch", "app1", "/object.tgz").Return(ioutil.NopCloser(bytes.NewReader(bdata)), nil)
mdata, err := ioutil.ReadFile("testdata/httpd/convox.yml")
require.NoError(t, err)
p.On("ReleaseList", "app1", structs.ReleaseListOptions{Limit: options.Int(1)}).Return(structs.Releases{*fxRelease()}, nil)
p.On("ReleaseGet", "app1", "release1").Return(fxRelease(), nil)
e.On("Run", mock.Anything, "docker", "build", "-t", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "-f", "Dockerfile", "--network", "host", ".").Return(nil).Run(func(args mock.Arguments) {
fmt.Fprintf(args.Get(0).(io.Writer), "build1\nbuild2\n")
})
e.On("Execute", "docker", "inspect", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "--format", "{{json .Config.Entrypoint}}").Return([]byte("[\"bin/entry\"]"), nil)
e.On("Execute", "docker", "pull", "httpd").Return([]byte("pulling\n"), nil)
e.On("Execute", "docker", "tag", "httpd", "rack1/app1:web.build1").Return([]byte("tagging\n"), nil)
e.On("Execute", "docker", "tag", "049f26f1b03bfca2e3af367d481a7bf1a94564ba", "rack1/app1:web2.build1").Return([]byte("tagging\n"), nil)
p.On("ObjectStore", "app1", "build/build1/logs", mock.Anything, structs.ObjectStoreOptions{}).Return(fxObject(), nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(2).(io.Reader))
require.NoError(t, err)
require.Equal(t, "Building: .\nbuild1\nbuild2\nRunning: docker pull httpd\nRunning: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web2.build1\nRunning: docker tag httpd rack1/app1:web.build1\n", string(data))
})
p.On("BuildUpdate", "app1", "build1", structs.BuildUpdateOptions{Entrypoint: options.String("bin/entry")}).Return(fxBuildStarted(), nil)
p.On("BuildUpdate", "app1", "build1", mock.Anything).Return(fxBuildStarted(), nil).Run(func(args mock.Arguments) {
opts := args.Get(2).(structs.BuildUpdateOptions)
if opts.Ended != nil {
require.False(t, opts.Ended.IsZero())
}
if opts.Logs != nil {
require.NotNil(t, opts.Logs)
}
if opts.Manifest != nil {
require.Equal(t, string(mdata), *opts.Manifest)
}
})
p.On("ReleaseCreate", "app1", structs.ReleaseCreateOptions{Build: options.String("build1")}).Return(fxRelease2(), nil)
p.On("EventSend", "build:create", structs.EventSendOptions{Data: map[string]string{"app": "app1", "id": "build1", "release_id": "release2"}}).Return(nil)
err = b.Execute()
require.NoError(t, err)
require.Equal(t,
[]string{
"Building: .",
"build1",
"build2",
"Running: docker pull httpd",
"Running: docker tag 049f26f1b03bfca2e3af367d481a7bf1a94564ba rack1/app1:web2.build1",
"Running: docker tag httpd rack1/app1:web.build1",
},
strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n"),
)
})
}
func TestBuildGeneration2Failure(t *testing.T) {
opts := build.Options{
App: "app1",
Auth: "{}",
Cache: true,
Generation: "2",
Id: "build1",
Rack: "rack1",
Source: "object://app1/object.tgz",
}
testBuild(t, opts, func(b *build.Build, p *structs.MockProvider, e *exec.MockInterface, out *bytes.Buffer) {
p.On("BuildGet", "app1", "build1").Return(fxBuildStarted(), nil)
p.On("ObjectFetch", "app1", "/object.tgz").Return(nil, fmt.Errorf("err1"))
p.On("ObjectStore", "app1", "build/build1/logs", mock.Anything, structs.ObjectStoreOptions{}).Return(fxObject(), nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(2).(io.Reader))
require.NoError(t, err)
require.Equal(t, "ERROR: err1\n", string(data))
})
p.On("BuildUpdate", "app1", "build1", mock.Anything).Return(fxBuildStarted(), nil).Run(func(args mock.Arguments) {
opts := args.Get(2).(structs.BuildUpdateOptions)
require.NotNil(t, opts.Ended)
require.False(t, opts.Ended.IsZero())
require.NotNil(t, opts.Logs)
require.Equal(t, "object://app1/build/build1/logs", *opts.Logs)
require.NotNil(t, opts.Status)
require.Equal(t, "failed", *opts.Status)
})
p.On("EventSend", "build:create", structs.EventSendOptions{Data: map[string]string{"app": "app1", "id": "build1"}, Error: options.String("err1")}).Return(nil)
err := b.Execute()
require.EqualError(t, err, "err1")
require.Equal(t,
[]string{
"ERROR: err1",
},
strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n"),
)
})
}
func TestBuildGeneration2Options(t *testing.T) {
opts := build.Options{
App: "app1",
Auth: `{"host1":{"username":"user1","password":"pass1"}}`,
Cache: false,
Development: true,
EnvWrapper: true,
Generation: "2",
Id: "build1",
Manifest: "convox2.yml",
Push: "push1",
Rack: "rack1",
Source: "object://app1/object.tgz",
}
testBuild(t, opts, func(b *build.Build, p *structs.MockProvider, e *exec.MockInterface, out *bytes.Buffer) {
p.On("BuildGet", "app1", "build1").Return(fxBuildStarted(), nil).Once()
e.On("Stream", mock.Anything, mock.Anything, "docker", "login", "-u", "user1", "--password-stdin", "host1").Return(nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(1).(io.Reader))
require.NoError(t, err)
require.Equal(t, "pass1", string(data))
fmt.Fprintf(args.Get(0).(io.Writer), "login-success\n")
})
bdata, err := ioutil.ReadFile("testdata/httpd.tgz")
require.NoError(t, err)
p.On("ObjectFetch", "app1", "/object.tgz").Return(ioutil.NopCloser(bytes.NewReader(bdata)), nil)
mdata, err := ioutil.ReadFile("testdata/httpd/convox2.yml")
require.NoError(t, err)
// p.On("BuildUpdate", "app1", "build1", structs.BuildUpdateOptions{Manifest: options.String(string(mdata))}).Return(fxBuildStarted(), nil).Once()
p.On("ReleaseList", "app1", structs.ReleaseListOptions{Limit: options.Int(1)}).Return(structs.Releases{*fxRelease()}, nil)
p.On("ReleaseGet", "app1", "release1").Return(fxRelease(), nil)
e.On("Run", mock.Anything, "docker", "build", "--no-cache", "-t", "63b602b07e75429dbf1ab14132f20c9e5a649f2f", "-f", "Dockerfile2", "--network", "host", "--build-arg", "FOO=bar", ".").Return(nil).Run(func(args mock.Arguments) {
fmt.Fprintf(args.Get(0).(io.Writer), "build1\nbuild2\n")
})
e.On("Execute", "docker", "inspect", "63b602b07e75429dbf1ab14132f20c9e5a649f2f", "--format", "{{json .Config.Entrypoint}}").Return([]byte("[]"), nil)
e.On("Execute", "docker", "tag", "63b602b07e75429dbf1ab14132f20c9e5a649f2f", "rack1/app1:web.build1").Return([]byte("tagging\n"), nil)
e.On("Execute", "docker", "tag", "rack1/app1:web.build1", "push1:web.build1").Return([]byte("tagging\n"), nil)
e.On("Execute", "docker", "inspect", "rack1/app1:web.build1", "--format", "{{json .Config.Cmd}}").Return([]byte(`["command2"]`), nil)
e.On("Execute", "docker", "inspect", "rack1/app1:web.build1", "--format", "{{json .Config.Entrypoint}}").Return([]byte(`["entrypoint2"]`), nil)
e.On("Execute", "cp", "/go/bin/convox-env", mock.AnythingOfType("string")).Return([]byte("copying\n"), nil)
e.On("Execute", "docker", "build", "-t", "rack1/app1:web.build1", mock.AnythingOfType("string")).Return([]byte("building convox-env\n"), nil)
e.On("Execute", "docker", "push", "push1:web.build1").Return([]byte("pushing\n"), nil)
p.On("ObjectStore", "app1", "build/build1/logs", mock.Anything, structs.ObjectStoreOptions{}).Return(fxObject(), nil).Run(func(args mock.Arguments) {
data, err := ioutil.ReadAll(args.Get(2).(io.Reader))
require.NoError(t, err)
require.Equal(t, "Authenticating host1: login-success\nBuilding: .\nbuild1\nbuild2\nRunning: docker tag 63b602b07e75429dbf1ab14132f20c9e5a649f2f rack1/app1:web.build1\nInjecting: convox-env\nRunning: docker tag rack1/app1:web.build1 push1:web.build1\nRunning: docker push push1:web.build1\n", string(data))
})
p.On("BuildUpdate", "app1", "build1", mock.Anything).Return(fxBuildStarted(), nil).Run(func(args mock.Arguments) {
opts := args.Get(2).(structs.BuildUpdateOptions)
if opts.Ended != nil {
require.False(t, opts.Ended.IsZero())
}
if opts.Logs != nil {
require.NotNil(t, opts.Logs)
}
if opts.Manifest != nil {
require.Equal(t, string(mdata), *opts.Manifest)
}
})
p.On("ReleaseCreate", "app1", structs.ReleaseCreateOptions{Build: options.String("build1")}).Return(fxRelease2(), nil)
p.On("EventSend", "build:create", structs.EventSendOptions{Data: map[string]string{"app": "app1", "id": "build1", "release_id": "release2"}}).Return(nil)
err = b.Execute()
require.NoError(t, err)
require.Equal(t,
[]string{
"Authenticating host1: login-success",
"Building: .",
"build1",
"build2",
"Running: docker tag 63b602b07e75429dbf1ab14132f20c9e5a649f2f rack1/app1:web.build1",
"Injecting: convox-env",
"Running: docker tag rack1/app1:web.build1 push1:web.build1",
"Running: docker push push1:web.build1",
},
strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n"),
)
})
}
func fxBuildStarted() *structs.Build {
return &structs.Build{
Id: "build1",
Description: "desc",
Started: time.Now().UTC(),
Status: "started",
}
}
func fxObject() *structs.Object {
return &structs.Object{
Url: "object://app1/build/build1/logs",
}
}
func fxRelease() *structs.Release {
return &structs.Release{
Id: "release1",
App: "app1",
Build: "build1",
Env: "FOO=bar\nBAZ=quux",
Manifest: "services:\n web:\n build: .",
Created: time.Now().UTC().Add(-49 * time.Hour),
}
}
func fxRelease2() *structs.Release {
return &structs.Release{
Id: "release2",
App: "app1",
Build: "build1",
Env: "FOO=bar\nBAZ=quux",
Manifest: "manifest",
Created: time.Now().UTC().Add(-49 * time.Hour),
}
}
func testBuild(t *testing.T, opts build.Options, fn func(*build.Build, *structs.MockProvider, *exec.MockInterface, *bytes.Buffer)) {
e := &exec.MockInterface{}
p := &structs.MockProvider{}
buf := &bytes.Buffer{}
opts.Output = buf
b, err := build.New(opts)
require.NoError(t, err)
b.Exec = e
b.Provider = p
fn(b, p, e, buf)
e.AssertExpectations(t)
p.AssertExpectations(t)
}

200
pkg/build/docker.go Normal file
View File

@ -0,0 +1,200 @@
package build
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/convox/convox/pkg/options"
"github.com/convox/convox/pkg/structs"
shellquote "github.com/kballard/go-shellquote"
)
func (bb *Build) build(path, dockerfile string, tag string, env map[string]string) error {
if path == "" {
return fmt.Errorf("must have path to build")
}
df := filepath.Join(path, dockerfile)
args := []string{"build"}
if !bb.Cache {
args = append(args, "--no-cache")
}
args = append(args, "-t", tag)
args = append(args, "-f", df)
args = append(args, "--network", "host")
ba, err := bb.buildArgs(df, env)
if err != nil {
return err
}
args = append(args, ba...)
args = append(args, path)
if err := bb.Exec.Run(bb.writer, "docker", args...); err != nil {
return err
}
data, err := bb.Exec.Execute("docker", "inspect", tag, "--format", "{{json .Config.Entrypoint}}")
if err != nil {
return err
}
var ep []string
if err := json.Unmarshal(data, &ep); err != nil {
return err
}
if ep != nil {
opts := structs.BuildUpdateOptions{
Entrypoint: options.String(shellquote.Join(ep...)),
}
if _, err := bb.Provider.BuildUpdate(bb.App, bb.Id, opts); err != nil {
return err
}
}
return nil
}
func (bb *Build) buildArgs(dockerfile string, env map[string]string) ([]string, error) {
fd, err := os.Open(dockerfile)
if err != nil {
return nil, err
}
defer fd.Close()
s := bufio.NewScanner(fd)
args := []string{}
for s.Scan() {
fields := strings.Fields(strings.TrimSpace(s.Text()))
if len(fields) < 2 {
continue
}
parts := strings.Split(fields[1], "=")
switch fields[0] {
case "FROM":
if bb.Development && strings.Contains(strings.ToLower(s.Text()), "as development") {
args = append(args, "--target", "development")
}
case "ARG":
k := strings.TrimSpace(parts[0])
if v, ok := env[k]; ok {
args = append(args, "--build-arg", fmt.Sprintf("%s=%s", k, v))
}
}
}
return args, nil
}
func (bb *Build) injectConvoxEnv(tag string) error {
fmt.Fprintf(bb.writer, "Injecting: convox-env\n")
var cmd []string
var entrypoint []string
data, err := bb.Exec.Execute("docker", "inspect", tag, "--format", "{{json .Config.Cmd}}")
if err != nil {
return err
}
if err := json.Unmarshal(data, &cmd); err != nil {
return err
}
data, err = bb.Exec.Execute("docker", "inspect", tag, "--format", "{{json .Config.Entrypoint}}")
if err != nil {
return err
}
if err := json.Unmarshal(data, &entrypoint); err != nil {
return err
}
epb, err := json.Marshal(append([]string{"/convox-env"}, entrypoint...))
if err != nil {
return err
}
epdfs := fmt.Sprintf("FROM %s\nCOPY ./convox-env /convox-env\nENTRYPOINT %s\n", tag, epb)
if cmd != nil {
cmdb, err := json.Marshal(cmd)
if err != nil {
return err
}
epdfs += fmt.Sprintf("CMD %s\n", cmdb)
}
tmp, err := ioutil.TempDir("", "")
if err != nil {
return err
}
if _, err := bb.Exec.Execute("cp", "/go/bin/convox-env", filepath.Join(tmp, "convox-env")); err != nil {
return err
}
epdf := filepath.Join(tmp, "Dockerfile")
if err := ioutil.WriteFile(epdf, []byte(epdfs), 0644); err != nil {
return err
}
data, err = bb.Exec.Execute("docker", "build", "-t", tag, tmp)
if err != nil {
return err
}
return nil
}
func (bb *Build) pull(tag string) error {
fmt.Fprintf(bb.writer, "Running: docker pull %s\n", tag)
data, err := bb.Exec.Execute("docker", "pull", tag)
if err != nil {
return errors.New(strings.TrimSpace(string(data)))
}
return nil
}
func (bb *Build) push(tag string) error {
fmt.Fprintf(bb.writer, "Running: docker push %s\n", tag)
data, err := bb.Exec.Execute("docker", "push", tag)
if err != nil {
return errors.New(strings.TrimSpace(string(data)))
}
return nil
}
func (bb *Build) tag(from, to string) error {
fmt.Fprintf(bb.writer, "Running: docker tag %s %s\n", from, to)
data, err := bb.Exec.Execute("docker", "tag", from, to)
if err != nil {
return errors.New(strings.TrimSpace(string(data)))
}
return nil
}

BIN
pkg/build/testdata/httpd-dev.tgz vendored Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
FROM httpd AS development

View File

@ -0,0 +1,3 @@
services:
web:
build: .

BIN
pkg/build/testdata/httpd.tgz vendored Normal file

Binary file not shown.

1
pkg/build/testdata/httpd/Dockerfile vendored Normal file
View File

@ -0,0 +1 @@
FROM httpd

3
pkg/build/testdata/httpd/Dockerfile2 vendored Normal file
View File

@ -0,0 +1,3 @@
FROM httpd
ARG FOO=qux

6
pkg/build/testdata/httpd/convox.yml vendored Normal file
View File

@ -0,0 +1,6 @@
services:
web:
image: httpd
port: 80
web2:
build: .

6
pkg/build/testdata/httpd/convox2.yml vendored Normal file
View File

@ -0,0 +1,6 @@
services:
web:
build:
path: .
manifest: Dockerfile2
port: 80

31
sdk/auth.go Normal file
View File

@ -0,0 +1,31 @@
package sdk
import (
"encoding/json"
"io/ioutil"
"github.com/convox/stdsdk"
)
func (c *Client) Auth() (string, error) {
res, err := c.GetStream("/auth", stdsdk.RequestOptions{})
if err != nil {
return "", err
}
defer res.Body.Close()
var auth struct {
Id string
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", err
}
if err := json.Unmarshal(data, &auth); err == nil {
return auth.Id, nil
}
return "", nil
}

469
sdk/compat.go Normal file
View File

@ -0,0 +1,469 @@
package sdk
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"math/rand"
"strconv"
"github.com/convox/convox/pkg/structs"
"github.com/convox/stdsdk"
)
func (c *Client) AppParametersGet(name string) (map[string]string, error) {
var params map[string]string
if err := c.Get(fmt.Sprintf("/apps/%s/parameters", name), stdsdk.RequestOptions{}, &params); err != nil {
return nil, err
}
return params, nil
}
func (c *Client) AppParametersSet(name string, params map[string]string) error {
ro := stdsdk.RequestOptions{
Params: stdsdk.Params{},
}
for k, v := range params {
ro.Params[k] = v
}
if err := c.Post(fmt.Sprintf("/apps/%s/parameters", name), ro, nil); err != nil {
return err
}
return nil
}
func (c *Client) BuildCreateUpload(app string, r io.Reader, opts structs.BuildCreateOptions) (*structs.Build, error) {
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["cache"] = fmt.Sprintf("%t", (opts.NoCache == nil || !*opts.NoCache))
if ro.Params["manifest"] != nil {
ro.Params["config"] = ro.Params["manifest"]
}
data, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
ro.Files = stdsdk.Files{"source": data}
var b *structs.Build
if err := c.Post(fmt.Sprintf("/apps/%s/builds", app), ro, &b); err != nil {
return nil, err
}
return b, nil
}
func (c *Client) BuildImportMultipart(app string, r io.Reader) (*structs.Build, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
ro := stdsdk.RequestOptions{
Files: stdsdk.Files{
"image": data,
},
}
var b *structs.Build
if err := c.Post(fmt.Sprintf("/apps/%s/builds", app), ro, &b); err != nil {
return nil, err
}
return b, nil
}
func (c *Client) BuildImportUrl(app string, r io.Reader) (*structs.Build, error) {
o, err := c.ObjectStore(app, "", r, structs.ObjectStoreOptions{})
if err != nil {
return nil, err
}
ro := stdsdk.RequestOptions{
Params: stdsdk.Params{
"url": o.Url,
},
}
var b *structs.Build
if err := c.Post(fmt.Sprintf("/apps/%s/builds/import", app), ro, &b); err != nil {
return nil, err
}
return b, nil
}
func (c *Client) CertificateCreateClassic(pub string, key string, opts structs.CertificateCreateOptions) (*structs.Certificate, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["public"] = pub
ro.Params["private"] = key
var v *structs.Certificate
err = c.Post(fmt.Sprintf("/certificates"), ro, &v)
return v, err
}
func (c *Client) EnvironmentSet(app string, env []byte) (*structs.Release, error) {
req, err := c.Request("POST", fmt.Sprintf("/apps/%s/environment", app), stdsdk.RequestOptions{Body: bytes.NewReader(env)})
if err != nil {
return nil, err
}
res, err := c.HandleRequest(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
id := res.Header.Get("Release-Id")
r, err := c.ReleaseGet(app, id)
if err != nil {
return nil, err
}
return r, nil
}
func (c *Client) EnvironmentUnset(app string, key string) (*structs.Release, error) {
req, err := c.Request("DELETE", fmt.Sprintf("/apps/%s/environment/%s", app, key), stdsdk.RequestOptions{})
if err != nil {
return nil, err
}
res, err := c.HandleRequest(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
id := res.Header.Get("Release-Id")
r, err := c.ReleaseGet(app, id)
if err != nil {
return nil, err
}
return r, nil
}
func (c *Client) FormationGet(app string) (structs.Services, error) {
var fs []struct {
Balancer string
Count int
Cpu int
Hostname string
Memory int
Name string
Ports []int
}
if err := c.Get(fmt.Sprintf("/apps/%s/formation", app), stdsdk.RequestOptions{}, &fs); err != nil {
return nil, err
}
ss := structs.Services{}
for _, f := range fs {
var ssls []struct {
Certificate string
Process string
Port int
}
if err := c.Get(fmt.Sprintf("/apps/%s/ssl", app), stdsdk.RequestOptions{}, &ssls); err != nil {
return nil, err
}
s := structs.Service{
Count: f.Count,
Cpu: f.Cpu,
Domain: coalesce(f.Balancer, f.Hostname),
Memory: f.Memory,
Name: f.Name,
Ports: []structs.ServicePort{},
}
for _, p := range f.Ports {
cert := ""
for _, ssl := range ssls {
if ssl.Process == s.Name && ssl.Port == p {
cert = ssl.Certificate
break
}
}
s.Ports = append(s.Ports, structs.ServicePort{Balancer: p, Certificate: cert})
}
ss = append(ss, s)
}
return ss, nil
}
func (c *Client) FormationUpdate(app string, service string, opts structs.ServiceUpdateOptions) error {
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
if err := c.Post(fmt.Sprintf("/apps/%s/formation/%s", app, service), ro, nil); err != nil {
return err
}
return nil
}
func (c *Client) InstanceShellClassic(id string, rw io.ReadWriter, opts structs.InstanceShellOptions) (int, error) {
var err error
// bug in old rack switched these
opts.Height, opts.Width = opts.Width, opts.Height
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return 0, err
}
ro.Headers["Terminal"] = "xterm"
ro.Body = rw
var v int
v, err = c.WebsocketExit(fmt.Sprintf("/instances/%s/ssh", id), ro, rw)
if err != nil {
return 0, err
}
return v, err
}
func (c *Client) ProcessRunAttached(app, service string, rw io.ReadWriter, timeout int, opts structs.ProcessRunOptions) (int, error) {
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return 0, err
}
ro.Headers["Timeout"] = strconv.Itoa(timeout)
ro.Body = rw
code, err := c.WebsocketExit(fmt.Sprintf("/apps/%s/processes/%s/run", app, service), ro, rw)
if err != nil {
return 0, err
}
return code, nil
}
func (c *Client) ProcessRunDetached(app, service string, opts structs.ProcessRunOptions) (string, error) {
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return "", err
}
var ret struct {
Pid string
}
ro.Params["command"] = ro.Headers["Command"]
ro.Params["release"] = ro.Headers["Release"]
if err := c.Post(fmt.Sprintf("/apps/%s/processes/%s/run", app, service), ro, &ret); err != nil {
return "", err
}
return ret.Pid, nil
}
func (c *Client) RegistryRemoveClassic(server string) error {
ro := stdsdk.RequestOptions{
Query: stdsdk.Query{
"server": server,
},
}
if err := c.Delete("/registries", ro, nil); err != nil {
return err
}
return nil
}
func (c *Client) ResourceCreateClassic(kind string, opts structs.ResourceCreateOptions) (*structs.Resource, error) {
ro := stdsdk.RequestOptions{
Params: stdsdk.Params{
"type": kind,
},
}
if opts.Name != nil {
ro.Params["name"] = *opts.Name
} else {
ro.Params["name"] = fmt.Sprintf("%s-%d", kind, (rand.Intn(8999) + 1000))
}
if opts.Parameters != nil {
for k, v := range opts.Parameters {
ro.Params[k] = v
}
}
var r *structs.Resource
if err := c.Post("/resources", ro, &r); err != nil {
return nil, err
}
return r, nil
}
func (c *Client) ResourceUpdateClassic(name string, opts structs.ResourceUpdateOptions) (*structs.Resource, error) {
ro := stdsdk.RequestOptions{
Params: stdsdk.Params{},
}
if opts.Parameters != nil {
for k, v := range opts.Parameters {
ro.Params[k] = v
}
}
var r *structs.Resource
if err := c.Put(fmt.Sprintf("/resources/%s", name), ro, &r); err != nil {
return nil, err
}
return r, nil
}
func (c *Client) SystemResourceCreateClassic(kind string, opts structs.ResourceCreateOptions) (*structs.Resource, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["kind"] = kind
var v *structs.Resource
err = c.Post(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceDeleteClassic(name string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/resources/%s", name), ro, nil)
return err
}
func (c *Client) SystemResourceGetClassic(name string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Resource
err = c.Get(fmt.Sprintf("/resources/%s", name), ro, &v)
return v, err
}
func (c *Client) SystemResourceLinkClassic(name string, app string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Params["app"] = app
var v *structs.Resource
err = c.Post(fmt.Sprintf("/resources/%s/links", name), ro, &v)
return v, err
}
func (c *Client) SystemResourceListClassic() (structs.Resources, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Resources
err = c.Get(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceTypesClassic() (structs.ResourceTypes, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.ResourceTypes
err = c.Options(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceUnlinkClassic(name string, app string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Resource
err = c.Delete(fmt.Sprintf("/resources/%s/links/%s", name, app), ro, &v)
return v, err
}
func (c *Client) SystemResourceUpdateClassic(name string, opts structs.ResourceUpdateOptions) (*structs.Resource, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v *structs.Resource
err = c.Put(fmt.Sprintf("/resources/%s", name), ro, &v)
return v, err
}

11
sdk/helpers.go Normal file
View File

@ -0,0 +1,11 @@
package sdk
func coalesce(strings ...string) string {
for _, s := range strings {
if s != "" {
return s
}
}
return ""
}

41
sdk/interface.go Normal file
View File

@ -0,0 +1,41 @@
package sdk
import (
"io"
"github.com/convox/convox/pkg/structs"
"github.com/convox/stdsdk"
)
type Interface interface {
structs.Provider
// raw http
Get(string, stdsdk.RequestOptions, interface{}) error
// backwards compatibility
AppParametersGet(string) (map[string]string, error)
AppParametersSet(string, map[string]string) error
BuildCreateUpload(string, io.Reader, structs.BuildCreateOptions) (*structs.Build, error)
BuildImportMultipart(string, io.Reader) (*structs.Build, error)
BuildImportUrl(string, io.Reader) (*structs.Build, error)
CertificateCreateClassic(string, string, structs.CertificateCreateOptions) (*structs.Certificate, error)
EnvironmentSet(string, []byte) (*structs.Release, error)
EnvironmentUnset(string, string) (*structs.Release, error)
FormationGet(string) (structs.Services, error)
FormationUpdate(string, string, structs.ServiceUpdateOptions) error
InstanceShellClassic(string, io.ReadWriter, structs.InstanceShellOptions) (int, error)
ProcessRunAttached(string, string, io.ReadWriter, int, structs.ProcessRunOptions) (int, error)
ProcessRunDetached(string, string, structs.ProcessRunOptions) (string, error)
RegistryRemoveClassic(string) error
ResourceCreateClassic(string, structs.ResourceCreateOptions) (*structs.Resource, error)
ResourceUpdateClassic(string, structs.ResourceUpdateOptions) (*structs.Resource, error)
SystemResourceCreateClassic(string, structs.ResourceCreateOptions) (*structs.Resource, error)
SystemResourceDeleteClassic(string) error
SystemResourceGetClassic(string) (*structs.Resource, error)
SystemResourceLinkClassic(string, string) (*structs.Resource, error)
SystemResourceListClassic() (structs.Resources, error)
SystemResourceTypesClassic() (structs.ResourceTypes, error)
SystemResourceUnlinkClassic(string, string) (*structs.Resource, error)
SystemResourceUpdateClassic(string, structs.ResourceUpdateOptions) (*structs.Resource, error)
}

958
sdk/methods.go Normal file
View File

@ -0,0 +1,958 @@
package sdk
import (
"fmt"
"io"
"strings"
"github.com/convox/convox/pkg/structs"
"github.com/convox/stdsdk"
)
func (c *Client) AppCancel(name string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Post(fmt.Sprintf("/apps/%s/cancel", name), ro, nil)
return err
}
func (c *Client) AppCreate(name string, opts structs.AppCreateOptions) (*structs.App, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["name"] = name
var v *structs.App
err = c.Post(fmt.Sprintf("/apps"), ro, &v)
return v, err
}
func (c *Client) AppDelete(name string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/apps/%s", name), ro, nil)
return err
}
func (c *Client) AppGet(name string) (*structs.App, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.App
err = c.Get(fmt.Sprintf("/apps/%s", name), ro, &v)
return v, err
}
func (c *Client) AppList() (structs.Apps, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Apps
err = c.Get(fmt.Sprintf("/apps"), ro, &v)
return v, err
}
func (c *Client) AppLogs(name string, opts structs.LogsOptions) (io.ReadCloser, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v io.ReadCloser
r, err := c.Websocket(fmt.Sprintf("/apps/%s/logs", name), ro)
if err != nil {
return nil, err
}
v = r
return v, err
}
func (c *Client) AppMetrics(name string, opts structs.MetricsOptions) (structs.Metrics, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Metrics
err = c.Get(fmt.Sprintf("/apps/%s/metrics", name), ro, &v)
return v, err
}
func (c *Client) AppUpdate(name string, opts structs.AppUpdateOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
err = c.Put(fmt.Sprintf("/apps/%s", name), ro, nil)
return err
}
func (c *Client) BuildCreate(app string, url string, opts structs.BuildCreateOptions) (*structs.Build, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["url"] = url
var v *structs.Build
err = c.Post(fmt.Sprintf("/apps/%s/builds", app), ro, &v)
return v, err
}
func (c *Client) BuildExport(app string, id string, w io.Writer) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
res, err := c.GetStream(fmt.Sprintf("/apps/%s/builds/%s.tgz", app, id), ro)
if err != nil {
return err
}
defer res.Body.Close()
if _, err := io.Copy(w, res.Body); err != nil {
return err
}
return err
}
func (c *Client) BuildGet(app string, id string) (*structs.Build, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Build
err = c.Get(fmt.Sprintf("/apps/%s/builds/%s", app, id), ro, &v)
return v, err
}
func (c *Client) BuildImport(app string, r io.Reader) (*structs.Build, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Body = r
var v *structs.Build
err = c.Post(fmt.Sprintf("/apps/%s/builds/import", app), ro, &v)
return v, err
}
func (c *Client) BuildList(app string, opts structs.BuildListOptions) (structs.Builds, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Builds
err = c.Get(fmt.Sprintf("/apps/%s/builds", app), ro, &v)
return v, err
}
func (c *Client) BuildLogs(app string, id string, opts structs.LogsOptions) (io.ReadCloser, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v io.ReadCloser
r, err := c.Websocket(fmt.Sprintf("/apps/%s/builds/%s/logs", app, id), ro)
if err != nil {
return nil, err
}
v = r
return v, err
}
func (c *Client) BuildUpdate(app string, id string, opts structs.BuildUpdateOptions) (*structs.Build, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v *structs.Build
err = c.Put(fmt.Sprintf("/apps/%s/builds/%s", app, id), ro, &v)
return v, err
}
func (c *Client) CapacityGet() (*structs.Capacity, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Capacity
err = c.Get(fmt.Sprintf("/system/capacity"), ro, &v)
return v, err
}
func (c *Client) CertificateApply(app string, service string, port int, id string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Params["id"] = id
err = c.Put(fmt.Sprintf("/apps/%s/ssl/%s/%d", app, service, port), ro, nil)
return err
}
func (c *Client) CertificateCreate(pub string, key string, opts structs.CertificateCreateOptions) (*structs.Certificate, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["pub"] = pub
ro.Params["key"] = key
var v *structs.Certificate
err = c.Post(fmt.Sprintf("/certificates"), ro, &v)
return v, err
}
func (c *Client) CertificateDelete(id string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/certificates/%s", id), ro, nil)
return err
}
func (c *Client) CertificateGenerate(domains []string) (*structs.Certificate, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Params["domains"] = strings.Join(domains, ",")
var v *structs.Certificate
err = c.Post(fmt.Sprintf("/certificates/generate"), ro, &v)
return v, err
}
func (c *Client) CertificateList() (structs.Certificates, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Certificates
err = c.Get(fmt.Sprintf("/certificates"), ro, &v)
return v, err
}
func (c *Client) EventSend(action string, opts structs.EventSendOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
ro.Params["action"] = action
err = c.Post(fmt.Sprintf("/events"), ro, nil)
return err
}
func (c *Client) FilesDelete(app string, pid string, files []string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Query["files"] = strings.Join(files, ",")
err = c.Delete(fmt.Sprintf("/apps/%s/processes/%s/files", app, pid), ro, nil)
return err
}
func (c *Client) FilesDownload(app string, pid string, file string) (io.Reader, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Query["file"] = file
var v io.Reader
res, err := c.GetStream(fmt.Sprintf("/apps/%s/processes/%s/files", app, pid), ro)
if err != nil {
return nil, err
}
v = res.Body
return v, err
}
func (c *Client) FilesUpload(app string, pid string, r io.Reader) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Body = r
err = c.Post(fmt.Sprintf("/apps/%s/processes/%s/files", app, pid), ro, nil)
return err
}
func (c *Client) Initialize(opts structs.ProviderOptions) error {
err := fmt.Errorf("not available via api")
return err
}
func (c *Client) InstanceKeyroll() error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Post(fmt.Sprintf("/instances/keyroll"), ro, nil)
return err
}
func (c *Client) InstanceList() (structs.Instances, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Instances
err = c.Get(fmt.Sprintf("/instances"), ro, &v)
return v, err
}
func (c *Client) InstanceShell(id string, rw io.ReadWriter, opts structs.InstanceShellOptions) (int, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return 0, err
}
ro.Body = rw
var v int
v, err = c.WebsocketExit(fmt.Sprintf("/instances/%s/shell", id), ro, rw)
if err != nil {
return 0, err
}
return v, err
}
func (c *Client) InstanceTerminate(id string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/instances/%s", id), ro, nil)
return err
}
func (c *Client) ObjectDelete(app string, key string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/apps/%s/objects/%s", app, key), ro, nil)
return err
}
func (c *Client) ObjectExists(app string, key string) (bool, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v bool
err = c.Head(fmt.Sprintf("/apps/%s/objects/%s", app, key), ro, &v)
return v, err
}
func (c *Client) ObjectFetch(app string, key string) (io.ReadCloser, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v io.ReadCloser
res, err := c.GetStream(fmt.Sprintf("/apps/%s/objects/%s", app, key), ro)
if err != nil {
return nil, err
}
v = res.Body
return v, err
}
func (c *Client) ObjectList(app string, prefix string) ([]string, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Query["prefix"] = prefix
var v []string
err = c.Get(fmt.Sprintf("/apps/%s/objects", app), ro, &v)
return v, err
}
func (c *Client) ObjectStore(app string, key string, r io.Reader, opts structs.ObjectStoreOptions) (*structs.Object, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Body = r
var v *structs.Object
err = c.Post(fmt.Sprintf("/apps/%s/objects/%s", app, key), ro, &v)
return v, err
}
func (c *Client) ProcessExec(app string, pid string, command string, rw io.ReadWriter, opts structs.ProcessExecOptions) (int, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return 0, err
}
ro.Headers["command"] = command
ro.Body = rw
var v int
v, err = c.WebsocketExit(fmt.Sprintf("/apps/%s/processes/%s/exec", app, pid), ro, rw)
if err != nil {
return 0, err
}
return v, err
}
func (c *Client) ProcessGet(app string, pid string) (*structs.Process, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Process
err = c.Get(fmt.Sprintf("/apps/%s/processes/%s", app, pid), ro, &v)
return v, err
}
func (c *Client) ProcessList(app string, opts structs.ProcessListOptions) (structs.Processes, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Processes
err = c.Get(fmt.Sprintf("/apps/%s/processes", app), ro, &v)
return v, err
}
func (c *Client) ProcessLogs(app string, pid string, opts structs.LogsOptions) (io.ReadCloser, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v io.ReadCloser
r, err := c.Websocket(fmt.Sprintf("/apps/%s/processes/%s/logs", app, pid), ro)
if err != nil {
return nil, err
}
v = r
return v, err
}
func (c *Client) ProcessRun(app string, service string, opts structs.ProcessRunOptions) (*structs.Process, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v *structs.Process
err = c.Post(fmt.Sprintf("/apps/%s/services/%s/processes", app, service), ro, &v)
return v, err
}
func (c *Client) ProcessStop(app string, pid string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/apps/%s/processes/%s", app, pid), ro, nil)
return err
}
func (c *Client) Proxy(host string, port int, rw io.ReadWriter, opts structs.ProxyOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
ro.Body = rw
r, err := c.Websocket(fmt.Sprintf("/proxy/%s/%d", host, port), ro)
if err != nil {
return err
}
if _, err := io.Copy(rw, r); err != nil {
return err
}
return err
}
func (c *Client) RegistryAdd(server string, username string, password string) (*structs.Registry, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Params["server"] = server
ro.Params["username"] = username
ro.Params["password"] = password
var v *structs.Registry
err = c.Post(fmt.Sprintf("/registries"), ro, &v)
return v, err
}
func (c *Client) RegistryList() (structs.Registries, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Registries
err = c.Get(fmt.Sprintf("/registries"), ro, &v)
return v, err
}
func (c *Client) RegistryRemove(server string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/registries/%s", server), ro, nil)
return err
}
func (c *Client) ReleaseCreate(app string, opts structs.ReleaseCreateOptions) (*structs.Release, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v *structs.Release
err = c.Post(fmt.Sprintf("/apps/%s/releases", app), ro, &v)
return v, err
}
func (c *Client) ReleaseGet(app string, id string) (*structs.Release, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Release
err = c.Get(fmt.Sprintf("/apps/%s/releases/%s", app, id), ro, &v)
return v, err
}
func (c *Client) ReleaseList(app string, opts structs.ReleaseListOptions) (structs.Releases, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Releases
err = c.Get(fmt.Sprintf("/apps/%s/releases", app), ro, &v)
return v, err
}
func (c *Client) ReleasePromote(app string, id string, opts structs.ReleasePromoteOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
err = c.Post(fmt.Sprintf("/apps/%s/releases/%s/promote", app, id), ro, nil)
return err
}
func (c *Client) ResourceGet(app string, name string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Resource
err = c.Get(fmt.Sprintf("/apps/%s/resources/%s", app, name), ro, &v)
return v, err
}
func (c *Client) ResourceList(app string) (structs.Resources, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Resources
err = c.Get(fmt.Sprintf("/apps/%s/resources", app), ro, &v)
return v, err
}
func (c *Client) ServiceList(app string) (structs.Services, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Services
err = c.Get(fmt.Sprintf("/apps/%s/services", app), ro, &v)
return v, err
}
func (c *Client) ServiceUpdate(app string, name string, opts structs.ServiceUpdateOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
err = c.Put(fmt.Sprintf("/apps/%s/services/%s", app, name), ro, nil)
return err
}
func (c *Client) SystemGet() (*structs.System, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.System
err = c.Get(fmt.Sprintf("/system"), ro, &v)
return v, err
}
func (c *Client) SystemInstall(w io.Writer, opts structs.SystemInstallOptions) (string, error) {
err := fmt.Errorf("not available via api")
return "", err
}
func (c *Client) SystemLogs(opts structs.LogsOptions) (io.ReadCloser, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v io.ReadCloser
r, err := c.Websocket(fmt.Sprintf("/system/logs"), ro)
if err != nil {
return nil, err
}
v = r
return v, err
}
func (c *Client) SystemMetrics(opts structs.MetricsOptions) (structs.Metrics, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Metrics
err = c.Get(fmt.Sprintf("/system/metrics"), ro, &v)
return v, err
}
func (c *Client) SystemProcesses(opts structs.SystemProcessesOptions) (structs.Processes, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v structs.Processes
err = c.Get(fmt.Sprintf("/system/processes"), ro, &v)
return v, err
}
func (c *Client) SystemReleases() (structs.Releases, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Releases
err = c.Get(fmt.Sprintf("/system/releases"), ro, &v)
return v, err
}
func (c *Client) SystemResourceCreate(kind string, opts structs.ResourceCreateOptions) (*structs.Resource, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
ro.Params["kind"] = kind
var v *structs.Resource
err = c.Post(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceDelete(name string) error {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
err = c.Delete(fmt.Sprintf("/resources/%s", name), ro, nil)
return err
}
func (c *Client) SystemResourceGet(name string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Resource
err = c.Get(fmt.Sprintf("/resources/%s", name), ro, &v)
return v, err
}
func (c *Client) SystemResourceLink(name string, app string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
ro.Params["app"] = app
var v *structs.Resource
err = c.Post(fmt.Sprintf("/resources/%s/links", name), ro, &v)
return v, err
}
func (c *Client) SystemResourceList() (structs.Resources, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.Resources
err = c.Get(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceTypes() (structs.ResourceTypes, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v structs.ResourceTypes
err = c.Options(fmt.Sprintf("/resources"), ro, &v)
return v, err
}
func (c *Client) SystemResourceUnlink(name string, app string) (*structs.Resource, error) {
var err error
ro := stdsdk.RequestOptions{Headers: stdsdk.Headers{}, Params: stdsdk.Params{}, Query: stdsdk.Query{}}
var v *structs.Resource
err = c.Delete(fmt.Sprintf("/resources/%s/links/%s", name, app), ro, &v)
return v, err
}
func (c *Client) SystemResourceUpdate(name string, opts structs.ResourceUpdateOptions) (*structs.Resource, error) {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return nil, err
}
var v *structs.Resource
err = c.Put(fmt.Sprintf("/resources/%s", name), ro, &v)
return v, err
}
func (c *Client) SystemUninstall(name string, w io.Writer, opts structs.SystemUninstallOptions) error {
err := fmt.Errorf("not available via api")
return err
}
func (c *Client) SystemUpdate(opts structs.SystemUpdateOptions) error {
var err error
ro, err := stdsdk.MarshalOptions(opts)
if err != nil {
return err
}
err = c.Put(fmt.Sprintf("/system"), ro, nil)
return err
}
func (c *Client) Workers() error {
err := fmt.Errorf("not available via api")
return err
}

135
sdk/sdk.go Normal file
View File

@ -0,0 +1,135 @@
package sdk
import (
"context"
"encoding/base64"
"fmt"
"io"
"math/rand"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/convox/convox/pkg/structs"
"github.com/convox/stdsdk"
)
const (
sortableTime = "20060102.150405.000000000"
statusCodePrefix = "F1E49A85-0AD7-4AEF-A618-C249C6E6568D:"
)
var (
Version = "dev"
)
type Client struct {
*stdsdk.Client
Debug bool
Rack string
Session SessionFunc
}
type SessionFunc func(c *Client) string
// ensure interface parity
var _ structs.Provider = &Client{}
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func New(endpoint string) (*Client, error) {
s, err := stdsdk.New(coalesce(endpoint, "https://rack.convox"))
if err != nil {
return nil, err
}
c := &Client{
Client: s,
Debug: os.Getenv("CONVOX_DEBUG") == "true",
}
c.Client.Headers = c.Headers
return c, nil
}
func NewFromEnv() (*Client, error) {
return New(os.Getenv("RACK_URL"))
}
func (c *Client) Headers() http.Header {
h := http.Header{}
h.Set("User-Agent", fmt.Sprintf("convox.go/%s", Version))
h.Set("Version", Version)
if c.Endpoint.User != nil {
h.Set("Authorization", fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s", c.Endpoint.User)))))
}
if c.Rack != "" {
h.Set("Rack", c.Rack)
}
if c.Session != nil {
h.Set("Session", c.Session(c))
}
return h
}
func (c *Client) Websocket(path string, opts stdsdk.RequestOptions) (io.ReadCloser, error) {
// trigger session authentication
c.Get("/racks", stdsdk.RequestOptions{}, nil)
return c.Client.Websocket(path, opts)
}
func (c *Client) WebsocketExit(path string, ro stdsdk.RequestOptions, rw io.ReadWriter) (int, error) {
ws, err := c.Websocket(path, ro)
if err != nil {
return 0, err
}
buf := make([]byte, 10*1024)
code := 0
for {
n, err := ws.Read(buf)
if err == io.EOF {
return code, nil
}
if err != nil {
return code, err
}
if i := strings.Index(string(buf[0:n]), statusCodePrefix); i > -1 {
if _, err := rw.Write(buf[0:i]); err != nil {
return 0, err
}
m := i + len(statusCodePrefix)
code, err = strconv.Atoi(strings.TrimSpace(string(buf[m:n])))
if err != nil {
return 0, fmt.Errorf("unable to read exit code")
}
continue
}
if _, err := rw.Write(buf[0:n]); err != nil {
return 0, err
}
}
}
func (c *Client) WithContext(ctx context.Context) structs.Provider {
cc := *c
cc.Client = cc.Client.WithContext(ctx)
return &cc
}

3
vendor/github.com/convox/exec/Makefile generated vendored Normal file
View File

@ -0,0 +1,3 @@
mocks:
go get -u github.com/vektra/mockery/.../
mockery -case underscore -inpkg -name Interface

33
vendor/github.com/convox/exec/exec.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
package exec
import (
"io"
"os"
"os/exec"
)
type Exec struct {
}
func (e *Exec) Execute(command string, args ...string) ([]byte, error) {
return exec.Command(command, args...).CombinedOutput()
}
func (e *Exec) Run(w io.Writer, command string, args ...string) error {
cmd := exec.Command(command, args...)
cmd.Stdout = w
cmd.Stderr = w
return cmd.Run()
}
func (e *Exec) Stream(w io.Writer, r io.Reader, command string, args ...string) error {
cmd := exec.Command(command, args...)
cmd.Stdin = r
cmd.Stdout = w
cmd.Stderr = w
return cmd.Run()
}
func (e *Exec) Terminal(command string, args ...string) error {
return e.Stream(os.Stdout, os.Stdin, command, args...)
}

10
vendor/github.com/convox/exec/interface.go generated vendored Normal file
View File

@ -0,0 +1,10 @@
package exec
import "io"
type Interface interface {
Execute(string, ...string) ([]byte, error)
Run(io.Writer, string, ...string) error
Stream(io.Writer, io.Reader, string, ...string) error
Terminal(string, ...string) error
}

104
vendor/github.com/convox/exec/mock_interface.go generated vendored Normal file
View File

@ -0,0 +1,104 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
package exec
import io "io"
import mock "github.com/stretchr/testify/mock"
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
// Execute provides a mock function with given fields: _a0, _a1
func (_m *MockInterface) Execute(_a0 string, _a1 ...string) ([]byte, error) {
_va := make([]interface{}, len(_a1))
for _i := range _a1 {
_va[_i] = _a1[_i]
}
var _ca []interface{}
_ca = append(_ca, _a0)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 []byte
if rf, ok := ret.Get(0).(func(string, ...string) []byte); ok {
r0 = rf(_a0, _a1...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]byte)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, ...string) error); ok {
r1 = rf(_a0, _a1...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Run provides a mock function with given fields: _a0, _a1, _a2
func (_m *MockInterface) Run(_a0 io.Writer, _a1 string, _a2 ...string) error {
_va := make([]interface{}, len(_a2))
for _i := range _a2 {
_va[_i] = _a2[_i]
}
var _ca []interface{}
_ca = append(_ca, _a0, _a1)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 error
if rf, ok := ret.Get(0).(func(io.Writer, string, ...string) error); ok {
r0 = rf(_a0, _a1, _a2...)
} else {
r0 = ret.Error(0)
}
return r0
}
// Stream provides a mock function with given fields: _a0, _a1, _a2, _a3
func (_m *MockInterface) Stream(_a0 io.Writer, _a1 io.Reader, _a2 string, _a3 ...string) error {
_va := make([]interface{}, len(_a3))
for _i := range _a3 {
_va[_i] = _a3[_i]
}
var _ca []interface{}
_ca = append(_ca, _a0, _a1, _a2)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 error
if rf, ok := ret.Get(0).(func(io.Writer, io.Reader, string, ...string) error); ok {
r0 = rf(_a0, _a1, _a2, _a3...)
} else {
r0 = ret.Error(0)
}
return r0
}
// Terminal provides a mock function with given fields: _a0, _a1
func (_m *MockInterface) Terminal(_a0 string, _a1 ...string) error {
_va := make([]interface{}, len(_a1))
for _i := range _a1 {
_va[_i] = _a1[_i]
}
var _ca []interface{}
_ca = append(_ca, _a0)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 error
if rf, ok := ret.Get(0).(func(string, ...string) error); ok {
r0 = rf(_a0, _a1...)
} else {
r0 = ret.Error(0)
}
return r0
}

View File

@ -1,8 +0,0 @@
language: go
go:
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Yasuhiro Matsumoto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,27 +0,0 @@
go-runewidth
============
[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)
[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD)
[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)
Provides functions to get fixed width of the character or string.
Usage
-----
```go
runewidth.StringWidth("つのだ☆HIRO") == 12
```
Author
------
Yasuhiro Matsumoto
License
-------
under the MIT License: http://mattn.mit-license.org/2013

View File

@ -1,977 +0,0 @@
package runewidth
import (
"os"
)
var (
// EastAsianWidth will be set true if the current locale is CJK
EastAsianWidth bool
// ZeroWidthJoiner is flag to set to use UTR#51 ZWJ
ZeroWidthJoiner bool
// DefaultCondition is a condition in current locale
DefaultCondition = &Condition{}
)
func init() {
handleEnv()
}
func handleEnv() {
env := os.Getenv("RUNEWIDTH_EASTASIAN")
if env == "" {
EastAsianWidth = IsEastAsian()
} else {
EastAsianWidth = env == "1"
}
// update DefaultCondition
DefaultCondition.EastAsianWidth = EastAsianWidth
DefaultCondition.ZeroWidthJoiner = ZeroWidthJoiner
}
type interval struct {
first rune
last rune
}
type table []interval
func inTables(r rune, ts ...table) bool {
for _, t := range ts {
if inTable(r, t) {
return true
}
}
return false
}
func inTable(r rune, t table) bool {
// func (t table) IncludesRune(r rune) bool {
if r < t[0].first {
return false
}
bot := 0
top := len(t) - 1
for top >= bot {
mid := (bot + top) >> 1
switch {
case t[mid].last < r:
bot = mid + 1
case t[mid].first > r:
top = mid - 1
default:
return true
}
}
return false
}
var private = table{
{0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
}
var nonprint = table{
{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
{0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
}
var combining = table{
{0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD},
{0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5},
{0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F},
{0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4},
{0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711},
{0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3},
{0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827},
{0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1},
{0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F},
{0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983},
{0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8},
{0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3},
{0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},
{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
{0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83},
{0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9},
{0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03},
{0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48},
{0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63},
{0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
{0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03},
{0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
{0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83},
{0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8},
{0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3},
{0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48},
{0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63},
{0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4},
{0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3},
{0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E},
{0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC},
{0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35},
{0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F},
{0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97},
{0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E},
{0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064},
{0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D},
{0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F},
{0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753},
{0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD},
{0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9},
{0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B},
{0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F},
{0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44},
{0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD},
{0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2},
{0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4},
{0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF},
{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F},
{0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A},
{0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F},
{0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806},
{0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881},
{0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D},
{0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0},
{0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43},
{0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0},
{0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF},
{0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6},
{0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E},
{0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD},
{0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03},
{0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A},
{0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002},
{0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA},
{0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173},
{0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC},
{0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA},
{0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344},
{0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357},
{0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
{0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5},
{0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640},
{0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36},
{0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6},
{0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E},
{0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169},
{0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B},
{0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36},
{0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84},
{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
{0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A},
{0xE0100, 0xE01EF},
}
var doublewidth = table{
{0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
{0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
{0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
{0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
{0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
{0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
{0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
{0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
{0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
{0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
{0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
{0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},
{0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
{0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247},
{0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C},
{0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3},
{0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60},
{0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC},
{0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004},
{0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
{0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
{0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335},
{0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA},
{0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4},
{0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC},
{0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567},
{0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4},
{0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC},
{0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6},
{0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930},
{0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E},
{0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD},
{0x30000, 0x3FFFD},
}
var ambiguous = table{
{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
{0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},
{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},
{0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},
{0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
{0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},
{0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},
{0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},
{0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
{0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},
{0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},
{0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},
{0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
{0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},
{0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},
{0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
{0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},
{0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},
{0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},
{0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
{0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},
{0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},
{0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},
{0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
{0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},
{0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},
{0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},
{0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
{0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},
{0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},
{0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},
{0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
{0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},
{0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},
{0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},
{0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},
{0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},
{0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},
{0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
{0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
{0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
{0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
{0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
{0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
{0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
}
var emoji = table{
{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
{0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF},
{0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2},
{0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0},
{0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E},
{0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618},
{0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623},
{0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F},
{0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642},
{0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663},
{0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B},
{0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699},
{0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26AA, 0x26AB},
{0x26B0, 0x26B1}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
{0x26C8, 0x26C8}, {0x26CE, 0x26CF}, {0x26D1, 0x26D1},
{0x26D3, 0x26D4}, {0x26E9, 0x26EA}, {0x26F0, 0x26F5},
{0x26F7, 0x26FA}, {0x26FD, 0x26FD}, {0x2702, 0x2702},
{0x2705, 0x2705}, {0x2708, 0x270D}, {0x270F, 0x270F},
{0x2712, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
{0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
{0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
{0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
{0x2757, 0x2757}, {0x2763, 0x2764}, {0x2795, 0x2797},
{0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
{0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
{0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
{0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F170, 0x1F171},
{0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
{0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F202}, {0x1F21A, 0x1F21A},
{0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F250, 0x1F251},
{0x1F300, 0x1F321}, {0x1F324, 0x1F393}, {0x1F396, 0x1F397},
{0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0}, {0x1F3F3, 0x1F3F5},
{0x1F3F7, 0x1F4FD}, {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E},
{0x1F550, 0x1F567}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A},
{0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590},
{0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8},
{0x1F5B1, 0x1F5B2}, {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4},
{0x1F5D1, 0x1F5D3}, {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1},
{0x1F5E3, 0x1F5E3}, {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF},
{0x1F5F3, 0x1F5F3}, {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5},
{0x1F6CB, 0x1F6D2}, {0x1F6E0, 0x1F6E5}, {0x1F6E9, 0x1F6E9},
{0x1F6EB, 0x1F6EC}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F9},
{0x1F910, 0x1F93A}, {0x1F93C, 0x1F93E}, {0x1F940, 0x1F945},
{0x1F947, 0x1F970}, {0x1F973, 0x1F976}, {0x1F97A, 0x1F97A},
{0x1F97C, 0x1F9A2}, {0x1F9B0, 0x1F9B9}, {0x1F9C0, 0x1F9C2},
{0x1F9D0, 0x1F9FF},
}
var notassigned = table{
{0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B},
{0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530},
{0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588},
{0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF},
{0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D},
{0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF},
{0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F},
{0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5},
{0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E},
{0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1},
{0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6},
{0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB},
{0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00},
{0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12},
{0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34},
{0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D},
{0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50},
{0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65},
{0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E},
{0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1},
{0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6},
{0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF},
{0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00},
{0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12},
{0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34},
{0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A},
{0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E},
{0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84},
{0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98},
{0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2},
{0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD},
{0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF},
{0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF},
{0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11},
{0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45},
{0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57},
{0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77},
{0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91},
{0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB},
{0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4},
{0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5},
{0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04},
{0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C},
{0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53},
{0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84},
{0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC},
{0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE},
{0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5},
{0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E},
{0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86},
{0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93},
{0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4},
{0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC},
{0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5},
{0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB},
{0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70},
{0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD},
{0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC},
{0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F},
{0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F},
{0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1},
{0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1},
{0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311},
{0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F},
{0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF},
{0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D},
{0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F},
{0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F},
{0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF},
{0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F},
{0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F},
{0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943},
{0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF},
{0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D},
{0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F},
{0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF},
{0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB},
{0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF},
{0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF},
{0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F},
{0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58},
{0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E},
{0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5},
{0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1},
{0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065},
{0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F},
{0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F},
{0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F},
{0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC},
{0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF},
{0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8},
{0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F},
{0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F},
{0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7},
{0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF},
{0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F},
{0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF},
{0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098},
{0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F},
{0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F},
{0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF},
{0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F},
{0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6},
{0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F},
{0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF},
{0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE},
{0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F},
{0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA},
{0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10},
{0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F},
{0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF},
{0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF},
{0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12},
{0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D},
{0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45},
{0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91},
{0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F},
{0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F},
{0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00},
{0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1},
{0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7},
{0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C},
{0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E},
{0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF},
{0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F},
{0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F},
{0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF},
{0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F},
{0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF},
{0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7},
{0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E},
{0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F},
{0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809},
{0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E},
{0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF},
{0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E},
{0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB},
{0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B},
{0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37},
{0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F},
{0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF},
{0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77},
{0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF},
{0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9},
{0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051},
{0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF},
{0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F},
{0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0},
{0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F},
{0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E},
{0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF},
{0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E},
{0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331},
{0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346},
{0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356},
{0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F},
{0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C},
{0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F},
{0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F},
{0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF},
{0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F},
{0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF},
{0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37},
{0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91},
{0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF},
{0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF},
{0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F},
{0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF},
{0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F},
{0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C},
{0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E},
{0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF},
{0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F},
{0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B},
{0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128},
{0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F},
{0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D},
{0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8},
{0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC},
{0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C},
{0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A},
{0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549},
{0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD},
{0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF},
{0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022},
{0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6},
{0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D},
{0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20},
{0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28},
{0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A},
{0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48},
{0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50},
{0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58},
{0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E},
{0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66},
{0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78},
{0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A},
{0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA},
{0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F},
{0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0},
{0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F},
{0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5},
{0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F},
{0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF},
{0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF},
{0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F},
{0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F},
{0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F},
{0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF},
{0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F},
{0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000},
{0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF},
{0xFFFFE, 0xFFFFF},
}
var neutral = table{
{0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},
{0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},
{0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},
{0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},
{0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},
{0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},
{0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
{0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
{0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
{0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
{0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
{0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},
{0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},
{0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},
{0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},
{0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},
{0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
{0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},
{0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},
{0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},
{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
{0x0531, 0x0556}, {0x0559, 0x055F}, {0x0561, 0x0587},
{0x0589, 0x058A}, {0x058D, 0x058F}, {0x0591, 0x05C7},
{0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0600, 0x061C},
{0x061E, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1},
{0x07C0, 0x07FA}, {0x0800, 0x082D}, {0x0830, 0x083E},
{0x0840, 0x085B}, {0x085E, 0x085E}, {0x08A0, 0x08B4},
{0x08B6, 0x08BD}, {0x08D4, 0x0983}, {0x0985, 0x098C},
{0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0},
{0x09B2, 0x09B2}, {0x09B6, 0x09B9}, {0x09BC, 0x09C4},
{0x09C7, 0x09C8}, {0x09CB, 0x09CE}, {0x09D7, 0x09D7},
{0x09DC, 0x09DD}, {0x09DF, 0x09E3}, {0x09E6, 0x09FB},
{0x0A01, 0x0A03}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10},
{0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
{0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C},
{0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D},
{0x0A51, 0x0A51}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E},
{0x0A66, 0x0A75}, {0x0A81, 0x0A83}, {0x0A85, 0x0A8D},
{0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0},
{0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5},
{0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0},
{0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AF9},
{0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
{0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33},
{0x0B35, 0x0B39}, {0x0B3C, 0x0B44}, {0x0B47, 0x0B48},
{0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B5C, 0x0B5D},
{0x0B5F, 0x0B63}, {0x0B66, 0x0B77}, {0x0B82, 0x0B83},
{0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
{0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F},
{0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9},
{0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD},
{0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA},
{0x0C00, 0x0C03}, {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10},
{0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3D, 0x0C44},
{0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
{0x0C58, 0x0C5A}, {0x0C60, 0x0C63}, {0x0C66, 0x0C6F},
{0x0C78, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},
{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D01, 0x0D03},
{0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A},
{0x0D3D, 0x0D44}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4F},
{0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, {0x0D82, 0x0D83},
{0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB},
{0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA},
{0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF},
{0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, {0x0E01, 0x0E3A},
{0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, {0x0E84, 0x0E84},
{0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, {0x0E8D, 0x0E8D},
{0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3},
{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, {0x0EAA, 0x0EAB},
{0x0EAD, 0x0EB9}, {0x0EBB, 0x0EBD}, {0x0EC0, 0x0EC4},
{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},
{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
{0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
{0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
{0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
{0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
{0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},
{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},
{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},
{0x1820, 0x1877}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},
{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},
{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},
{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},
{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},
{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},
{0x1AB0, 0x1ABE}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},
{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},
{0x1C4D, 0x1C88}, {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CF6},
{0x1CF8, 0x1CF9}, {0x1D00, 0x1DF5}, {0x1DFB, 0x1F15},
{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
{0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
{0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
{0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
{0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
{0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
{0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20F0},
{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
{0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
{0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
{0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
{0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
{0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
{0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
{0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
{0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
{0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
{0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
{0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
{0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
{0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
{0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
{0x23F1, 0x23F2}, {0x23F4, 0x23FE}, {0x2400, 0x2426},
{0x2440, 0x244A}, {0x24EA, 0x24EA}, {0x254C, 0x254F},
{0x2574, 0x257F}, {0x2590, 0x2591}, {0x2596, 0x259F},
{0x25A2, 0x25A2}, {0x25AA, 0x25B1}, {0x25B4, 0x25B5},
{0x25B8, 0x25BB}, {0x25BE, 0x25BF}, {0x25C2, 0x25C5},
{0x25C9, 0x25CA}, {0x25CC, 0x25CD}, {0x25D2, 0x25E1},
{0x25E6, 0x25EE}, {0x25F0, 0x25FC}, {0x25FF, 0x2604},
{0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613},
{0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F},
{0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F},
{0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B},
{0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692},
{0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9},
{0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2},
{0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709},
{0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B},
{0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756},
{0x2758, 0x2775}, {0x2780, 0x2794}, {0x2798, 0x27AF},
{0x27B1, 0x27BE}, {0x27C0, 0x27E5}, {0x27EE, 0x2984},
{0x2987, 0x2B1A}, {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54},
{0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9},
{0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF},
{0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2CF3},
{0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D},
{0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96},
{0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6},
{0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE},
{0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E44},
{0x303F, 0x303F}, {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B},
{0xA640, 0xA6F7}, {0xA700, 0xA7AE}, {0xA7B0, 0xA7B7},
{0xA7F7, 0xA82B}, {0xA830, 0xA839}, {0xA840, 0xA877},
{0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA8FD},
{0xA900, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
{0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
{0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
{0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
{0xAB30, 0xAB65}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},
{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},
{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
{0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
{0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
{0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
{0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
{0x10300, 0x10323}, {0x10330, 0x1034A}, {0x10350, 0x1037A},
{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},
{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33},
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A47}, {0x10A50, 0x10A58},
{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
{0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x1104D},
{0x11052, 0x1106F}, {0x1107F, 0x110C1}, {0x110D0, 0x110E8},
{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11143},
{0x11150, 0x11176}, {0x11180, 0x111CD}, {0x111D0, 0x111DF},
{0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x1123E},
{0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D},
{0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA},
{0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C},
{0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330},
{0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133C, 0x11344},
{0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350},
{0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C},
{0x11370, 0x11374}, {0x11400, 0x11459}, {0x1145B, 0x1145B},
{0x1145D, 0x1145D}, {0x11480, 0x114C7}, {0x114D0, 0x114D9},
{0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644},
{0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B7},
{0x116C0, 0x116C9}, {0x11700, 0x11719}, {0x1171D, 0x1172B},
{0x11730, 0x1173F}, {0x118A0, 0x118F2}, {0x118FF, 0x118FF},
{0x11AC0, 0x11AF8}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36},
{0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F},
{0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x12000, 0x12399},
{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
{0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38},
{0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F},
{0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45},
{0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77},
{0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, {0x16F50, 0x16F7E},
{0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
{0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3},
{0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1E8},
{0x1D200, 0x1D245}, {0x1D300, 0x1D356}, {0x1D360, 0x1D371},
{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},
{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},
{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},
{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},
{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},
{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},
{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},
{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
{0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
{0x1E900, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
{0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22},
{0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32},
{0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B},
{0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49},
{0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52},
{0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59},
{0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F},
{0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A},
{0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C},
{0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B},
{0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB},
{0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B},
{0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF},
{0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C},
{0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF},
{0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
{0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
{0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
{0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
{0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
{0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
{0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA},
{0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4},
{0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859},
{0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001},
{0xE0020, 0xE007F},
}
// Condition have flag EastAsianWidth whether the current locale is CJK or not.
type Condition struct {
EastAsianWidth bool
ZeroWidthJoiner bool
}
// NewCondition return new instance of Condition which is current locale.
func NewCondition() *Condition {
return &Condition{
EastAsianWidth: EastAsianWidth,
ZeroWidthJoiner: ZeroWidthJoiner,
}
}
// RuneWidth returns the number of cells in r.
// See http://www.unicode.org/reports/tr11/
func (c *Condition) RuneWidth(r rune) int {
switch {
case r < 0 || r > 0x10FFFF ||
inTables(r, nonprint, combining, notassigned):
return 0
case (c.EastAsianWidth && IsAmbiguousWidth(r)) ||
inTables(r, doublewidth, emoji):
return 2
default:
return 1
}
}
func (c *Condition) stringWidth(s string) (width int) {
for _, r := range []rune(s) {
width += c.RuneWidth(r)
}
return width
}
func (c *Condition) stringWidthZeroJoiner(s string) (width int) {
r1, r2 := rune(0), rune(0)
for _, r := range []rune(s) {
if r == 0xFE0E || r == 0xFE0F {
continue
}
w := c.RuneWidth(r)
if r2 == 0x200D && inTables(r, emoji) && inTables(r1, emoji) {
w = 0
}
width += w
r1, r2 = r2, r
}
return width
}
// StringWidth return width as you can see
func (c *Condition) StringWidth(s string) (width int) {
if c.ZeroWidthJoiner {
return c.stringWidthZeroJoiner(s)
}
return c.stringWidth(s)
}
// Truncate return string truncated with w cells
func (c *Condition) Truncate(s string, w int, tail string) string {
if c.StringWidth(s) <= w {
return s
}
r := []rune(s)
tw := c.StringWidth(tail)
w -= tw
width := 0
i := 0
for ; i < len(r); i++ {
cw := c.RuneWidth(r[i])
if width+cw > w {
break
}
width += cw
}
return string(r[0:i]) + tail
}
// Wrap return string wrapped with w cells
func (c *Condition) Wrap(s string, w int) string {
width := 0
out := ""
for _, r := range []rune(s) {
cw := RuneWidth(r)
if r == '\n' {
out += string(r)
width = 0
continue
} else if width+cw > w {
out += "\n"
width = 0
out += string(r)
width += cw
continue
}
out += string(r)
width += cw
}
return out
}
// FillLeft return string filled in left by spaces in w cells
func (c *Condition) FillLeft(s string, w int) string {
width := c.StringWidth(s)
count := w - width
if count > 0 {
b := make([]byte, count)
for i := range b {
b[i] = ' '
}
return string(b) + s
}
return s
}
// FillRight return string filled in left by spaces in w cells
func (c *Condition) FillRight(s string, w int) string {
width := c.StringWidth(s)
count := w - width
if count > 0 {
b := make([]byte, count)
for i := range b {
b[i] = ' '
}
return s + string(b)
}
return s
}
// RuneWidth returns the number of cells in r.
// See http://www.unicode.org/reports/tr11/
func RuneWidth(r rune) int {
return DefaultCondition.RuneWidth(r)
}
// IsAmbiguousWidth returns whether is ambiguous width or not.
func IsAmbiguousWidth(r rune) bool {
return inTables(r, private, ambiguous)
}
// IsNeutralWidth returns whether is neutral width or not.
func IsNeutralWidth(r rune) bool {
return inTable(r, neutral)
}
// StringWidth return width as you can see
func StringWidth(s string) (width int) {
return DefaultCondition.StringWidth(s)
}
// Truncate return string truncated with w cells
func Truncate(s string, w int, tail string) string {
return DefaultCondition.Truncate(s, w, tail)
}
// Wrap return string wrapped with w cells
func Wrap(s string, w int) string {
return DefaultCondition.Wrap(s, w)
}
// FillLeft return string filled in left by spaces in w cells
func FillLeft(s string, w int) string {
return DefaultCondition.FillLeft(s, w)
}
// FillRight return string filled in left by spaces in w cells
func FillRight(s string, w int) string {
return DefaultCondition.FillRight(s, w)
}

View File

@ -1,8 +0,0 @@
// +build appengine
package runewidth
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
return false
}

View File

@ -1,9 +0,0 @@
// +build js
// +build !appengine
package runewidth
func IsEastAsian() bool {
// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
return false
}

View File

@ -1,79 +0,0 @@
// +build !windows
// +build !js
// +build !appengine
package runewidth
import (
"os"
"regexp"
"strings"
)
var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
var mblenTable = map[string]int{
"utf-8": 6,
"utf8": 6,
"jis": 8,
"eucjp": 3,
"euckr": 2,
"euccn": 2,
"sjis": 2,
"cp932": 2,
"cp51932": 2,
"cp936": 2,
"cp949": 2,
"cp950": 2,
"big5": 2,
"gbk": 2,
"gb2312": 2,
}
func isEastAsian(locale string) bool {
charset := strings.ToLower(locale)
r := reLoc.FindStringSubmatch(locale)
if len(r) == 2 {
charset = strings.ToLower(r[1])
}
if strings.HasSuffix(charset, "@cjk_narrow") {
return false
}
for pos, b := range []byte(charset) {
if b == '@' {
charset = charset[:pos]
break
}
}
max := 1
if m, ok := mblenTable[charset]; ok {
max = m
}
if max > 1 && (charset[0] != 'u' ||
strings.HasPrefix(locale, "ja") ||
strings.HasPrefix(locale, "ko") ||
strings.HasPrefix(locale, "zh")) {
return true
}
return false
}
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
locale := os.Getenv("LC_CTYPE")
if locale == "" {
locale = os.Getenv("LANG")
}
// ignore C locale
if locale == "POSIX" || locale == "C" {
return false
}
if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
return false
}
return isEastAsian(locale)
}

View File

@ -1,28 +0,0 @@
// +build windows
// +build !appengine
package runewidth
import (
"syscall"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32")
procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
)
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
r1, _, _ := procGetConsoleOutputCP.Call()
if r1 == 0 {
return false
}
switch int(r1) {
case 932, 51932, 936, 949, 950:
return true
}
return false
}

View File

@ -1,9 +0,0 @@
language: go
go:
- 1.7.x
- 1.10.x
- master
sudo: false
os:
- linux
- osx

View File

@ -1,12 +0,0 @@
Copyright (c) 2012-2015, Sergey Cherepanov
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,177 +0,0 @@
# Terminal progress bar for Go
Simple progress bar for console programs.
Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta)
## Installation
```
go get gopkg.in/cheggaaa/pb.v1
```
## Usage
```Go
package main
import (
"gopkg.in/cheggaaa/pb.v1"
"time"
)
func main() {
count := 100000
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
```
Result will be like this:
```
> go run test.go
37158 / 100000 [================>_______________________________] 37.16% 1m11s
```
## Customization
```Go
// create bar
bar := pb.New(count)
// refresh info every second (default 200ms)
bar.SetRefreshRate(time.Second)
// show percents (by default already true)
bar.ShowPercent = true
// show bar (by default already true)
bar.ShowBar = true
// no counters
bar.ShowCounters = false
// show "time left"
bar.ShowTimeLeft = true
// show average speed
bar.ShowSpeed = true
// sets the width of the progress bar
bar.SetWidth(80)
// sets the width of the progress bar, but if terminal size smaller will be ignored
bar.SetMaxWidth(80)
// convert output to readable format (like KB, MB)
bar.SetUnits(pb.U_BYTES)
// and start
bar.Start()
```
## Progress bar for IO Operations
```go
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
// create proxy reader
reader := bar.NewProxyReader(r)
// and copy from pb reader
io.Copy(w, reader)
```
```go
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
// create multi writer
writer := io.MultiWriter(w, bar)
// and copy
io.Copy(writer, r)
bar.Finish()
```
## Custom Progress Bar Look-and-feel
```go
bar.Format("<.- >")
```
## Multiple Progress Bars (experimental and unstable)
Do not print to terminal while pool is active.
```go
package main
import (
"math/rand"
"sync"
"time"
"gopkg.in/cheggaaa/pb.v1"
)
func main() {
// create bars
first := pb.New(200).Prefix("First ")
second := pb.New(200).Prefix("Second ")
third := pb.New(200).Prefix("Third ")
// start pool
pool, err := pb.StartPool(first, second, third)
if err != nil {
panic(err)
}
// update bars
wg := new(sync.WaitGroup)
for _, bar := range []*pb.ProgressBar{first, second, third} {
wg.Add(1)
go func(cb *pb.ProgressBar) {
for n := 0; n < 200; n++ {
cb.Increment()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
}
cb.Finish()
wg.Done()
}(bar)
}
wg.Wait()
// close pool
pool.Stop()
}
```
The result will be as follows:
```
$ go run example/multiple.go
First 34 / 200 [=========>---------------------------------------------] 17.00% 00m08s
Second 42 / 200 [===========>------------------------------------------] 21.00% 00m06s
Third 36 / 200 [=========>---------------------------------------------] 18.00% 00m08s
```

View File

@ -1,125 +0,0 @@
package pb
import (
"fmt"
"time"
)
type Units int
const (
// U_NO are default units, they represent a simple value and are not formatted at all.
U_NO Units = iota
// U_BYTES units are formatted in a human readable way (B, KiB, MiB, ...)
U_BYTES
// U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...)
U_BYTES_DEC
// U_DURATION units are formatted in a human readable way (3h14m15s)
U_DURATION
)
const (
KiB = 1024
MiB = 1048576
GiB = 1073741824
TiB = 1099511627776
KB = 1e3
MB = 1e6
GB = 1e9
TB = 1e12
)
func Format(i int64) *formatter {
return &formatter{n: i}
}
type formatter struct {
n int64
unit Units
width int
perSec bool
}
func (f *formatter) To(unit Units) *formatter {
f.unit = unit
return f
}
func (f *formatter) Width(width int) *formatter {
f.width = width
return f
}
func (f *formatter) PerSec() *formatter {
f.perSec = true
return f
}
func (f *formatter) String() (out string) {
switch f.unit {
case U_BYTES:
out = formatBytes(f.n)
case U_BYTES_DEC:
out = formatBytesDec(f.n)
case U_DURATION:
out = formatDuration(f.n)
default:
out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
}
if f.perSec {
out += "/s"
}
return
}
// Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B
func formatBytes(i int64) (result string) {
switch {
case i >= TiB:
result = fmt.Sprintf("%.02f TiB", float64(i)/TiB)
case i >= GiB:
result = fmt.Sprintf("%.02f GiB", float64(i)/GiB)
case i >= MiB:
result = fmt.Sprintf("%.02f MiB", float64(i)/MiB)
case i >= KiB:
result = fmt.Sprintf("%.02f KiB", float64(i)/KiB)
default:
result = fmt.Sprintf("%d B", i)
}
return
}
// Convert bytes to base-10 human readable string. Like 2 MB, 64.2 KB, 52 B
func formatBytesDec(i int64) (result string) {
switch {
case i >= TB:
result = fmt.Sprintf("%.02f TB", float64(i)/TB)
case i >= GB:
result = fmt.Sprintf("%.02f GB", float64(i)/GB)
case i >= MB:
result = fmt.Sprintf("%.02f MB", float64(i)/MB)
case i >= KB:
result = fmt.Sprintf("%.02f KB", float64(i)/KB)
default:
result = fmt.Sprintf("%d B", i)
}
return
}
func formatDuration(n int64) (result string) {
d := time.Duration(n)
if d > time.Hour*24 {
result = fmt.Sprintf("%dd", d/24/time.Hour)
d -= (d / time.Hour / 24) * (time.Hour * 24)
}
if d > time.Hour {
result = fmt.Sprintf("%s%dh", result, d/time.Hour)
d -= d / time.Hour * time.Hour
}
m := d / time.Minute
d -= m * time.Minute
s := d / time.Second
result = fmt.Sprintf("%s%02dm%02ds", result, m, s)
return
}

500
vendor/gopkg.in/cheggaaa/pb.v1/pb.go generated vendored
View File

@ -1,500 +0,0 @@
// Simple console progress bars
package pb
import (
"fmt"
"io"
"math"
"strings"
"sync"
"sync/atomic"
"time"
"unicode/utf8"
)
// Current version
const Version = "1.0.28"
const (
// Default refresh rate - 200ms
DEFAULT_REFRESH_RATE = time.Millisecond * 200
FORMAT = "[=>-]"
)
// DEPRECATED
// variables for backward compatibility, from now do not work
// use pb.Format and pb.SetRefreshRate
var (
DefaultRefreshRate = DEFAULT_REFRESH_RATE
BarStart, BarEnd, Empty, Current, CurrentN string
)
// Create new progress bar object
func New(total int) *ProgressBar {
return New64(int64(total))
}
// Create new progress bar object using int64 as total
func New64(total int64) *ProgressBar {
pb := &ProgressBar{
Total: total,
RefreshRate: DEFAULT_REFRESH_RATE,
ShowPercent: true,
ShowCounters: true,
ShowBar: true,
ShowTimeLeft: true,
ShowElapsedTime: false,
ShowFinalTime: true,
Units: U_NO,
ManualUpdate: false,
finish: make(chan struct{}),
}
return pb.Format(FORMAT)
}
// Create new object and start
func StartNew(total int) *ProgressBar {
return New(total).Start()
}
// Callback for custom output
// For example:
// bar.Callback = func(s string) {
// mySuperPrint(s)
// }
//
type Callback func(out string)
type ProgressBar struct {
current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
previous int64
Total int64
RefreshRate time.Duration
ShowPercent, ShowCounters bool
ShowSpeed, ShowTimeLeft, ShowBar bool
ShowFinalTime, ShowElapsedTime bool
Output io.Writer
Callback Callback
NotPrint bool
Units Units
Width int
ForceWidth bool
ManualUpdate bool
AutoStat bool
// Default width for the time box.
UnitsWidth int
TimeBoxWidth int
finishOnce sync.Once //Guards isFinish
finish chan struct{}
isFinish bool
startTime time.Time
startValue int64
changeTime time.Time
prefix, postfix string
mu sync.Mutex
lastPrint string
BarStart string
BarEnd string
Empty string
Current string
CurrentN string
AlwaysUpdate bool
}
// Start print
func (pb *ProgressBar) Start() *ProgressBar {
pb.startTime = time.Now()
pb.startValue = atomic.LoadInt64(&pb.current)
if atomic.LoadInt64(&pb.Total) == 0 {
pb.ShowTimeLeft = false
pb.ShowPercent = false
pb.AutoStat = false
}
if !pb.ManualUpdate {
pb.Update() // Initial printing of the bar before running the bar refresher.
go pb.refresher()
}
return pb
}
// Increment current value
func (pb *ProgressBar) Increment() int {
return pb.Add(1)
}
// Get current value
func (pb *ProgressBar) Get() int64 {
c := atomic.LoadInt64(&pb.current)
return c
}
// Set current value
func (pb *ProgressBar) Set(current int) *ProgressBar {
return pb.Set64(int64(current))
}
// Set64 sets the current value as int64
func (pb *ProgressBar) Set64(current int64) *ProgressBar {
atomic.StoreInt64(&pb.current, current)
return pb
}
// Add to current value
func (pb *ProgressBar) Add(add int) int {
return int(pb.Add64(int64(add)))
}
func (pb *ProgressBar) Add64(add int64) int64 {
return atomic.AddInt64(&pb.current, add)
}
// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
pb.mu.Lock()
defer pb.mu.Unlock()
pb.prefix = prefix
return pb
}
// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
pb.mu.Lock()
defer pb.mu.Unlock()
pb.postfix = postfix
return pb
}
// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
var formatEntries []string
if utf8.RuneCountInString(format) == 5 {
formatEntries = strings.Split(format, "")
} else {
formatEntries = strings.Split(format, "\x00")
}
if len(formatEntries) == 5 {
pb.BarStart = formatEntries[0]
pb.BarEnd = formatEntries[4]
pb.Empty = formatEntries[3]
pb.Current = formatEntries[1]
pb.CurrentN = formatEntries[2]
}
return pb
}
// Set bar refresh rate
func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
pb.RefreshRate = rate
return pb
}
// Set units
// bar.SetUnits(U_NO) - by default
// bar.SetUnits(U_BYTES) - for Mb, Kb, etc
func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
pb.Units = units
return pb
}
// Set max width, if width is bigger than terminal width, will be ignored
func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
pb.Width = width
pb.ForceWidth = false
return pb
}
// Set bar width
func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
pb.Width = width
pb.ForceWidth = true
return pb
}
// End print
func (pb *ProgressBar) Finish() {
//Protect multiple calls
pb.finishOnce.Do(func() {
close(pb.finish)
pb.write(atomic.LoadInt64(&pb.Total), atomic.LoadInt64(&pb.current))
pb.mu.Lock()
defer pb.mu.Unlock()
switch {
case pb.Output != nil:
fmt.Fprintln(pb.Output)
case !pb.NotPrint:
fmt.Println()
}
pb.isFinish = true
})
}
// IsFinished return boolean
func (pb *ProgressBar) IsFinished() bool {
pb.mu.Lock()
defer pb.mu.Unlock()
return pb.isFinish
}
// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
pb.Finish()
if pb.Output != nil {
fmt.Fprintln(pb.Output, str)
} else {
fmt.Println(str)
}
}
// implement io.Writer
func (pb *ProgressBar) Write(p []byte) (n int, err error) {
n = len(p)
pb.Add(n)
return
}
// implement io.Reader
func (pb *ProgressBar) Read(p []byte) (n int, err error) {
n = len(p)
pb.Add(n)
return
}
// Create new proxy reader over bar
// Takes io.Reader or io.ReadCloser
func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
return &Reader{r, pb}
}
func (pb *ProgressBar) write(total, current int64) {
pb.mu.Lock()
defer pb.mu.Unlock()
width := pb.GetWidth()
var percentBox, countersBox, timeLeftBox, timeSpentBox, speedBox, barBox, end, out string
// percents
if pb.ShowPercent {
var percent float64
if total > 0 {
percent = float64(current) / (float64(total) / float64(100))
} else {
percent = float64(current) / float64(100)
}
percentBox = fmt.Sprintf(" %6.02f%%", percent)
}
// counters
if pb.ShowCounters {
current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
if total > 0 {
totalS := Format(total).To(pb.Units).Width(pb.UnitsWidth)
countersBox = fmt.Sprintf(" %s / %s ", current, totalS)
} else {
countersBox = fmt.Sprintf(" %s / ? ", current)
}
}
// time left
currentFromStart := current - pb.startValue
fromStart := time.Now().Sub(pb.startTime)
lastChangeTime := pb.changeTime
fromChange := lastChangeTime.Sub(pb.startTime)
if pb.ShowElapsedTime {
timeSpentBox = fmt.Sprintf(" %s ", (fromStart/time.Second)*time.Second)
}
select {
case <-pb.finish:
if pb.ShowFinalTime {
var left time.Duration
left = (fromStart / time.Second) * time.Second
timeLeftBox = fmt.Sprintf(" %s", left.String())
}
default:
if pb.ShowTimeLeft && currentFromStart > 0 {
perEntry := fromChange / time.Duration(currentFromStart)
var left time.Duration
if total > 0 {
left = time.Duration(total-current) * perEntry
left -= time.Since(lastChangeTime)
left = (left / time.Second) * time.Second
}
if left > 0 {
timeLeft := Format(int64(left)).To(U_DURATION).String()
timeLeftBox = fmt.Sprintf(" %s", timeLeft)
}
}
}
if len(timeLeftBox) < pb.TimeBoxWidth {
timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
}
// speed
if pb.ShowSpeed && currentFromStart > 0 {
fromStart := time.Now().Sub(pb.startTime)
speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String()
}
barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeSpentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
// bar
if pb.ShowBar {
size := width - barWidth
if size > 0 {
if total > 0 {
curSize := int(math.Ceil((float64(current) / float64(total)) * float64(size)))
emptySize := size - curSize
barBox = pb.BarStart
if emptySize < 0 {
emptySize = 0
}
if curSize > size {
curSize = size
}
cursorLen := escapeAwareRuneCountInString(pb.Current)
if emptySize <= 0 {
barBox += strings.Repeat(pb.Current, curSize/cursorLen)
} else if curSize > 0 {
cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN)
cursorRepetitions := (curSize - cursorEndLen) / cursorLen
barBox += strings.Repeat(pb.Current, cursorRepetitions)
barBox += pb.CurrentN
}
emptyLen := escapeAwareRuneCountInString(pb.Empty)
barBox += strings.Repeat(pb.Empty, emptySize/emptyLen)
barBox += pb.BarEnd
} else {
pos := size - int(current)%int(size)
barBox = pb.BarStart
if pos-1 > 0 {
barBox += strings.Repeat(pb.Empty, pos-1)
}
barBox += pb.Current
if size-pos-1 > 0 {
barBox += strings.Repeat(pb.Empty, size-pos-1)
}
barBox += pb.BarEnd
}
}
}
// check len
out = pb.prefix + timeSpentBox + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
if cl := escapeAwareRuneCountInString(out); cl < width {
end = strings.Repeat(" ", width-cl)
}
// and print!
pb.lastPrint = out + end
isFinish := pb.isFinish
switch {
case isFinish:
return
case pb.Output != nil:
fmt.Fprint(pb.Output, "\r"+out+end)
case pb.Callback != nil:
pb.Callback(out + end)
case !pb.NotPrint:
fmt.Print("\r" + out + end)
}
}
// GetTerminalWidth - returns terminal width for all platforms.
func GetTerminalWidth() (int, error) {
return terminalWidth()
}
func (pb *ProgressBar) GetWidth() int {
if pb.ForceWidth {
return pb.Width
}
width := pb.Width
termWidth, _ := terminalWidth()
if width == 0 || termWidth <= width {
width = termWidth
}
return width
}
// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
c := atomic.LoadInt64(&pb.current)
p := atomic.LoadInt64(&pb.previous)
t := atomic.LoadInt64(&pb.Total)
if p != c {
pb.mu.Lock()
pb.changeTime = time.Now()
pb.mu.Unlock()
atomic.StoreInt64(&pb.previous, c)
}
pb.write(t, c)
if pb.AutoStat {
if c == 0 {
pb.startTime = time.Now()
pb.startValue = 0
} else if c >= t && pb.isFinish != true {
pb.Finish()
}
}
}
// String return the last bar print
func (pb *ProgressBar) String() string {
pb.mu.Lock()
defer pb.mu.Unlock()
return pb.lastPrint
}
// SetTotal atomically sets new total count
func (pb *ProgressBar) SetTotal(total int) *ProgressBar {
return pb.SetTotal64(int64(total))
}
// SetTotal64 atomically sets new total count
func (pb *ProgressBar) SetTotal64(total int64) *ProgressBar {
atomic.StoreInt64(&pb.Total, total)
return pb
}
// Reset bar and set new total count
// Does effect only on finished bar
func (pb *ProgressBar) Reset(total int) *ProgressBar {
pb.mu.Lock()
defer pb.mu.Unlock()
if pb.isFinish {
pb.SetTotal(total).Set(0)
atomic.StoreInt64(&pb.previous, 0)
}
return pb
}
// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
for {
select {
case <-pb.finish:
return
case <-time.After(pb.RefreshRate):
pb.Update()
}
}
}

View File

@ -1,11 +0,0 @@
// +build appengine js
package pb
import "errors"
// terminalWidth returns width of the terminal, which is not supported
// and should always failed on appengine classic which is a sandboxed PaaS.
func terminalWidth() (int, error) {
return 0, errors.New("Not supported")
}

View File

@ -1,143 +0,0 @@
// +build windows
package pb
import (
"errors"
"fmt"
"os"
"sync"
"syscall"
"unsafe"
)
var tty = os.Stdin
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
// GetConsoleScreenBufferInfo retrieves information about the
// specified console screen buffer.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
// GetConsoleMode retrieves the current input mode of a console's
// input buffer or the current output mode of a console screen buffer.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
getConsoleMode = kernel32.NewProc("GetConsoleMode")
// SetConsoleMode sets the input mode of a console's input buffer
// or the output mode of a console screen buffer.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
setConsoleMode = kernel32.NewProc("SetConsoleMode")
// SetConsoleCursorPosition sets the cursor position in the
// specified console screen buffer.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx
setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
)
type (
// Defines the coordinates of the upper left and lower right corners
// of a rectangle.
// See
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
smallRect struct {
Left, Top, Right, Bottom int16
}
// Defines the coordinates of a character cell in a console screen
// buffer. The origin of the coordinate system (0,0) is at the top, left cell
// of the buffer.
// See
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
coordinates struct {
X, Y int16
}
word int16
// Contains information about a console screen buffer.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
consoleScreenBufferInfo struct {
dwSize coordinates
dwCursorPosition coordinates
wAttributes word
srWindow smallRect
dwMaximumWindowSize coordinates
}
)
// terminalWidth returns width of the terminal.
func terminalWidth() (width int, err error) {
var info consoleScreenBufferInfo
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
if e != 0 {
return 0, error(e)
}
return int(info.dwSize.X) - 1, nil
}
func getCursorPos() (pos coordinates, err error) {
var info consoleScreenBufferInfo
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
if e != 0 {
return info.dwCursorPosition, error(e)
}
return info.dwCursorPosition, nil
}
func setCursorPos(pos coordinates) error {
_, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0)
if e != 0 {
return error(e)
}
return nil
}
var ErrPoolWasStarted = errors.New("Bar pool was started")
var echoLocked bool
var echoLockMutex sync.Mutex
var oldState word
func lockEcho() (shutdownCh chan struct{}, err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if echoLocked {
err = ErrPoolWasStarted
return
}
echoLocked = true
if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 {
err = fmt.Errorf("Can't get terminal settings: %v", e)
return
}
newState := oldState
const ENABLE_ECHO_INPUT = 0x0004
const ENABLE_LINE_INPUT = 0x0002
newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))
if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 {
err = fmt.Errorf("Can't set terminal settings: %v", e)
return
}
shutdownCh = make(chan struct{})
return
}
func unlockEcho() (err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if !echoLocked {
return
}
echoLocked = false
if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 {
err = fmt.Errorf("Can't set terminal settings")
}
return
}

View File

@ -1,118 +0,0 @@
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
// +build !appengine !js
package pb
import (
"errors"
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"golang.org/x/sys/unix"
)
var ErrPoolWasStarted = errors.New("Bar pool was started")
var (
echoLockMutex sync.Mutex
origTermStatePtr *unix.Termios
tty *os.File
istty bool
)
func init() {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
var err error
tty, err = os.Open("/dev/tty")
istty = true
if err != nil {
tty = os.Stdin
istty = false
}
}
// terminalWidth returns width of the terminal.
func terminalWidth() (int, error) {
if !istty {
return 0, errors.New("Not Supported")
}
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
fd := int(tty.Fd())
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return 0, err
}
return int(ws.Col), nil
}
func lockEcho() (shutdownCh chan struct{}, err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if istty {
if origTermStatePtr != nil {
return shutdownCh, ErrPoolWasStarted
}
fd := int(tty.Fd())
origTermStatePtr, err = unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, fmt.Errorf("Can't get terminal settings: %v", err)
}
oldTermios := *origTermStatePtr
newTermios := oldTermios
newTermios.Lflag &^= syscall.ECHO
newTermios.Lflag |= syscall.ICANON | syscall.ISIG
newTermios.Iflag |= syscall.ICRNL
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil {
return nil, fmt.Errorf("Can't set terminal settings: %v", err)
}
}
shutdownCh = make(chan struct{})
go catchTerminate(shutdownCh)
return
}
func unlockEcho() error {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if istty {
if origTermStatePtr == nil {
return nil
}
fd := int(tty.Fd())
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil {
return fmt.Errorf("Can't set terminal settings: %v", err)
}
}
origTermStatePtr = nil
return nil
}
// listen exit signals and restore terminal state
func catchTerminate(shutdownCh chan struct{}) {
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
defer signal.Stop(sig)
select {
case <-shutdownCh:
unlockEcho()
case <-sig:
unlockEcho()
}
}

View File

@ -1,104 +0,0 @@
// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows
package pb
import (
"io"
"sync"
"time"
)
// Create and start new pool with given bars
// You need call pool.Stop() after work
func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
pool = new(Pool)
if err = pool.Start(); err != nil {
return
}
pool.Add(pbs...)
return
}
// NewPool initialises a pool with progress bars, but
// doesn't start it. You need to call Start manually
func NewPool(pbs ...*ProgressBar) (pool *Pool) {
pool = new(Pool)
pool.Add(pbs...)
return
}
type Pool struct {
Output io.Writer
RefreshRate time.Duration
bars []*ProgressBar
lastBarsCount int
shutdownCh chan struct{}
workerCh chan struct{}
m sync.Mutex
finishOnce sync.Once
}
// Add progress bars.
func (p *Pool) Add(pbs ...*ProgressBar) {
p.m.Lock()
defer p.m.Unlock()
for _, bar := range pbs {
bar.ManualUpdate = true
bar.NotPrint = true
bar.Start()
p.bars = append(p.bars, bar)
}
}
func (p *Pool) Start() (err error) {
p.RefreshRate = DefaultRefreshRate
p.shutdownCh, err = lockEcho()
if err != nil {
return
}
p.workerCh = make(chan struct{})
go p.writer()
return
}
func (p *Pool) writer() {
var first = true
defer func() {
if first == false {
p.print(false)
} else {
p.print(true)
p.print(false)
}
close(p.workerCh)
}()
for {
select {
case <-time.After(p.RefreshRate):
if p.print(first) {
p.print(false)
return
}
first = false
case <-p.shutdownCh:
return
}
}
}
// Restore terminal state and close pool
func (p *Pool) Stop() error {
p.finishOnce.Do(func() {
if p.shutdownCh != nil {
close(p.shutdownCh)
}
})
// Wait for the worker to complete
select {
case <-p.workerCh:
}
return unlockEcho()
}

View File

@ -1,45 +0,0 @@
// +build windows
package pb
import (
"fmt"
"log"
)
func (p *Pool) print(first bool) bool {
p.m.Lock()
defer p.m.Unlock()
var out string
if !first {
coords, err := getCursorPos()
if err != nil {
log.Panic(err)
}
coords.Y -= int16(p.lastBarsCount)
if coords.Y < 0 {
coords.Y = 0
}
coords.X = 0
err = setCursorPos(coords)
if err != nil {
log.Panic(err)
}
}
isFinished := true
for _, bar := range p.bars {
if !bar.IsFinished() {
isFinished = false
}
bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String())
}
if p.Output != nil {
fmt.Fprint(p.Output, out)
} else {
fmt.Print(out)
}
p.lastBarsCount = len(p.bars)
return isFinished
}

View File

@ -1,29 +0,0 @@
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
package pb
import "fmt"
func (p *Pool) print(first bool) bool {
p.m.Lock()
defer p.m.Unlock()
var out string
if !first {
out = fmt.Sprintf("\033[%dA", p.lastBarsCount)
}
isFinished := true
for _, bar := range p.bars {
if !bar.IsFinished() {
isFinished = false
}
bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String())
}
if p.Output != nil {
fmt.Fprint(p.Output, out)
} else {
fmt.Print(out)
}
p.lastBarsCount = len(p.bars)
return isFinished
}

View File

@ -1,25 +0,0 @@
package pb
import (
"io"
)
// It's proxy reader, implement io.Reader
type Reader struct {
io.Reader
bar *ProgressBar
}
func (r *Reader) Read(p []byte) (n int, err error) {
n, err = r.Reader.Read(p)
r.bar.Add(n)
return
}
// Close the reader when it implements io.Closer
func (r *Reader) Close() (err error) {
if closer, ok := r.Reader.(io.Closer); ok {
return closer.Close()
}
return
}

View File

@ -1,17 +0,0 @@
package pb
import (
"github.com/mattn/go-runewidth"
"regexp"
)
// Finds the control character sequences (like colors)
var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d")
func escapeAwareRuneCountInString(s string) int {
n := runewidth.StringWidth(s)
for _, sm := range ctrlFinder.FindAllString(s, -1) {
n -= runewidth.StringWidth(sm)
}
return n
}

View File

@ -1,9 +0,0 @@
// +build darwin freebsd netbsd openbsd dragonfly
// +build !appengine
package pb
import "syscall"
const ioctlReadTermios = syscall.TIOCGETA
const ioctlWriteTermios = syscall.TIOCSETA

View File

@ -1,13 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux solaris
// +build !appengine
package pb
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS

201
vendor/k8s.io/metrics/LICENSE generated vendored
View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,19 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +groupName=metrics.k8s.io
package metrics

View File

@ -1,53 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "metrics.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&NodeMetrics{},
&NodeMetricsList{},
&PodMetrics{},
&PodMetricsList{},
)
return nil
}

View File

@ -1,95 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +resourceName=nodes
// +genclient:readonly
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a node.
type NodeMetrics struct {
metav1.TypeMeta
metav1.ObjectMeta
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time
Window metav1.Duration
// The memory usage is the memory working set.
Usage corev1.ResourceList
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeMetricsList is a list of NodeMetrics.
type NodeMetricsList struct {
metav1.TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta
// List of node metrics.
Items []NodeMetrics
}
// +genclient
// +resourceName=pods
// +genclient:readonly
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a pod.
type PodMetrics struct {
metav1.TypeMeta
metav1.ObjectMeta
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time
Window metav1.Duration
// Metrics for all containers are collected within the same time window.
Containers []ContainerMetrics
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodMetricsList is a list of PodMetrics.
type PodMetricsList struct {
metav1.TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta
// List of pod metrics.
Items []PodMetrics
}
// resource usage metrics of a container.
type ContainerMetrics struct {
// Container name corresponding to the one from pod.spec.containers.
Name string
// The memory usage is the memory working set.
Usage corev1.ResourceList
}

View File

@ -1,21 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/metrics
// +k8s:openapi-gen=true
package v1alpha1

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
syntax = 'proto2';
package k8s.io.metrics.pkg.apis.metrics.v1alpha1;
import "k8s.io/api/core/v1/generated.proto";
import "k8s.io/apimachinery/pkg/api/resource/generated.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "v1alpha1";
// resource usage metrics of a container.
message ContainerMetrics {
// Container name corresponding to the one from pod.spec.containers.
optional string name = 1;
// The memory usage is the memory working set.
map<string, k8s.io.apimachinery.pkg.api.resource.Quantity> usage = 2;
}
// resource usage metrics of a node.
message NodeMetrics {
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time timestamp = 2;
optional k8s.io.apimachinery.pkg.apis.meta.v1.Duration window = 3;
// The memory usage is the memory working set.
map<string, k8s.io.apimachinery.pkg.api.resource.Quantity> usage = 4;
}
// NodeMetricsList is a list of NodeMetrics.
message NodeMetricsList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
// List of node metrics.
repeated NodeMetrics items = 2;
}
// resource usage metrics of a pod.
message PodMetrics {
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time timestamp = 2;
optional k8s.io.apimachinery.pkg.apis.meta.v1.Duration window = 3;
// Metrics for all containers are collected within the same time window.
repeated ContainerMetrics containers = 4;
}
// PodMetricsList is a list of PodMetrics.
message PodMetricsList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
// List of pod metrics.
repeated PodMetrics items = 2;
}

View File

@ -1,51 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "metrics.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
localSchemeBuilder = &SchemeBuilder
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&NodeMetrics{},
&NodeMetricsList{},
&PodMetrics{},
&PodMetricsList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -1,95 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +resourceName=nodes
// +genclient:readonly
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a node.
type NodeMetrics struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time `json:"timestamp" protobuf:"bytes,2,opt,name=timestamp"`
Window metav1.Duration `json:"window" protobuf:"bytes,3,opt,name=window"`
// The memory usage is the memory working set.
Usage v1.ResourceList `json:"usage" protobuf:"bytes,4,rep,name=usage,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeMetricsList is a list of NodeMetrics.
type NodeMetricsList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of node metrics.
Items []NodeMetrics `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient
// +resourceName=pods
// +genclient:readonly
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a pod.
type PodMetrics struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time `json:"timestamp" protobuf:"bytes,2,opt,name=timestamp"`
Window metav1.Duration `json:"window" protobuf:"bytes,3,opt,name=window"`
// Metrics for all containers are collected within the same time window.
Containers []ContainerMetrics `json:"containers" protobuf:"bytes,4,rep,name=containers"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodMetricsList is a list of PodMetrics.
type PodMetricsList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of pod metrics.
Items []PodMetrics `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// resource usage metrics of a container.
type ContainerMetrics struct {
// Container name corresponding to the one from pod.spec.containers.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// The memory usage is the memory working set.
Usage v1.ResourceList `json:"usage" protobuf:"bytes,2,rep,name=usage,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"`
}

View File

@ -1,169 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by conversion-gen. DO NOT EDIT.
package v1alpha1
import (
unsafe "unsafe"
v1 "k8s.io/api/core/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
metrics "k8s.io/metrics/pkg/apis/metrics"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_v1alpha1_ContainerMetrics_To_metrics_ContainerMetrics,
Convert_metrics_ContainerMetrics_To_v1alpha1_ContainerMetrics,
Convert_v1alpha1_NodeMetrics_To_metrics_NodeMetrics,
Convert_metrics_NodeMetrics_To_v1alpha1_NodeMetrics,
Convert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList,
Convert_metrics_NodeMetricsList_To_v1alpha1_NodeMetricsList,
Convert_v1alpha1_PodMetrics_To_metrics_PodMetrics,
Convert_metrics_PodMetrics_To_v1alpha1_PodMetrics,
Convert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList,
Convert_metrics_PodMetricsList_To_v1alpha1_PodMetricsList,
)
}
func autoConvert_v1alpha1_ContainerMetrics_To_metrics_ContainerMetrics(in *ContainerMetrics, out *metrics.ContainerMetrics, s conversion.Scope) error {
out.Name = in.Name
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_v1alpha1_ContainerMetrics_To_metrics_ContainerMetrics is an autogenerated conversion function.
func Convert_v1alpha1_ContainerMetrics_To_metrics_ContainerMetrics(in *ContainerMetrics, out *metrics.ContainerMetrics, s conversion.Scope) error {
return autoConvert_v1alpha1_ContainerMetrics_To_metrics_ContainerMetrics(in, out, s)
}
func autoConvert_metrics_ContainerMetrics_To_v1alpha1_ContainerMetrics(in *metrics.ContainerMetrics, out *ContainerMetrics, s conversion.Scope) error {
out.Name = in.Name
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_metrics_ContainerMetrics_To_v1alpha1_ContainerMetrics is an autogenerated conversion function.
func Convert_metrics_ContainerMetrics_To_v1alpha1_ContainerMetrics(in *metrics.ContainerMetrics, out *ContainerMetrics, s conversion.Scope) error {
return autoConvert_metrics_ContainerMetrics_To_v1alpha1_ContainerMetrics(in, out, s)
}
func autoConvert_v1alpha1_NodeMetrics_To_metrics_NodeMetrics(in *NodeMetrics, out *metrics.NodeMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_v1alpha1_NodeMetrics_To_metrics_NodeMetrics is an autogenerated conversion function.
func Convert_v1alpha1_NodeMetrics_To_metrics_NodeMetrics(in *NodeMetrics, out *metrics.NodeMetrics, s conversion.Scope) error {
return autoConvert_v1alpha1_NodeMetrics_To_metrics_NodeMetrics(in, out, s)
}
func autoConvert_metrics_NodeMetrics_To_v1alpha1_NodeMetrics(in *metrics.NodeMetrics, out *NodeMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_metrics_NodeMetrics_To_v1alpha1_NodeMetrics is an autogenerated conversion function.
func Convert_metrics_NodeMetrics_To_v1alpha1_NodeMetrics(in *metrics.NodeMetrics, out *NodeMetrics, s conversion.Scope) error {
return autoConvert_metrics_NodeMetrics_To_v1alpha1_NodeMetrics(in, out, s)
}
func autoConvert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList(in *NodeMetricsList, out *metrics.NodeMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]metrics.NodeMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList is an autogenerated conversion function.
func Convert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList(in *NodeMetricsList, out *metrics.NodeMetricsList, s conversion.Scope) error {
return autoConvert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList(in, out, s)
}
func autoConvert_metrics_NodeMetricsList_To_v1alpha1_NodeMetricsList(in *metrics.NodeMetricsList, out *NodeMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]NodeMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_metrics_NodeMetricsList_To_v1alpha1_NodeMetricsList is an autogenerated conversion function.
func Convert_metrics_NodeMetricsList_To_v1alpha1_NodeMetricsList(in *metrics.NodeMetricsList, out *NodeMetricsList, s conversion.Scope) error {
return autoConvert_metrics_NodeMetricsList_To_v1alpha1_NodeMetricsList(in, out, s)
}
func autoConvert_v1alpha1_PodMetrics_To_metrics_PodMetrics(in *PodMetrics, out *metrics.PodMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Containers = *(*[]metrics.ContainerMetrics)(unsafe.Pointer(&in.Containers))
return nil
}
// Convert_v1alpha1_PodMetrics_To_metrics_PodMetrics is an autogenerated conversion function.
func Convert_v1alpha1_PodMetrics_To_metrics_PodMetrics(in *PodMetrics, out *metrics.PodMetrics, s conversion.Scope) error {
return autoConvert_v1alpha1_PodMetrics_To_metrics_PodMetrics(in, out, s)
}
func autoConvert_metrics_PodMetrics_To_v1alpha1_PodMetrics(in *metrics.PodMetrics, out *PodMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Containers = *(*[]ContainerMetrics)(unsafe.Pointer(&in.Containers))
return nil
}
// Convert_metrics_PodMetrics_To_v1alpha1_PodMetrics is an autogenerated conversion function.
func Convert_metrics_PodMetrics_To_v1alpha1_PodMetrics(in *metrics.PodMetrics, out *PodMetrics, s conversion.Scope) error {
return autoConvert_metrics_PodMetrics_To_v1alpha1_PodMetrics(in, out, s)
}
func autoConvert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList(in *PodMetricsList, out *metrics.PodMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]metrics.PodMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList is an autogenerated conversion function.
func Convert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList(in *PodMetricsList, out *metrics.PodMetricsList, s conversion.Scope) error {
return autoConvert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList(in, out, s)
}
func autoConvert_metrics_PodMetricsList_To_v1alpha1_PodMetricsList(in *metrics.PodMetricsList, out *PodMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]PodMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_metrics_PodMetricsList_To_v1alpha1_PodMetricsList is an autogenerated conversion function.
func Convert_metrics_PodMetricsList_To_v1alpha1_PodMetricsList(in *metrics.PodMetricsList, out *PodMetricsList, s conversion.Scope) error {
return autoConvert_metrics_PodMetricsList_To_v1alpha1_PodMetricsList(in, out, s)
}

View File

@ -1,185 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerMetrics) DeepCopyInto(out *ContainerMetrics) {
*out = *in
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerMetrics.
func (in *ContainerMetrics) DeepCopy() *ContainerMetrics {
if in == nil {
return nil
}
out := new(ContainerMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetrics) DeepCopyInto(out *NodeMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetrics.
func (in *NodeMetrics) DeepCopy() *NodeMetrics {
if in == nil {
return nil
}
out := new(NodeMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetricsList) DeepCopyInto(out *NodeMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]NodeMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetricsList.
func (in *NodeMetricsList) DeepCopy() *NodeMetricsList {
if in == nil {
return nil
}
out := new(NodeMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetrics) DeepCopyInto(out *PodMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Containers != nil {
in, out := &in.Containers, &out.Containers
*out = make([]ContainerMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetrics.
func (in *PodMetrics) DeepCopy() *PodMetrics {
if in == nil {
return nil
}
out := new(PodMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetricsList) DeepCopyInto(out *PodMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PodMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetricsList.
func (in *PodMetricsList) DeepCopy() *PodMetricsList {
if in == nil {
return nil
}
out := new(PodMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -1,21 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/metrics/pkg/apis/metrics
// +k8s:openapi-gen=true
package v1beta1

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
syntax = 'proto2';
package k8s.io.metrics.pkg.apis.metrics.v1beta1;
import "k8s.io/api/core/v1/generated.proto";
import "k8s.io/apimachinery/pkg/api/resource/generated.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/generated.proto";
import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "v1beta1";
// resource usage metrics of a container.
message ContainerMetrics {
// Container name corresponding to the one from pod.spec.containers.
optional string name = 1;
// The memory usage is the memory working set.
map<string, k8s.io.apimachinery.pkg.api.resource.Quantity> usage = 2;
}
// resource usage metrics of a node.
message NodeMetrics {
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time timestamp = 2;
optional k8s.io.apimachinery.pkg.apis.meta.v1.Duration window = 3;
// The memory usage is the memory working set.
map<string, k8s.io.apimachinery.pkg.api.resource.Quantity> usage = 4;
}
// NodeMetricsList is a list of NodeMetrics.
message NodeMetricsList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
// List of node metrics.
repeated NodeMetrics items = 2;
}
// resource usage metrics of a pod.
message PodMetrics {
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
optional k8s.io.apimachinery.pkg.apis.meta.v1.Time timestamp = 2;
optional k8s.io.apimachinery.pkg.apis.meta.v1.Duration window = 3;
// Metrics for all containers are collected within the same time window.
repeated ContainerMetrics containers = 4;
}
// PodMetricsList is a list of PodMetrics.
message PodMetricsList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
// List of pod metrics.
repeated PodMetrics items = 2;
}

View File

@ -1,51 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "metrics.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
localSchemeBuilder = &SchemeBuilder
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&NodeMetrics{},
&NodeMetricsList{},
&PodMetrics{},
&PodMetricsList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -1,95 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +resourceName=nodes
// +genclient:readonly
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a node.
type NodeMetrics struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time `json:"timestamp" protobuf:"bytes,2,opt,name=timestamp"`
Window metav1.Duration `json:"window" protobuf:"bytes,3,opt,name=window"`
// The memory usage is the memory working set.
Usage v1.ResourceList `json:"usage" protobuf:"bytes,4,rep,name=usage,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeMetricsList is a list of NodeMetrics.
type NodeMetricsList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of node metrics.
Items []NodeMetrics `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient
// +resourceName=pods
// +genclient:readonly
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// resource usage metrics of a pod.
type PodMetrics struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// The following fields define time interval from which metrics were
// collected from the interval [Timestamp-Window, Timestamp].
Timestamp metav1.Time `json:"timestamp" protobuf:"bytes,2,opt,name=timestamp"`
Window metav1.Duration `json:"window" protobuf:"bytes,3,opt,name=window"`
// Metrics for all containers are collected within the same time window.
Containers []ContainerMetrics `json:"containers" protobuf:"bytes,4,rep,name=containers"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodMetricsList is a list of PodMetrics.
type PodMetricsList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of pod metrics.
Items []PodMetrics `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// resource usage metrics of a container.
type ContainerMetrics struct {
// Container name corresponding to the one from pod.spec.containers.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// The memory usage is the memory working set.
Usage v1.ResourceList `json:"usage" protobuf:"bytes,2,rep,name=usage,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"`
}

View File

@ -1,169 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by conversion-gen. DO NOT EDIT.
package v1beta1
import (
unsafe "unsafe"
v1 "k8s.io/api/core/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
metrics "k8s.io/metrics/pkg/apis/metrics"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_v1beta1_ContainerMetrics_To_metrics_ContainerMetrics,
Convert_metrics_ContainerMetrics_To_v1beta1_ContainerMetrics,
Convert_v1beta1_NodeMetrics_To_metrics_NodeMetrics,
Convert_metrics_NodeMetrics_To_v1beta1_NodeMetrics,
Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList,
Convert_metrics_NodeMetricsList_To_v1beta1_NodeMetricsList,
Convert_v1beta1_PodMetrics_To_metrics_PodMetrics,
Convert_metrics_PodMetrics_To_v1beta1_PodMetrics,
Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList,
Convert_metrics_PodMetricsList_To_v1beta1_PodMetricsList,
)
}
func autoConvert_v1beta1_ContainerMetrics_To_metrics_ContainerMetrics(in *ContainerMetrics, out *metrics.ContainerMetrics, s conversion.Scope) error {
out.Name = in.Name
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_v1beta1_ContainerMetrics_To_metrics_ContainerMetrics is an autogenerated conversion function.
func Convert_v1beta1_ContainerMetrics_To_metrics_ContainerMetrics(in *ContainerMetrics, out *metrics.ContainerMetrics, s conversion.Scope) error {
return autoConvert_v1beta1_ContainerMetrics_To_metrics_ContainerMetrics(in, out, s)
}
func autoConvert_metrics_ContainerMetrics_To_v1beta1_ContainerMetrics(in *metrics.ContainerMetrics, out *ContainerMetrics, s conversion.Scope) error {
out.Name = in.Name
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_metrics_ContainerMetrics_To_v1beta1_ContainerMetrics is an autogenerated conversion function.
func Convert_metrics_ContainerMetrics_To_v1beta1_ContainerMetrics(in *metrics.ContainerMetrics, out *ContainerMetrics, s conversion.Scope) error {
return autoConvert_metrics_ContainerMetrics_To_v1beta1_ContainerMetrics(in, out, s)
}
func autoConvert_v1beta1_NodeMetrics_To_metrics_NodeMetrics(in *NodeMetrics, out *metrics.NodeMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_v1beta1_NodeMetrics_To_metrics_NodeMetrics is an autogenerated conversion function.
func Convert_v1beta1_NodeMetrics_To_metrics_NodeMetrics(in *NodeMetrics, out *metrics.NodeMetrics, s conversion.Scope) error {
return autoConvert_v1beta1_NodeMetrics_To_metrics_NodeMetrics(in, out, s)
}
func autoConvert_metrics_NodeMetrics_To_v1beta1_NodeMetrics(in *metrics.NodeMetrics, out *NodeMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Usage = *(*v1.ResourceList)(unsafe.Pointer(&in.Usage))
return nil
}
// Convert_metrics_NodeMetrics_To_v1beta1_NodeMetrics is an autogenerated conversion function.
func Convert_metrics_NodeMetrics_To_v1beta1_NodeMetrics(in *metrics.NodeMetrics, out *NodeMetrics, s conversion.Scope) error {
return autoConvert_metrics_NodeMetrics_To_v1beta1_NodeMetrics(in, out, s)
}
func autoConvert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(in *NodeMetricsList, out *metrics.NodeMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]metrics.NodeMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList is an autogenerated conversion function.
func Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(in *NodeMetricsList, out *metrics.NodeMetricsList, s conversion.Scope) error {
return autoConvert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(in, out, s)
}
func autoConvert_metrics_NodeMetricsList_To_v1beta1_NodeMetricsList(in *metrics.NodeMetricsList, out *NodeMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]NodeMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_metrics_NodeMetricsList_To_v1beta1_NodeMetricsList is an autogenerated conversion function.
func Convert_metrics_NodeMetricsList_To_v1beta1_NodeMetricsList(in *metrics.NodeMetricsList, out *NodeMetricsList, s conversion.Scope) error {
return autoConvert_metrics_NodeMetricsList_To_v1beta1_NodeMetricsList(in, out, s)
}
func autoConvert_v1beta1_PodMetrics_To_metrics_PodMetrics(in *PodMetrics, out *metrics.PodMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Containers = *(*[]metrics.ContainerMetrics)(unsafe.Pointer(&in.Containers))
return nil
}
// Convert_v1beta1_PodMetrics_To_metrics_PodMetrics is an autogenerated conversion function.
func Convert_v1beta1_PodMetrics_To_metrics_PodMetrics(in *PodMetrics, out *metrics.PodMetrics, s conversion.Scope) error {
return autoConvert_v1beta1_PodMetrics_To_metrics_PodMetrics(in, out, s)
}
func autoConvert_metrics_PodMetrics_To_v1beta1_PodMetrics(in *metrics.PodMetrics, out *PodMetrics, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.Timestamp = in.Timestamp
out.Window = in.Window
out.Containers = *(*[]ContainerMetrics)(unsafe.Pointer(&in.Containers))
return nil
}
// Convert_metrics_PodMetrics_To_v1beta1_PodMetrics is an autogenerated conversion function.
func Convert_metrics_PodMetrics_To_v1beta1_PodMetrics(in *metrics.PodMetrics, out *PodMetrics, s conversion.Scope) error {
return autoConvert_metrics_PodMetrics_To_v1beta1_PodMetrics(in, out, s)
}
func autoConvert_v1beta1_PodMetricsList_To_metrics_PodMetricsList(in *PodMetricsList, out *metrics.PodMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]metrics.PodMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList is an autogenerated conversion function.
func Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList(in *PodMetricsList, out *metrics.PodMetricsList, s conversion.Scope) error {
return autoConvert_v1beta1_PodMetricsList_To_metrics_PodMetricsList(in, out, s)
}
func autoConvert_metrics_PodMetricsList_To_v1beta1_PodMetricsList(in *metrics.PodMetricsList, out *PodMetricsList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]PodMetrics)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_metrics_PodMetricsList_To_v1beta1_PodMetricsList is an autogenerated conversion function.
func Convert_metrics_PodMetricsList_To_v1beta1_PodMetricsList(in *metrics.PodMetricsList, out *PodMetricsList, s conversion.Scope) error {
return autoConvert_metrics_PodMetricsList_To_v1beta1_PodMetricsList(in, out, s)
}

View File

@ -1,185 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1beta1
import (
v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerMetrics) DeepCopyInto(out *ContainerMetrics) {
*out = *in
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerMetrics.
func (in *ContainerMetrics) DeepCopy() *ContainerMetrics {
if in == nil {
return nil
}
out := new(ContainerMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetrics) DeepCopyInto(out *NodeMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetrics.
func (in *NodeMetrics) DeepCopy() *NodeMetrics {
if in == nil {
return nil
}
out := new(NodeMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetricsList) DeepCopyInto(out *NodeMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]NodeMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetricsList.
func (in *NodeMetricsList) DeepCopy() *NodeMetricsList {
if in == nil {
return nil
}
out := new(NodeMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetrics) DeepCopyInto(out *PodMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Containers != nil {
in, out := &in.Containers, &out.Containers
*out = make([]ContainerMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetrics.
func (in *PodMetrics) DeepCopy() *PodMetrics {
if in == nil {
return nil
}
out := new(PodMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetricsList) DeepCopyInto(out *PodMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PodMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetricsList.
func (in *PodMetricsList) DeepCopy() *PodMetricsList {
if in == nil {
return nil
}
out := new(PodMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -1,185 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package metrics
import (
v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerMetrics) DeepCopyInto(out *ContainerMetrics) {
*out = *in
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerMetrics.
func (in *ContainerMetrics) DeepCopy() *ContainerMetrics {
if in == nil {
return nil
}
out := new(ContainerMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetrics) DeepCopyInto(out *NodeMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Usage != nil {
in, out := &in.Usage, &out.Usage
*out = make(v1.ResourceList, len(*in))
for key, val := range *in {
(*out)[key] = val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetrics.
func (in *NodeMetrics) DeepCopy() *NodeMetrics {
if in == nil {
return nil
}
out := new(NodeMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetricsList) DeepCopyInto(out *NodeMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]NodeMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetricsList.
func (in *NodeMetricsList) DeepCopy() *NodeMetricsList {
if in == nil {
return nil
}
out := new(NodeMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *NodeMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetrics) DeepCopyInto(out *PodMetrics) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Timestamp.DeepCopyInto(&out.Timestamp)
out.Window = in.Window
if in.Containers != nil {
in, out := &in.Containers, &out.Containers
*out = make([]ContainerMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetrics.
func (in *PodMetrics) DeepCopy() *PodMetrics {
if in == nil {
return nil
}
out := new(PodMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetrics) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodMetricsList) DeepCopyInto(out *PodMetricsList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PodMetrics, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodMetricsList.
func (in *PodMetricsList) DeepCopy() *PodMetricsList {
if in == nil {
return nil
}
out := new(PodMetricsList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodMetricsList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -1,112 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package clientset
import (
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
metricsv1alpha1 "k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1alpha1"
metricsv1beta1 "k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1beta1"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
MetricsV1alpha1() metricsv1alpha1.MetricsV1alpha1Interface
MetricsV1beta1() metricsv1beta1.MetricsV1beta1Interface
// Deprecated: please explicitly pick a version if possible.
Metrics() metricsv1beta1.MetricsV1beta1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
metricsV1alpha1 *metricsv1alpha1.MetricsV1alpha1Client
metricsV1beta1 *metricsv1beta1.MetricsV1beta1Client
}
// MetricsV1alpha1 retrieves the MetricsV1alpha1Client
func (c *Clientset) MetricsV1alpha1() metricsv1alpha1.MetricsV1alpha1Interface {
return c.metricsV1alpha1
}
// MetricsV1beta1 retrieves the MetricsV1beta1Client
func (c *Clientset) MetricsV1beta1() metricsv1beta1.MetricsV1beta1Interface {
return c.metricsV1beta1
}
// Deprecated: Metrics retrieves the default version of MetricsClient.
// Please explicitly pick a version.
func (c *Clientset) Metrics() metricsv1beta1.MetricsV1beta1Interface {
return c.metricsV1beta1
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.metricsV1alpha1, err = metricsv1alpha1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.metricsV1beta1, err = metricsv1beta1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.metricsV1alpha1 = metricsv1alpha1.NewForConfigOrDie(c)
cs.metricsV1beta1 = metricsv1beta1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
}
// New creates a new Clientset for the given RESTClient.
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.metricsV1alpha1 = metricsv1alpha1.New(c)
cs.metricsV1beta1 = metricsv1beta1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}

View File

@ -1,20 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated clientset.
package clientset

View File

@ -1,20 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package contains the scheme of the automatically generated clientset.
package scheme

View File

@ -1,56 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package scheme
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
metricsv1alpha1 "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
metricsv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
)
var Scheme = runtime.NewScheme()
var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
AddToScheme(Scheme)
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
func AddToScheme(scheme *runtime.Scheme) {
metricsv1alpha1.AddToScheme(scheme)
metricsv1beta1.AddToScheme(scheme)
}

View File

@ -1,20 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1alpha1

View File

@ -1,23 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
type NodeMetricsExpansion interface{}
type PodMetricsExpansion interface{}

View File

@ -1,95 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
rest "k8s.io/client-go/rest"
v1alpha1 "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
"k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
type MetricsV1alpha1Interface interface {
RESTClient() rest.Interface
NodeMetricsesGetter
PodMetricsesGetter
}
// MetricsV1alpha1Client is used to interact with features provided by the metrics group.
type MetricsV1alpha1Client struct {
restClient rest.Interface
}
func (c *MetricsV1alpha1Client) NodeMetricses() NodeMetricsInterface {
return newNodeMetricses(c)
}
func (c *MetricsV1alpha1Client) PodMetricses(namespace string) PodMetricsInterface {
return newPodMetricses(c, namespace)
}
// NewForConfig creates a new MetricsV1alpha1Client for the given config.
func NewForConfig(c *rest.Config) (*MetricsV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &MetricsV1alpha1Client{client}, nil
}
// NewForConfigOrDie creates a new MetricsV1alpha1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *MetricsV1alpha1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new MetricsV1alpha1Client for the given RESTClient.
func New(c rest.Interface) *MetricsV1alpha1Client {
return &MetricsV1alpha1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *MetricsV1alpha1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@ -1,85 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1alpha1 "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
scheme "k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
// NodeMetricsesGetter has a method to return a NodeMetricsInterface.
// A group's client should implement this interface.
type NodeMetricsesGetter interface {
NodeMetricses() NodeMetricsInterface
}
// NodeMetricsInterface has methods to work with NodeMetrics resources.
type NodeMetricsInterface interface {
Get(name string, options v1.GetOptions) (*v1alpha1.NodeMetrics, error)
List(opts v1.ListOptions) (*v1alpha1.NodeMetricsList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
NodeMetricsExpansion
}
// nodeMetricses implements NodeMetricsInterface
type nodeMetricses struct {
client rest.Interface
}
// newNodeMetricses returns a NodeMetricses
func newNodeMetricses(c *MetricsV1alpha1Client) *nodeMetricses {
return &nodeMetricses{
client: c.RESTClient(),
}
}
// Get takes name of the nodeMetrics, and returns the corresponding nodeMetrics object, and an error if there is any.
func (c *nodeMetricses) Get(name string, options v1.GetOptions) (result *v1alpha1.NodeMetrics, err error) {
result = &v1alpha1.NodeMetrics{}
err = c.client.Get().
Resource("nodes").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of NodeMetricses that match those selectors.
func (c *nodeMetricses) List(opts v1.ListOptions) (result *v1alpha1.NodeMetricsList, err error) {
result = &v1alpha1.NodeMetricsList{}
err = c.client.Get().
Resource("nodes").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested nodeMetricses.
func (c *nodeMetricses) Watch(opts v1.ListOptions) (watch.Interface, error) {
opts.Watch = true
return c.client.Get().
Resource("nodes").
VersionedParams(&opts, scheme.ParameterCodec).
Watch()
}

View File

@ -1,90 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1alpha1 "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
scheme "k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
// PodMetricsesGetter has a method to return a PodMetricsInterface.
// A group's client should implement this interface.
type PodMetricsesGetter interface {
PodMetricses(namespace string) PodMetricsInterface
}
// PodMetricsInterface has methods to work with PodMetrics resources.
type PodMetricsInterface interface {
Get(name string, options v1.GetOptions) (*v1alpha1.PodMetrics, error)
List(opts v1.ListOptions) (*v1alpha1.PodMetricsList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
PodMetricsExpansion
}
// podMetricses implements PodMetricsInterface
type podMetricses struct {
client rest.Interface
ns string
}
// newPodMetricses returns a PodMetricses
func newPodMetricses(c *MetricsV1alpha1Client, namespace string) *podMetricses {
return &podMetricses{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the podMetrics, and returns the corresponding podMetrics object, and an error if there is any.
func (c *podMetricses) Get(name string, options v1.GetOptions) (result *v1alpha1.PodMetrics, err error) {
result = &v1alpha1.PodMetrics{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of PodMetricses that match those selectors.
func (c *podMetricses) List(opts v1.ListOptions) (result *v1alpha1.PodMetricsList, err error) {
result = &v1alpha1.PodMetricsList{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested podMetricses.
func (c *podMetricses) Watch(opts v1.ListOptions) (watch.Interface, error) {
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Watch()
}

View File

@ -1,20 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1beta1

View File

@ -1,23 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
type NodeMetricsExpansion interface{}
type PodMetricsExpansion interface{}

View File

@ -1,95 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
rest "k8s.io/client-go/rest"
v1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
"k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
type MetricsV1beta1Interface interface {
RESTClient() rest.Interface
NodeMetricsesGetter
PodMetricsesGetter
}
// MetricsV1beta1Client is used to interact with features provided by the metrics group.
type MetricsV1beta1Client struct {
restClient rest.Interface
}
func (c *MetricsV1beta1Client) NodeMetricses() NodeMetricsInterface {
return newNodeMetricses(c)
}
func (c *MetricsV1beta1Client) PodMetricses(namespace string) PodMetricsInterface {
return newPodMetricses(c, namespace)
}
// NewForConfig creates a new MetricsV1beta1Client for the given config.
func NewForConfig(c *rest.Config) (*MetricsV1beta1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &MetricsV1beta1Client{client}, nil
}
// NewForConfigOrDie creates a new MetricsV1beta1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *MetricsV1beta1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new MetricsV1beta1Client for the given RESTClient.
func New(c rest.Interface) *MetricsV1beta1Client {
return &MetricsV1beta1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1beta1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *MetricsV1beta1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@ -1,85 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
scheme "k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
// NodeMetricsesGetter has a method to return a NodeMetricsInterface.
// A group's client should implement this interface.
type NodeMetricsesGetter interface {
NodeMetricses() NodeMetricsInterface
}
// NodeMetricsInterface has methods to work with NodeMetrics resources.
type NodeMetricsInterface interface {
Get(name string, options v1.GetOptions) (*v1beta1.NodeMetrics, error)
List(opts v1.ListOptions) (*v1beta1.NodeMetricsList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
NodeMetricsExpansion
}
// nodeMetricses implements NodeMetricsInterface
type nodeMetricses struct {
client rest.Interface
}
// newNodeMetricses returns a NodeMetricses
func newNodeMetricses(c *MetricsV1beta1Client) *nodeMetricses {
return &nodeMetricses{
client: c.RESTClient(),
}
}
// Get takes name of the nodeMetrics, and returns the corresponding nodeMetrics object, and an error if there is any.
func (c *nodeMetricses) Get(name string, options v1.GetOptions) (result *v1beta1.NodeMetrics, err error) {
result = &v1beta1.NodeMetrics{}
err = c.client.Get().
Resource("nodes").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of NodeMetricses that match those selectors.
func (c *nodeMetricses) List(opts v1.ListOptions) (result *v1beta1.NodeMetricsList, err error) {
result = &v1beta1.NodeMetricsList{}
err = c.client.Get().
Resource("nodes").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested nodeMetricses.
func (c *nodeMetricses) Watch(opts v1.ListOptions) (watch.Interface, error) {
opts.Watch = true
return c.client.Get().
Resource("nodes").
VersionedParams(&opts, scheme.ParameterCodec).
Watch()
}

View File

@ -1,90 +0,0 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1"
scheme "k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme"
)
// PodMetricsesGetter has a method to return a PodMetricsInterface.
// A group's client should implement this interface.
type PodMetricsesGetter interface {
PodMetricses(namespace string) PodMetricsInterface
}
// PodMetricsInterface has methods to work with PodMetrics resources.
type PodMetricsInterface interface {
Get(name string, options v1.GetOptions) (*v1beta1.PodMetrics, error)
List(opts v1.ListOptions) (*v1beta1.PodMetricsList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
PodMetricsExpansion
}
// podMetricses implements PodMetricsInterface
type podMetricses struct {
client rest.Interface
ns string
}
// newPodMetricses returns a PodMetricses
func newPodMetricses(c *MetricsV1beta1Client, namespace string) *podMetricses {
return &podMetricses{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the podMetrics, and returns the corresponding podMetrics object, and an error if there is any.
func (c *podMetricses) Get(name string, options v1.GetOptions) (result *v1beta1.PodMetrics, err error) {
result = &v1beta1.PodMetrics{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of PodMetricses that match those selectors.
func (c *podMetricses) List(opts v1.ListOptions) (result *v1beta1.PodMetricsList, err error) {
result = &v1beta1.PodMetricsList{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested podMetricses.
func (c *podMetricses) Watch(opts v1.ListOptions) (watch.Interface, error) {
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Watch()
}

14
vendor/modules.txt vendored
View File

@ -65,6 +65,8 @@ github.com/containerd/continuity/fs
github.com/containerd/continuity/sysx
github.com/containerd/continuity/pathdriver
github.com/containerd/continuity/syscallx
# github.com/convox/exec v0.0.0-20180905012044-cc13d277f897
github.com/convox/exec
# github.com/convox/logger v0.0.0-20180522214415-e39179955b52
github.com/convox/logger
# github.com/convox/stdapi v0.0.0-20190708203955-b81b71b6a680
@ -190,8 +192,6 @@ github.com/json-iterator/go
github.com/kballard/go-shellquote
# github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/konsorten/go-windows-terminal-sequences
# github.com/mattn/go-runewidth v0.0.4
github.com/mattn/go-runewidth
# github.com/miekg/dns v1.1.15
github.com/miekg/dns
# github.com/mitchellh/go-homedir v1.1.0
@ -268,8 +268,6 @@ google.golang.org/grpc/status
google.golang.org/grpc/internal
google.golang.org/grpc/connectivity
google.golang.org/grpc/grpclog
# gopkg.in/cheggaaa/pb.v1 v1.0.28
gopkg.in/cheggaaa/pb.v1
# gopkg.in/inf.v0 v0.9.0
gopkg.in/inf.v0
# gopkg.in/yaml.v2 v2.2.2
@ -422,11 +420,3 @@ k8s.io/client-go/util/connrotation
k8s.io/client-go/tools/clientcmd/api/v1
# k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058
k8s.io/kube-openapi/pkg/util/proto
# k8s.io/metrics v0.0.0-20181204004050-3d8dd1c3a53c
k8s.io/metrics/pkg/client/clientset_generated/clientset
k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1alpha1
k8s.io/metrics/pkg/client/clientset_generated/clientset/typed/metrics/v1beta1
k8s.io/metrics/pkg/apis/metrics/v1alpha1
k8s.io/metrics/pkg/client/clientset_generated/clientset/scheme
k8s.io/metrics/pkg/apis/metrics/v1beta1
k8s.io/metrics/pkg/apis/metrics