mirror of
https://github.com/genuinetools/reg.git
synced 2024-09-21 01:01:01 -04:00
Compare commits
No commits in common. "master" and "v0.15.7" have entirely different histories.
1069 changed files with 165337 additions and 109954 deletions
13
.github/workflows/make-all.yml
vendored
13
.github/workflows/make-all.yml
vendored
|
@ -1,13 +0,0 @@
|
|||
on: push
|
||||
name: make all
|
||||
jobs:
|
||||
makeall:
|
||||
name: make all
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: make all
|
||||
uses: docker://golang:latest
|
||||
with:
|
||||
entrypoint: bash
|
||||
args: -c "go get honnef.co/go/tools/cmd/staticcheck && go get golang.org/x/lint/golint && make fmt lint staticcheck vet install"
|
11
.github/workflows/make-image.yml
vendored
11
.github/workflows/make-image.yml
vendored
|
@ -1,11 +0,0 @@
|
|||
on: push
|
||||
name: make image
|
||||
jobs:
|
||||
makeimage:
|
||||
name: make image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: make image
|
||||
run: make image
|
||||
shell: bash
|
29
.github/workflows/make-release.yml
vendored
29
.github/workflows/make-release.yml
vendored
|
@ -1,29 +0,0 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
name: make release
|
||||
jobs:
|
||||
makerelease:
|
||||
name: make release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: make release
|
||||
uses: docker://golang:latest
|
||||
with:
|
||||
args: make release
|
||||
- name: upload assets
|
||||
uses: docker://r.j3ss.co/github-dev
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
entrypoint: bash
|
||||
args: -c "upload-assets ./cross/*"
|
||||
- name: update release body
|
||||
uses: docker://r.j3ss.co/pepper
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
entrypoint: sh
|
||||
args: -c "pepper release --repo $GITHUB_REPOSITORY -d --nouser"
|
11
.github/workflows/make-test.yml
vendored
11
.github/workflows/make-test.yml
vendored
|
@ -1,11 +0,0 @@
|
|||
on: push
|
||||
name: make test
|
||||
jobs:
|
||||
maketest:
|
||||
name: make test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: make test
|
||||
run: DOCKER_API_VERSION=1.39 make dind dtest
|
||||
shell: bash
|
15
.github/workflows/toc.yml
vendored
15
.github/workflows/toc.yml
vendored
|
@ -1,15 +0,0 @@
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # Push events on master branch
|
||||
name: Table of Contents Generator
|
||||
jobs:
|
||||
generateTOC:
|
||||
name: TOC Generator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: TOC Generator
|
||||
uses: technote-space/toc-generator@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TARGET_PATHS: "README.md"
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -43,15 +43,12 @@ Icon
|
|||
.Trashes
|
||||
|
||||
reg
|
||||
testreg
|
||||
.certs
|
||||
cross/
|
||||
server/static/index.html
|
||||
server/static/repo/
|
||||
|
||||
# Go coverage results
|
||||
coverage.txt
|
||||
profile.out
|
||||
|
||||
!go.mod
|
||||
|
||||
testreg
|
||||
.certs
|
||||
server/static/index.html
|
||||
server/static/repo/
|
||||
|
|
56
.travis.yml
Normal file
56
.travis.yml
Normal file
|
@ -0,0 +1,56 @@
|
|||
language: go
|
||||
sudo: true
|
||||
services:
|
||||
- docker
|
||||
go:
|
||||
- 1.10.x
|
||||
before_install:
|
||||
- go get github.com/golang/lint/golint
|
||||
- go get honnef.co/go/tools/cmd/staticcheck
|
||||
jobs:
|
||||
include:
|
||||
- script:
|
||||
- make fmt lint staticcheck vet install
|
||||
- DOCKER_API_VERSION=1.38 make dind dtest
|
||||
- stage: Build Release
|
||||
script:
|
||||
- make release
|
||||
- echo "Deploying to GitHub releases ..."
|
||||
deploy:
|
||||
provider: releases
|
||||
file:
|
||||
- cross/reg-darwin-amd64
|
||||
- cross/reg-darwin-amd64.md5
|
||||
- cross/reg-darwin-amd64.sha256
|
||||
- cross/reg-darwin-386
|
||||
- cross/reg-darwin-386.md5
|
||||
- cross/reg-darwin-386.sha256
|
||||
- cross/reg-freebsd-amd64
|
||||
- cross/reg-freebsd-amd64.md5
|
||||
- cross/reg-freebsd-amd64.sha256
|
||||
- cross/reg-freebsd-386
|
||||
- cross/reg-freebsd-386.md5
|
||||
- cross/reg-freebsd-386.sha256
|
||||
- cross/reg-linux-arm
|
||||
- cross/reg-linux-arm.md5
|
||||
- cross/reg-linux-arm.sha256
|
||||
- cross/reg-linux-arm64
|
||||
- cross/reg-linux-arm64.md5
|
||||
- cross/reg-linux-arm64.sha256
|
||||
- cross/reg-linux-amd64
|
||||
- cross/reg-linux-amd64.md5
|
||||
- cross/reg-linux-amd64.sha256
|
||||
- cross/reg-linux-386
|
||||
- cross/reg-linux-386.md5
|
||||
- cross/reg-linux-386.sha256
|
||||
- cross/reg-windows-amd64
|
||||
- cross/reg-windows-amd64.md5
|
||||
- cross/reg-windows-amd64.sha256
|
||||
- cross/reg-windows-386
|
||||
- cross/reg-windows-386.md5
|
||||
- cross/reg-windows-386.sha256
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
api_key:
|
||||
secure: "AULDRJQ8olD4R3v35sCnSZx136DnJnqMkX3ANNC/gosQhI+sFViW7BT0kaQBcIqBjF3jrik4Zm4BAW0VSZruwahD+pxjf/uroYAraMaFohw5SCL+CIY4qgNM/kkkZXTAP5DvPIOKEmXY8FfL1ZD0C6B8OKabRjh2rxuoh+enjflrA/B6B98yqo/NufCgfqfhwSK7xnh7kY4DCwfpQ80fQFzwj1BQQ5bBpP7tTVpZVqnbfSTSUoV8pX+2Ef/+t3KgYWx11+zkML9GbLevf7SbaMP9qceLvSW2npjzK1vCdQEtKp5OEuvaqsHXpdV58EdQx01zt5RSKSj/EcVaASwt2dbR10kTV7hBTvNqmvStjjKavCKzyohHG5s8VOrTXnIezuxXe1l9P9teIktY+uFClsC9t8jkQZZlVYn8brWMp+oU1VtVgYQRiF4p08IxUUS5DtZ1ZML9Yqh0am1lo2EFRydOBiIVoG2cSO8IbvDYYhIUrfc+pZ01vBV+sp+5EGmNp/7wgLwNSzoAgjh6BRLZO7irICcd579L4ZLWYX8k7/oXFDb8ABjzl0/Fk4K6EL1TTQzJaabxVAT1SI7b2PnqhJx7f5xPbNdNIQAQ/+I0sN7hpIJ0o/VaqObGKIdJeZSWISQ5TTlK+TtbucAtNaSgw0rhNYrIslK2bfgODa6MfJc="
|
1
.traviskey
Normal file
1
.traviskey
Normal file
|
@ -0,0 +1 @@
|
|||
AULDRJQ8olD4R3v35sCnSZx136DnJnqMkX3ANNC/gosQhI+sFViW7BT0kaQBcIqBjF3jrik4Zm4BAW0VSZruwahD+pxjf/uroYAraMaFohw5SCL+CIY4qgNM/kkkZXTAP5DvPIOKEmXY8FfL1ZD0C6B8OKabRjh2rxuoh+enjflrA/B6B98yqo/NufCgfqfhwSK7xnh7kY4DCwfpQ80fQFzwj1BQQ5bBpP7tTVpZVqnbfSTSUoV8pX+2Ef/+t3KgYWx11+zkML9GbLevf7SbaMP9qceLvSW2npjzK1vCdQEtKp5OEuvaqsHXpdV58EdQx01zt5RSKSj/EcVaASwt2dbR10kTV7hBTvNqmvStjjKavCKzyohHG5s8VOrTXnIezuxXe1l9P9teIktY+uFClsC9t8jkQZZlVYn8brWMp+oU1VtVgYQRiF4p08IxUUS5DtZ1ZML9Yqh0am1lo2EFRydOBiIVoG2cSO8IbvDYYhIUrfc+pZ01vBV+sp+5EGmNp/7wgLwNSzoAgjh6BRLZO7irICcd579L4ZLWYX8k7/oXFDb8ABjzl0/Fk4K6EL1TTQzJaabxVAT1SI7b2PnqhJx7f5xPbNdNIQAQ/+I0sN7hpIJ0o/VaqObGKIdJeZSWISQ5TTlK+TtbucAtNaSgw0rhNYrIslK2bfgODa6MfJc=
|
|
@ -5,7 +5,6 @@ ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
|||
ENV GOPATH /go
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
ca-certificates
|
||||
|
||||
COPY . /go/src/github.com/genuinetools/reg
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
FROM golang:alpine
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
build-base \
|
||||
ca-certificates \
|
||||
git
|
||||
|
|
541
Gopkg.lock
generated
Normal file
541
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,541 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:81f8c061c3d18ed1710957910542bc17d2b789c6cd19e0f654c30b35fd255ca5"
|
||||
name = "github.com/Azure/go-ansiterm"
|
||||
packages = [
|
||||
".",
|
||||
"winterm",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d6e3b3328b783f23731bc4d058875b0371ff8109"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2be791e7b333ff7c06f8fb3dc18a7d70580e9399dbdffd352621d067ff260b6e"
|
||||
name = "github.com/Microsoft/go-winio"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "97e4973ce50b2ff5f09635a57e2b88a037aae829"
|
||||
version = "v0.4.11"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7da1a26e347165227c79dfb10b90b3b5dedb6cbae50e88cdb81f5b6259b5b951"
|
||||
name = "github.com/Nvveen/Gotty"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cd527374f1e5bff4938207604a14f2e38a9cf512"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:707ebe952a8b3d00b343c01536c79c73771d100f63ec6babeaed5c79e2b8a8dd"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
pruneopts = "NUT"
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4a029051269e04c040c092eb4ddd92732f8f3a3921a8b43b82b30804e00f3357"
|
||||
name = "github.com/containerd/continuity"
|
||||
packages = ["pathdriver"]
|
||||
pruneopts = "NUT"
|
||||
revision = "c2ac4ecc959316e616c37fd95143e972811bd12e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2b7e45c96a900225df4288dd1a8a2a1c34477027274cbba6ff5320110aa7a02a"
|
||||
name = "github.com/coreos/clair"
|
||||
packages = [
|
||||
"api/v3/clairpb",
|
||||
"database",
|
||||
"ext/versionfmt",
|
||||
"pkg/pagination",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d0a3fe9206309b34e562887f886d908f51e0821a"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3d253a76fba28c8ed28b517fd89b362b4e0116d05833023bcc987111b5aa9b15"
|
||||
name = "github.com/docker/cli"
|
||||
packages = [
|
||||
"cli/config/configfile",
|
||||
"cli/config/credentials",
|
||||
"opts",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b4180e8757e9d5f9b38813e10c4f4a1c0f6643b5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1aed2b27277a9c4a2b3b40abf3e0484704a35482f24a804e7791c5172dcbf323"
|
||||
name = "github.com/docker/distribution"
|
||||
packages = [
|
||||
".",
|
||||
"digestset",
|
||||
"manifest",
|
||||
"manifest/manifestlist",
|
||||
"manifest/schema1",
|
||||
"manifest/schema2",
|
||||
"metrics",
|
||||
"reference",
|
||||
"registry/api/errcode",
|
||||
"registry/api/v2",
|
||||
"registry/client",
|
||||
"registry/client/auth",
|
||||
"registry/client/auth/challenge",
|
||||
"registry/client/transport",
|
||||
"registry/storage/cache",
|
||||
"registry/storage/cache/memory",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b089e91688254eb5aef187f188c8ee0ebe4e4675"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:29566f3fa9f66bf12978baba01329b29da05526cace5c15a74e1a61f7f3a4381"
|
||||
name = "github.com/docker/docker"
|
||||
packages = [
|
||||
"api",
|
||||
"api/types",
|
||||
"api/types/blkiodev",
|
||||
"api/types/container",
|
||||
"api/types/events",
|
||||
"api/types/filters",
|
||||
"api/types/image",
|
||||
"api/types/mount",
|
||||
"api/types/network",
|
||||
"api/types/registry",
|
||||
"api/types/strslice",
|
||||
"api/types/swarm",
|
||||
"api/types/swarm/runtime",
|
||||
"api/types/time",
|
||||
"api/types/versions",
|
||||
"api/types/volume",
|
||||
"client",
|
||||
"errdefs",
|
||||
"pkg/homedir",
|
||||
"pkg/idtools",
|
||||
"pkg/ioutils",
|
||||
"pkg/jsonmessage",
|
||||
"pkg/longpath",
|
||||
"pkg/mount",
|
||||
"pkg/stringid",
|
||||
"pkg/system",
|
||||
"pkg/tarsum",
|
||||
"pkg/term",
|
||||
"pkg/term/windows",
|
||||
"registry",
|
||||
"registry/resumable",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "ed392603acbf7849aa68d760c67d9c645ac035d8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:961fe5dd401b2284aff5141c1076e6a5cce10fcf2e6440b79bb7e2ea353d1c01"
|
||||
name = "github.com/docker/docker-ce"
|
||||
packages = ["components/cli/cli/config"]
|
||||
pruneopts = "NUT"
|
||||
revision = "d156a93844295ae887439d37031e71737db7b5e0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8866486038791fe65ea1abf660041423954b1f3fb99ea6a0ad8424422e943458"
|
||||
name = "github.com/docker/docker-credential-helpers"
|
||||
packages = [
|
||||
"client",
|
||||
"credentials",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "5241b46610f2491efdf9d1c85f1ddf5b02f6d962"
|
||||
version = "v0.6.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:42cfcc9461365aacb806b9cfe929c926f0d3fb0f692bfc10c375872f2881b2f2"
|
||||
name = "github.com/docker/go-connections"
|
||||
packages = [
|
||||
"nat",
|
||||
"sockets",
|
||||
"tlsconfig",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "97c2040d34dfae1d1b1275fa3a78dbdd2f41cf7e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8e5e04894d9d663ac464d6e73803d602f85fe679ec5a54de35378b5d073efd64"
|
||||
name = "github.com/docker/go-metrics"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "399ea8c73916000c64c2c76e8da00ca82f8387ab"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4340101f42556a9cb2f7a360a0e95a019bfef6247d92e6c4c46f2433cf86a482"
|
||||
name = "github.com/docker/go-units"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "47565b4f722fb6ceae66b95f853feed578a4a51c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ce43438a8204a4259b4461153a392bc3e504bef7e4785a8192344f002c7bd935"
|
||||
name = "github.com/docker/libtrust"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "aabc10ec26b754e797f9028f4589c5b7bd90dc20"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e101620a1bea7755f45d9cca76bfd505e3f4678b47f37209838ddab235341d1c"
|
||||
name = "github.com/fernet/fernet-go"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "9eac43b88a5efb8651d24de9b68e87567e029736"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:bd228d1a02fffcaf3abca973886870113d843ea7a67d5b6f70a5169950499ea9"
|
||||
name = "github.com/genuinetools/pkg"
|
||||
packages = ["cli"]
|
||||
pruneopts = "NUT"
|
||||
revision = "1c141f661797b5fb22033c9a7a5ab004994a0404"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:38e684375ef5b55e812332266d63f9fc5b6329ab303067c4cdda051db6d29ca4"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = ["proto"]
|
||||
pruneopts = "NUT"
|
||||
revision = "636bf0302bc95575d69441b25a2603156ffdddf1"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9b117ac202b9de210a7093bca0c29d0d2424e4c9235c9e025ae0d6ef6b121c82"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"protoc-gen-go/descriptor",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/struct",
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2e3c336fc7fde5c984d2841455a658a6d626450b1754a854b3b32e7a8f49a07a"
|
||||
name = "github.com/google/go-cmp"
|
||||
packages = [
|
||||
"cmp",
|
||||
"cmp/internal/diff",
|
||||
"cmp/internal/function",
|
||||
"cmp/internal/value",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "3af367b6b30c263d47e8895973edcca9a49cf029"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c01767916c59f084bb7c41a7d5877c0f3099b1595cfa066e84ec6ad6b084dd89"
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bf5cf1d53d703332e9bd8984c69784645b73a938317bf5ace9aadf20ac49379a"
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
|
||||
version = "v1.6.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:228dfa88f068306d5d23fb3efac8e61b868e1d327aac6eebc21f0f15b03e44e4"
|
||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
||||
packages = [
|
||||
"runtime",
|
||||
"runtime/internal",
|
||||
"utilities",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "8558711daa6c2853489043207b563dceacbc19cf"
|
||||
version = "v1.5.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5985ef4caf91ece5d54817c11ea25f182697534f8ae6521eadcd628c142ac4b6"
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
pruneopts = "NUT"
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9f63926f52745d1f9d6053f8fbbb3bd3983c2c97c0565957e682b8d2f7aad3af"
|
||||
name = "github.com/mitchellh/go-wordwrap"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "9e67c67572bc5dd02aef930e2b0ae3c02a4b5a5c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:55c0cfaa11248731dfb2070a4a5b81330117a6f3bc288bfedd9feff9946b907a"
|
||||
name = "github.com/opencontainers/go-digest"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "c9281466c8b2f606084ac71339773efd177436e7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:11db38d694c130c800d0aefb502fb02519e514dc53d9804ce51d1ad25ec27db6"
|
||||
name = "github.com/opencontainers/image-spec"
|
||||
packages = [
|
||||
"specs-go",
|
||||
"specs-go/v1",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d60099175f88c47cd379c4738d158884749ed235"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:918dbd46ad099418ce9760291bb156ebf23d441aad4cb682dd9bf09e2d3c0c7b"
|
||||
name = "github.com/opencontainers/runc"
|
||||
packages = ["libcontainer/user"]
|
||||
pruneopts = "NUT"
|
||||
revision = "baf6536d6259209c3edfa2b22237af82942d3dfa"
|
||||
version = "v0.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:014d3763649dd2f071fcf4acb03f3a2964c0c6dcf5581f4585fdd0d492235518"
|
||||
name = "github.com/peterhellberg/link"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "d1cebc7ea14a5fc0de7cb4a45acae773161642c6"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:cfa8aa49949ef9e612512736234abd8023cffd7bc76865afcfeec9846b246daf"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/internal",
|
||||
"prometheus/promhttp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "e637cec7d9c8990247098639ebc6d43dd34ddd49"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = "NUT"
|
||||
revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:fad5a35eea6a1a33d6c8f949fbc146f24275ca809ece854248187683f52cc30b"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "c7de2306084e37d54b8be01f3541a8464345e9a5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:6621142cd60b7150ab66f38ff36303ca55843dc5a635c1f9a28f95ecddab72b4"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
"internal/util",
|
||||
"nfs",
|
||||
"xfs",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "05ee40e3a273f7245e8777337fc7b46e533a9a92"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:25eadade1fa09cbada860b0f17e559a40b97feea133ff73d8d6451be5df6d9a4"
|
||||
name = "github.com/shurcooL/httpfs"
|
||||
packages = [
|
||||
"html/vfstemplate",
|
||||
"path/vfspath",
|
||||
"vfsutil",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "809beceb23714880abc4a382a00c05f89d13b1cc"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:43c44ab8b001881225afe48c6aedcf2dd4f93495efd4586d1649c9dc2c7c7eaa"
|
||||
name = "github.com/shurcooL/vfsgen"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "33ae1944be3fe078a54c597f107e0867da19c713"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b2339e83ce9b5c4f79405f949429a7f68a9a904fed903c672aac1e7ceb7f5f02"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
|
||||
version = "v1.0.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3f3a05ae0b95893d90b9b3b5afdb79a9b3d96e4e36e099d841ae602e4aca0da8"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
pruneopts = "NUT"
|
||||
revision = "0e37d006457bf46f9e6692014ba72ef82c33022c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8f96a3abd7277a1f433c5b7036c00f21188fd6a36ff1e8c9c1681ab14476e192"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/socks",
|
||||
"internal/timeseries",
|
||||
"proxy",
|
||||
"trace",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "26e67e76b6c3f6ce91f7c52def5af501b4e0f3a2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:581828cee9f0d31195c1ae52ea8935dfaec395cee6c23adc02109b892b391c2e"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d0be0721c37eeb5299f245a996a483160fc36940"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e7071ed636b5422cc51c0e3a6cebc229d6c9fffc528814b519a980641422d619"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:42448f154e7d40907ae03cbdf99dbcfa3feb927c4521e0f01c52c6142e4891d5"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = [
|
||||
"googleapis/api/annotations",
|
||||
"googleapis/rpc/status",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "4b56f30a1fd96a133a036b62cdd2a249883dd89b"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5b805b8e03b29399b344655cac16873f026e54dc0a7c17b381f6f4d4c7b6d741"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclog",
|
||||
"internal",
|
||||
"internal/backoff",
|
||||
"internal/channelz",
|
||||
"internal/envconfig",
|
||||
"internal/grpcrand",
|
||||
"internal/transport",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
"peer",
|
||||
"resolver",
|
||||
"resolver/dns",
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "8dea3dc473e90c8179e519d91302d0597c0ca1d1"
|
||||
version = "v1.15.0"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/coreos/clair/api/v3/clairpb",
|
||||
"github.com/docker/distribution",
|
||||
"github.com/docker/distribution/manifest/manifestlist",
|
||||
"github.com/docker/distribution/manifest/schema1",
|
||||
"github.com/docker/distribution/manifest/schema2",
|
||||
"github.com/docker/distribution/reference",
|
||||
"github.com/docker/docker-ce/components/cli/cli/config",
|
||||
"github.com/docker/docker/api/types",
|
||||
"github.com/docker/docker/api/types/container",
|
||||
"github.com/docker/docker/client",
|
||||
"github.com/docker/docker/pkg/jsonmessage",
|
||||
"github.com/docker/docker/pkg/term",
|
||||
"github.com/genuinetools/pkg/cli",
|
||||
"github.com/google/go-cmp/cmp",
|
||||
"github.com/gorilla/mux",
|
||||
"github.com/mitchellh/go-wordwrap",
|
||||
"github.com/opencontainers/go-digest",
|
||||
"github.com/peterhellberg/link",
|
||||
"github.com/shurcooL/httpfs/html/vfstemplate",
|
||||
"github.com/shurcooL/vfsgen",
|
||||
"github.com/sirupsen/logrus",
|
||||
"google.golang.org/grpc",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
73
Gopkg.toml
Normal file
73
Gopkg.toml
Normal file
|
@ -0,0 +1,73 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
[prune]
|
||||
non-go = true
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[override]]
|
||||
name = "github.com/Sirupsen/logrus"
|
||||
source = "github.com/sirupsen/logrus"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/docker/distribution"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/docker/docker"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/docker/docker-ce"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/cli"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/docker-credentials-helpers"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/go-connections"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/docker/go-units"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/opencontainers/go-digest"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/shurcooL/vfsgen"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/shurcooL/httpfs"
|
||||
branch = "master"
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 The Genuinetools Authors
|
||||
Copyright (c) 2018 The Genuinetools Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
184
Makefile
184
Makefile
|
@ -1,26 +1,174 @@
|
|||
# Set an output prefix, which is the local directory if not specified
|
||||
PREFIX?=$(shell pwd)
|
||||
|
||||
# Setup name variables for the package/tool
|
||||
NAME := reg
|
||||
PKG := github.com/genuinetools/$(NAME)
|
||||
|
||||
CGO_ENABLED := 0
|
||||
|
||||
# Set any default go build tags.
|
||||
# Set any default go build tags
|
||||
BUILDTAGS :=
|
||||
|
||||
include basic.mk
|
||||
# Set the build dir, where built cross-compiled binaries will be output
|
||||
BUILDDIR := ${PREFIX}/cross
|
||||
|
||||
.PHONY: prebuild
|
||||
prebuild:
|
||||
# Populate version variables
|
||||
# Add to compile time flags
|
||||
VERSION := $(shell cat VERSION.txt)
|
||||
GITCOMMIT := $(shell git rev-parse --short HEAD)
|
||||
GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
|
||||
ifneq ($(GITUNTRACKEDCHANGES),)
|
||||
GITCOMMIT := $(GITCOMMIT)-dirty
|
||||
endif
|
||||
CTIMEVAR=-X $(PKG)/version.GITCOMMIT=$(GITCOMMIT) -X $(PKG)/version.VERSION=$(VERSION)
|
||||
GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
|
||||
GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
|
||||
|
||||
# Set our default go compiler
|
||||
GO := go
|
||||
|
||||
# List the GOOS and GOARCH to build
|
||||
GOOSARCHES = $(shell cat .goosarch)
|
||||
|
||||
.PHONY: build
|
||||
build: $(NAME) ## Builds a dynamic executable or package
|
||||
|
||||
$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
|
||||
@echo "+ $@"
|
||||
$(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o $(NAME) .
|
||||
|
||||
.PHONY: static
|
||||
static: ## Builds a static executable
|
||||
@echo "+ $@"
|
||||
CGO_ENABLED=0 $(GO) build \
|
||||
-tags "$(BUILDTAGS) static_build" \
|
||||
${GO_LDFLAGS_STATIC} -o $(NAME) .
|
||||
|
||||
all: clean build fmt lint test staticcheck vet install ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Verifies all files have been `gofmt`ed
|
||||
@echo "+ $@"
|
||||
@gofmt -s -l . | grep -v '.pb.go:' | grep -v vendor | tee /dev/stderr
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Verifies `golint` passes
|
||||
@echo "+ $@"
|
||||
@golint ./... | grep -v '.pb.go:' | grep -v vendor | grep -v internal | tee /dev/stderr
|
||||
|
||||
.PHONY: test
|
||||
test: ## Runs the go tests
|
||||
@echo "+ $@"
|
||||
@$(GO) test -v -tags "$(BUILDTAGS) cgo" $(shell $(GO) list ./... | grep -v vendor)
|
||||
|
||||
.PHONY: vet
|
||||
vet: ## Verifies `go vet` passes
|
||||
@echo "+ $@"
|
||||
@$(GO) vet $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck: ## Verifies `staticcheck` passes
|
||||
@echo "+ $@"
|
||||
@staticcheck $(shell $(GO) list ./... | grep -v vendor) | grep -v '.pb.go:' | tee /dev/stderr
|
||||
|
||||
.PHONY: cover
|
||||
cover: ## Runs go test with coverage
|
||||
@echo "" > coverage.txt
|
||||
@for d in $(shell $(GO) list ./... | grep -v vendor); do \
|
||||
$(GO) test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
|
||||
if [ -f profile.out ]; then \
|
||||
cat profile.out >> coverage.txt; \
|
||||
rm profile.out; \
|
||||
fi; \
|
||||
done;
|
||||
|
||||
.PHONY: install
|
||||
install: ## Installs the executable or package
|
||||
@echo "+ $@"
|
||||
$(GO) install -a -tags "$(BUILDTAGS)" ${GO_LDFLAGS} .
|
||||
|
||||
define buildpretty
|
||||
mkdir -p $(BUILDDIR)/$(1)/$(2);
|
||||
GOOS=$(1) GOARCH=$(2) CGO_ENABLED=0 $(GO) build \
|
||||
-o $(BUILDDIR)/$(1)/$(2)/$(NAME) \
|
||||
-a -tags "$(BUILDTAGS) static_build netgo" \
|
||||
-installsuffix netgo ${GO_LDFLAGS_STATIC} .;
|
||||
md5sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).md5;
|
||||
sha256sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).sha256;
|
||||
endef
|
||||
|
||||
.PHONY: cross
|
||||
cross: *.go VERSION.txt ## Builds the cross-compiled binaries, creating a clean directory structure (eg. GOOS/GOARCH/binary)
|
||||
@echo "+ $@"
|
||||
$(foreach GOOSARCH,$(GOOSARCHES), $(call buildpretty,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
|
||||
|
||||
define buildrelease
|
||||
GOOS=$(1) GOARCH=$(2) CGO_ENABLED=0 $(GO) build \
|
||||
-o $(BUILDDIR)/$(NAME)-$(1)-$(2) \
|
||||
-a -tags "$(BUILDTAGS) static_build netgo" \
|
||||
-installsuffix netgo ${GO_LDFLAGS_STATIC} .;
|
||||
md5sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).md5;
|
||||
sha256sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).sha256;
|
||||
endef
|
||||
|
||||
.PHONY: release
|
||||
release: *.go VERSION.txt ## Builds the cross-compiled binaries, naming them in such a way for release (eg. binary-GOOS-GOARCH)
|
||||
@echo "+ $@"
|
||||
$(foreach GOOSARCH,$(GOOSARCHES), $(call buildrelease,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
|
||||
|
||||
.PHONY: bump-version
|
||||
BUMP := patch
|
||||
bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
|
||||
@$(GO) get -u github.com/jessfraz/junk/sembump # update sembump tool
|
||||
$(eval NEW_VERSION = $(shell sembump --kind $(BUMP) $(VERSION)))
|
||||
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
||||
echo $(NEW_VERSION) > VERSION.txt
|
||||
@echo "Updating links to download binaries in README.md"
|
||||
sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
|
||||
git add VERSION.txt README.md
|
||||
git commit -vsam "Bump version to $(NEW_VERSION)"
|
||||
@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
|
||||
|
||||
.PHONY: tag
|
||||
tag: ## Create a new git tag to prepare to build a release
|
||||
git tag -sa $(VERSION) -m "$(VERSION)"
|
||||
@echo "Run git push origin $(VERSION) to push your new tag to GitHub and trigger a travis build."
|
||||
|
||||
.PHONY: AUTHORS
|
||||
AUTHORS:
|
||||
@$(file >$@,# This file lists all individuals having contributed content to the repository.)
|
||||
@$(file >>$@,# For how it is generated, see `make AUTHORS`.)
|
||||
@echo "$(shell git log --format='\n%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf)" >> $@
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Cleanup any build binaries or packages
|
||||
@echo "+ $@"
|
||||
$(RM) $(NAME)
|
||||
$(RM) -r $(BUILDDIR)
|
||||
sudo $(RM) -r $(CURDIR)/.certs
|
||||
|
||||
# set the graph driver as the current graphdriver if not set
|
||||
DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
|
||||
export DOCKER_GRAPHDRIVER
|
||||
|
||||
# if this session isn't interactive, then we don't want to allocate a
|
||||
# TTY, which would fail, but if it is interactive, we do want to attach
|
||||
# so that the user can send e.g. ^C through.
|
||||
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
|
||||
ifeq ($(INTERACTIVE), 1)
|
||||
DOCKER_FLAGS += -t
|
||||
endif
|
||||
|
||||
.PHONY: dind
|
||||
dind: stop-dind ## Starts a docker-in-docker container for running the tests with.
|
||||
DIND_CONTAINER=reg-dind
|
||||
DIND_DOCKER_IMAGE=r.j3ss.co/docker:userns
|
||||
dind: stop-dind ## Starts a docker-in-docker container for running the tests with
|
||||
docker run -d \
|
||||
--name $(NAME)-dind \
|
||||
--name $(DIND_CONTAINER) \
|
||||
--privileged \
|
||||
-v $(CURDIR)/.certs:/etc/docker/ssl \
|
||||
-v $(CURDIR):/go/src/github.com/genuinetools/reg \
|
||||
-v /tmp:/tmp \
|
||||
$(REGISTRY)/docker:userns \
|
||||
$(DIND_DOCKER_IMAGE) \
|
||||
dockerd -D --storage-driver $(DOCKER_GRAPHDRIVER) \
|
||||
-H tcp://127.0.0.1:2375 \
|
||||
--host=unix:///var/run/docker.sock \
|
||||
|
@ -32,27 +180,33 @@ dind: stop-dind ## Starts a docker-in-docker container for running the tests wit
|
|||
--tlscert=/etc/docker/ssl/server.cert
|
||||
|
||||
.PHONY: stop-dind
|
||||
stop-dind: ## Stops the docker-in-docker container.
|
||||
@docker rm -f $(NAME)-dind >/dev/null 2>&1 || true
|
||||
stop-dind: ## Stops the docker-in-docker container
|
||||
@docker rm -f $(DIND_CONTAINER) >/dev/null 2>&1 || true
|
||||
|
||||
.PHONY: dtest
|
||||
dtest: image-dev ## Run the tests in a docker container.
|
||||
DOCKER_IMAGE := reg-dev
|
||||
dtest: ## Run the tests in a docker container
|
||||
docker build --rm --force-rm -f Dockerfile.dev -t $(DOCKER_IMAGE) .
|
||||
docker run --rm -i $(DOCKER_FLAGS) \
|
||||
-v $(CURDIR):/go/src/github.com/genuinetools/reg \
|
||||
--workdir /go/src/github.com/genuinetools/reg \
|
||||
-v $(CURDIR)/.certs:/etc/docker/ssl:ro \
|
||||
-v /tmp:/tmp \
|
||||
--disable-content-trust=true \
|
||||
--net container:$(NAME)-dind \
|
||||
--net container:$(DIND_CONTAINER) \
|
||||
-e DOCKER_HOST=tcp://127.0.0.1:2375 \
|
||||
-e DOCKER_TLS_VERIFY=true \
|
||||
-e DOCKER_CERT_PATH=/etc/docker/ssl \
|
||||
-e DOCKER_API_VERSION \
|
||||
$(REGISTRY)/$(NAME):dev \
|
||||
$(DOCKER_IMAGE) \
|
||||
make test
|
||||
|
||||
.PHONY: snakeoil
|
||||
snakeoil: ## Update snakeoil certs for testing.
|
||||
snakeoil: ## Update snakeoil certs for testing
|
||||
go run /usr/local/go/src/crypto/tls/generate_cert.go --host localhost,127.0.0.1 --ca
|
||||
mv $(CURDIR)/key.pem $(CURDIR)/testutils/snakeoil/key.pem
|
||||
mv $(CURDIR)/cert.pem $(CURDIR)/testutils/snakeoil/cert.pem
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
|
39
README.md
39
README.md
|
@ -1,33 +1,25 @@
|
|||
# reg
|
||||
|
||||
[![make-all](https://github.com/genuinetools/reg/workflows/make%20all/badge.svg)](https://github.com/genuinetools/reg/actions?query=workflow%3A%22make+all%22)
|
||||
[![make-image](https://github.com/genuinetools/reg/workflows/make%20image/badge.svg)](https://github.com/genuinetools/reg/actions?query=workflow%3A%22make+image%22)
|
||||
[![make-test](https://github.com/genuinetools/reg/workflows/make%20test/badge.svg)](https://github.com/genuinetools/reg/actions?query=workflow%3A%22make+test%22)
|
||||
[![Travis CI](https://img.shields.io/travis/genuinetools/reg.svg?style=for-the-badge)](https://travis-ci.org/genuinetools/reg)
|
||||
[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=for-the-badge)](https://godoc.org/github.com/genuinetools/reg)
|
||||
[![Github All Releases](https://img.shields.io/github/downloads/genuinetools/reg/total.svg?style=for-the-badge)](https://github.com/genuinetools/reg/releases)
|
||||
|
||||
Docker registry v2 command line client and repo listing generator with security checks.
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
**Table of Contents**
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Binaries](#binaries)
|
||||
- [Via Go](#via-go)
|
||||
- [Usage](#usage)
|
||||
- [Auth](#auth)
|
||||
- [List Repositories and Tags](#list-repositories-and-tags)
|
||||
- [Get a Manifest](#get-a-manifest)
|
||||
- [Get the Digest](#get-the-digest)
|
||||
- [Download a Layer](#download-a-layer)
|
||||
- [Delete an Image](#delete-an-image)
|
||||
- [Vulnerability Reports](#vulnerability-reports)
|
||||
- [Generating Static Website for a Registry](#generating-static-website-for-a-registry)
|
||||
- [Using Self-Signed Certs with a Registry](#using-self-signed-certs-with-a-registry)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
* [Installation](README.md#installation)
|
||||
* [Binaries](README.md#binaries)
|
||||
* [Via Go](README.md#via-go)
|
||||
* [Usage](README.md#usage)
|
||||
* [Auth](README.md#auth)
|
||||
* [List Repositories and Tags](README.md#list-repositories-and-tags)
|
||||
* [Get a Manifest](README.md#get-a-manifest)
|
||||
* [Get the Digest](README.md#get-the-digest)
|
||||
* [Download a Layer](README.md#download-a-layer)
|
||||
* [Delete an Image](README.md#delete-an-image)
|
||||
* [Vulnerability Reports](README.md#vulnerability-reports)
|
||||
* [Running a Static UI Server for a Registry](README.md#running-a-static-ui-server-for-a-registry)
|
||||
* [Using Self-Signed Certs with a Registry](README.md#using-self-signed-certs-with-a-registry)
|
||||
* [Contributing](README.md#contributing)
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -51,7 +43,6 @@ Usage: reg <command>
|
|||
|
||||
Flags:
|
||||
|
||||
--auth-url alternate URL for registry authentication (ex. auth.docker.io) (default: <none>)
|
||||
-d enable debug logging (default: false)
|
||||
-f, --force-non-ssl force allow use of non-ssl (default: false)
|
||||
-k, --insecure do not verify tls certificates (default: false)
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.16.1
|
||||
v0.15.7
|
||||
|
|
196
basic.mk
196
basic.mk
|
@ -1,196 +0,0 @@
|
|||
# Set the shell
|
||||
SHELL := /bin/bash
|
||||
|
||||
# Set an output prefix, which is the local directory if not specified
|
||||
PREFIX?=$(shell pwd)
|
||||
|
||||
# Set the build dir, where built cross-compiled binaries will be output
|
||||
BUILDDIR := ${PREFIX}/cross
|
||||
|
||||
# Populate version variables
|
||||
# Add to compile time flags
|
||||
VERSION := $(shell cat VERSION.txt)
|
||||
GITCOMMIT := $(shell git rev-parse --short HEAD)
|
||||
GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
|
||||
ifneq ($(GITUNTRACKEDCHANGES),)
|
||||
GITCOMMIT := $(GITCOMMIT)-dirty
|
||||
endif
|
||||
ifeq ($(GITCOMMIT),)
|
||||
GITCOMMIT := ${GITHUB_SHA}
|
||||
endif
|
||||
CTIMEVAR=-X $(PKG)/version.GITCOMMIT=$(GITCOMMIT) -X $(PKG)/version.VERSION=$(VERSION)
|
||||
GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
|
||||
GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
|
||||
|
||||
# Set our default go compiler
|
||||
GO := go
|
||||
|
||||
# List the GOOS and GOARCH to build
|
||||
GOOSARCHES = $(shell cat .goosarch)
|
||||
|
||||
# Set the graph driver as the current graphdriver if not set.
|
||||
DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
|
||||
export DOCKER_GRAPHDRIVER
|
||||
|
||||
# If this session isn't interactive, then we don't want to allocate a
|
||||
# TTY, which would fail, but if it is interactive, we do want to attach
|
||||
# so that the user can send e.g. ^C through.
|
||||
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
|
||||
ifeq ($(INTERACTIVE), 1)
|
||||
DOCKER_FLAGS += -t
|
||||
endif
|
||||
|
||||
.PHONY: build
|
||||
build: prebuild $(NAME) ## Builds a dynamic executable or package.
|
||||
|
||||
$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
|
||||
@echo "+ $@"
|
||||
$(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o $(NAME) .
|
||||
|
||||
.PHONY: static
|
||||
static: prebuild ## Builds a static executable.
|
||||
@echo "+ $@"
|
||||
CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
|
||||
-tags "$(BUILDTAGS) static_build" \
|
||||
${GO_LDFLAGS_STATIC} -o $(NAME) .
|
||||
|
||||
all: clean build fmt lint test staticcheck vet install ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install.
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Verifies all files have been `gofmt`ed.
|
||||
@echo "+ $@"
|
||||
@if [[ ! -z "$(shell gofmt -s -l . | grep -v '.pb.go:' | grep -v '.twirp.go:' | grep -v vendor | tee /dev/stderr)" ]]; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Verifies `golint` passes.
|
||||
@echo "+ $@"
|
||||
@if [[ ! -z "$(shell golint ./... | grep -v '.pb.go:' | grep -v '.twirp.go:' | grep -v vendor | tee /dev/stderr)" ]]; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: test
|
||||
test: prebuild ## Runs the go tests.
|
||||
@echo "+ $@"
|
||||
@$(GO) test -v -tags "$(BUILDTAGS) cgo" $(shell $(GO) list ./... | grep -v vendor)
|
||||
|
||||
.PHONY: vet
|
||||
vet: ## Verifies `go vet` passes.
|
||||
@echo "+ $@"
|
||||
@if [[ ! -z "$(shell $(GO) vet $(shell $(GO) list ./... | grep -v vendor) | tee /dev/stderr)" ]]; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck: ## Verifies `staticcheck` passes.
|
||||
@echo "+ $@"
|
||||
@if [[ ! -z "$(shell staticcheck $(shell $(GO) list ./... | grep -v vendor) | tee /dev/stderr)" ]]; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: cover
|
||||
cover: prebuild ## Runs go test with coverage.
|
||||
@echo "" > coverage.txt
|
||||
@for d in $(shell $(GO) list ./... | grep -v vendor); do \
|
||||
$(GO) test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
|
||||
if [ -f profile.out ]; then \
|
||||
cat profile.out >> coverage.txt; \
|
||||
rm profile.out; \
|
||||
fi; \
|
||||
done;
|
||||
|
||||
.PHONY: install
|
||||
install: prebuild ## Installs the executable or package.
|
||||
@echo "+ $@"
|
||||
$(GO) install -a -tags "$(BUILDTAGS)" ${GO_LDFLAGS} .
|
||||
|
||||
define buildpretty
|
||||
mkdir -p $(BUILDDIR)/$(1)/$(2);
|
||||
GOOS=$(1) GOARCH=$(2) CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
|
||||
-o $(BUILDDIR)/$(1)/$(2)/$(NAME) \
|
||||
-a -tags "$(BUILDTAGS) static_build netgo" \
|
||||
-installsuffix netgo ${GO_LDFLAGS_STATIC} .;
|
||||
md5sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).md5;
|
||||
sha256sum $(BUILDDIR)/$(1)/$(2)/$(NAME) > $(BUILDDIR)/$(1)/$(2)/$(NAME).sha256;
|
||||
endef
|
||||
|
||||
.PHONY: cross
|
||||
cross: *.go VERSION.txt prebuild ## Builds the cross-compiled binaries, creating a clean directory structure (eg. GOOS/GOARCH/binary).
|
||||
@echo "+ $@"
|
||||
$(foreach GOOSARCH,$(GOOSARCHES), $(call buildpretty,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
|
||||
|
||||
define buildrelease
|
||||
GOOS=$(1) GOARCH=$(2) CGO_ENABLED=$(CGO_ENABLED) $(GO) build \
|
||||
-o $(BUILDDIR)/$(NAME)-$(1)-$(2) \
|
||||
-a -tags "$(BUILDTAGS) static_build netgo" \
|
||||
-installsuffix netgo ${GO_LDFLAGS_STATIC} .;
|
||||
md5sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).md5;
|
||||
sha256sum $(BUILDDIR)/$(NAME)-$(1)-$(2) > $(BUILDDIR)/$(NAME)-$(1)-$(2).sha256;
|
||||
endef
|
||||
|
||||
.PHONY: release
|
||||
release: *.go VERSION.txt prebuild ## Builds the cross-compiled binaries, naming them in such a way for release (eg. binary-GOOS-GOARCH).
|
||||
@echo "+ $@"
|
||||
$(foreach GOOSARCH,$(GOOSARCHES), $(call buildrelease,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH))))
|
||||
|
||||
.PHONY: bump-version
|
||||
BUMP := patch
|
||||
bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ].
|
||||
@$(GO) get -u github.com/jessfraz/junk/sembump || true # update sembump tool
|
||||
$(eval NEW_VERSION = $(shell sembump --kind $(BUMP) $(VERSION)))
|
||||
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
||||
echo $(NEW_VERSION) > VERSION.txt
|
||||
@echo "Updating links to download binaries in README.md"
|
||||
sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
|
||||
git add VERSION.txt README.md
|
||||
git commit -vsam "Bump version to $(NEW_VERSION)"
|
||||
@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
|
||||
|
||||
.PHONY: tag
|
||||
tag: ## Create a new git tag to prepare to build a release.
|
||||
git tag -sa $(VERSION) -m "$(VERSION)"
|
||||
@echo "Run git push origin $(VERSION) to push your new tag to GitHub and trigger a release."
|
||||
|
||||
REGISTRY := r.j3ss.co
|
||||
.PHONY: image
|
||||
image: ## Create the docker image from the Dockerfile.
|
||||
@docker build --rm --force-rm -t $(REGISTRY)/$(NAME) .
|
||||
|
||||
.PHONY: image-dev
|
||||
image-dev:
|
||||
@docker build --rm --force-rm -f Dockerfile.dev -t $(REGISTRY)/$(NAME):dev .
|
||||
|
||||
.PHONY: AUTHORS
|
||||
AUTHORS:
|
||||
@$(file >$@,# This file lists all individuals having contributed content to the repository.)
|
||||
@$(file >>$@,# For how it is generated, see `make AUTHORS`.)
|
||||
@echo "$(shell git log --format='\n%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf)" >> $@
|
||||
|
||||
.PHONY: vendor
|
||||
vendor: ## Updates the vendoring directory.
|
||||
@$(RM) go.sum
|
||||
@$(RM) -r vendor
|
||||
GO111MODULE=on $(GO) mod init || true
|
||||
GO111MODULE=on $(GO) mod tidy
|
||||
GO111MODULE=on $(GO) mod vendor
|
||||
@$(RM) Gopkg.toml Gopkg.lock
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Cleanup any build binaries or packages.
|
||||
@echo "+ $@"
|
||||
$(RM) $(NAME)
|
||||
$(RM) -r $(BUILDDIR)
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | sed 's/^[^:]*://g' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
check_defined = \
|
||||
$(strip $(foreach 1,$1, \
|
||||
$(call __check_defined,$1,$(strip $(value 2)))))
|
||||
|
||||
__check_defined = \
|
||||
$(if $(value $1),, \
|
||||
$(error Undefined $1$(if $2, ($2))$(if $(value @), \
|
||||
required by target `$@')))
|
|
@ -13,7 +13,7 @@ var (
|
|||
)
|
||||
|
||||
// GetAncestry displays an ancestry and all of its features and vulnerabilities.
|
||||
func (c *Clair) GetAncestry(ctx context.Context, name string) (*clairpb.GetAncestryResponse_Ancestry, error) {
|
||||
func (c *Clair) GetAncestry(name string) (*clairpb.GetAncestryResponse_Ancestry, error) {
|
||||
c.Logf("clair.ancestry.get name=%s", name)
|
||||
|
||||
if c.grpcConn == nil {
|
||||
|
@ -22,7 +22,7 @@ func (c *Clair) GetAncestry(ctx context.Context, name string) (*clairpb.GetAnces
|
|||
|
||||
client := clairpb.NewAncestryServiceClient(c.grpcConn)
|
||||
|
||||
resp, err := client.GetAncestry(ctx, &clairpb.GetAncestryRequest{
|
||||
resp, err := client.GetAncestry(context.Background(), &clairpb.GetAncestryRequest{
|
||||
AncestryName: name,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -41,7 +41,7 @@ func (c *Clair) GetAncestry(ctx context.Context, name string) (*clairpb.GetAnces
|
|||
}
|
||||
|
||||
// PostAncestry performs the analysis of all layers from the provided path.
|
||||
func (c *Clair) PostAncestry(ctx context.Context, name string, layers []*clairpb.PostAncestryRequest_PostLayer) error {
|
||||
func (c *Clair) PostAncestry(name string, layers []*clairpb.PostAncestryRequest_PostLayer) error {
|
||||
c.Logf("clair.ancestry.post name=%s", name)
|
||||
|
||||
if c.grpcConn == nil {
|
||||
|
@ -50,7 +50,7 @@ func (c *Clair) PostAncestry(ctx context.Context, name string, layers []*clairpb
|
|||
|
||||
client := clairpb.NewAncestryServiceClient(c.grpcConn)
|
||||
|
||||
resp, err := client.PostAncestry(ctx, &clairpb.PostAncestryRequest{
|
||||
resp, err := client.PostAncestry(context.Background(), &clairpb.PostAncestryRequest{
|
||||
AncestryName: name,
|
||||
Layers: layers,
|
||||
Format: "Docker",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package clair
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -12,7 +11,7 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Clair defines the client for retrieving information from the clair API.
|
||||
// Clair defines the client for retriving information from the clair API.
|
||||
type Clair struct {
|
||||
URL string
|
||||
Client *http.Client
|
||||
|
@ -82,24 +81,15 @@ func New(url string, opt Opt) (*Clair, error) {
|
|||
return registry, nil
|
||||
}
|
||||
|
||||
// Close closes the gRPC connection
|
||||
func (c *Clair) Close() error {
|
||||
return c.grpcConn.Close()
|
||||
}
|
||||
|
||||
// url returns a clair URL with the passed arguments concatenated.
|
||||
// url returns a clair URL with the passed arguements concatenated.
|
||||
func (c *Clair) url(pathTemplate string, args ...interface{}) string {
|
||||
pathSuffix := fmt.Sprintf(pathTemplate, args...)
|
||||
url := fmt.Sprintf("%s%s", c.URL, pathSuffix)
|
||||
return url
|
||||
}
|
||||
|
||||
func (c *Clair) getJSON(ctx context.Context, url string, response interface{}) (http.Header, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.Client.Do(req.WithContext(ctx))
|
||||
func (c *Clair) getJSON(url string, response interface{}) (http.Header, error) {
|
||||
resp, err := c.Client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2,19 +2,18 @@ package clair
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetLayer displays a Layer and optionally all of its features and vulnerabilities.
|
||||
func (c *Clair) GetLayer(ctx context.Context, name string, features, vulnerabilities bool) (*Layer, error) {
|
||||
func (c *Clair) GetLayer(name string, features, vulnerabilities bool) (*Layer, error) {
|
||||
url := c.url("/v1/layers/%s?features=%t&vulnerabilities=%t", name, features, vulnerabilities)
|
||||
c.Logf("clair.layers.get url=%s name=%s", url, name)
|
||||
|
||||
var respLayer layerEnvelope
|
||||
if _, err := c.getJSON(ctx, url, &respLayer); err != nil {
|
||||
if _, err := c.getJSON(url, &respLayer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -26,7 +25,7 @@ func (c *Clair) GetLayer(ctx context.Context, name string, features, vulnerabili
|
|||
}
|
||||
|
||||
// PostLayer performs the analysis of a Layer from the provided path.
|
||||
func (c *Clair) PostLayer(ctx context.Context, layer *Layer) (*Layer, error) {
|
||||
func (c *Clair) PostLayer(layer *Layer) (*Layer, error) {
|
||||
url := c.url("/v1/layers")
|
||||
c.Logf("clair.layers.post url=%s name=%s", url, layer.Name)
|
||||
|
||||
|
@ -37,14 +36,7 @@ func (c *Clair) PostLayer(ctx context.Context, layer *Layer) (*Layer, error) {
|
|||
|
||||
c.Logf("clair.layers.post req.Body=%s", string(b))
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.Client.Do(req.WithContext(ctx))
|
||||
resp, err := c.Client.Post(url, "application/json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -65,7 +57,7 @@ func (c *Clair) PostLayer(ctx context.Context, layer *Layer) (*Layer, error) {
|
|||
}
|
||||
|
||||
// DeleteLayer removes a layer reference from clair.
|
||||
func (c *Clair) DeleteLayer(ctx context.Context, name string) error {
|
||||
func (c *Clair) DeleteLayer(name string) error {
|
||||
url := c.url("/v1/layers/%s", name)
|
||||
c.Logf("clair.layers.delete url=%s name=%s", url, name)
|
||||
|
||||
|
@ -74,7 +66,7 @@ func (c *Clair) DeleteLayer(ctx context.Context, name string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
resp, err := c.Client.Do(req.WithContext(ctx))
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -85,5 +77,5 @@ func (c *Clair) DeleteLayer(ctx context.Context, name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("got status code: %d", resp.StatusCode)
|
||||
return fmt.Errorf("Got status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package clair
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -11,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// NewClairLayer will form a layer struct required for a clair scan.
|
||||
func (c *Clair) NewClairLayer(ctx context.Context, r *registry.Registry, image string, fsLayers map[int]distribution.Descriptor, index int) (*Layer, error) {
|
||||
func (c *Clair) NewClairLayer(r *registry.Registry, image string, fsLayers map[int]distribution.Descriptor, index int) (*Layer, error) {
|
||||
var parentName string
|
||||
if index < len(fsLayers)-1 {
|
||||
parentName = fsLayers[index+1].Digest.String()
|
||||
|
@ -21,7 +20,7 @@ func (c *Clair) NewClairLayer(ctx context.Context, r *registry.Registry, image s
|
|||
p := strings.Join([]string{r.URL, "v2", image, "blobs", fsLayers[index].Digest.String()}, "/")
|
||||
|
||||
// Get the headers.
|
||||
h, err := r.Headers(ctx, p)
|
||||
h, err := r.Headers(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -36,12 +35,12 @@ func (c *Clair) NewClairLayer(ctx context.Context, r *registry.Registry, image s
|
|||
}
|
||||
|
||||
// NewClairV3Layer will form a layer struct required for a clair scan.
|
||||
func (c *Clair) NewClairV3Layer(ctx context.Context, r *registry.Registry, image string, fsLayer distribution.Descriptor) (*clairpb.PostAncestryRequest_PostLayer, error) {
|
||||
func (c *Clair) NewClairV3Layer(r *registry.Registry, image string, fsLayer distribution.Descriptor) (*clairpb.PostAncestryRequest_PostLayer, error) {
|
||||
// Form the path.
|
||||
p := strings.Join([]string{r.URL, "v2", image, "blobs", fsLayer.Digest.String()}, "/")
|
||||
|
||||
// Get the headers.
|
||||
h, err := r.Headers(ctx, p)
|
||||
h, err := r.Headers(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -53,10 +52,10 @@ func (c *Clair) NewClairV3Layer(ctx context.Context, r *registry.Registry, image
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *Clair) getLayers(ctx context.Context, r *registry.Registry, repo, tag string, filterEmpty bool) (map[int]distribution.Descriptor, string, error) {
|
||||
func (c *Clair) getLayers(r *registry.Registry, repo, tag string, filterEmpty bool) (map[int]distribution.Descriptor, error) {
|
||||
ok := true
|
||||
// Get the manifest to pass to clair.
|
||||
mf, err := r.ManifestV2(ctx, repo, tag)
|
||||
mf, err := r.ManifestV2(repo, tag)
|
||||
if err != nil {
|
||||
ok = false
|
||||
c.Logf("couldn't retrieve manifest v2, falling back to v1")
|
||||
|
@ -74,12 +73,12 @@ func (c *Clair) getLayers(ctx context.Context, r *registry.Registry, repo, tag s
|
|||
}
|
||||
}
|
||||
|
||||
return filteredLayers, mf.Config.Digest.String(), nil
|
||||
return filteredLayers, nil
|
||||
}
|
||||
|
||||
m, err := r.ManifestV1(ctx, repo, tag)
|
||||
m, err := r.ManifestV1(repo, tag)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("getting the v1 manifest for %s:%s failed: %v", repo, tag, err)
|
||||
return nil, fmt.Errorf("getting the v1 manifest for %s:%s failed: %v", repo, tag, err)
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.FSLayers); i++ {
|
||||
|
@ -92,5 +91,5 @@ func (c *Clair) getLayers(ctx context.Context, r *registry.Registry, repo, tag s
|
|||
}
|
||||
}
|
||||
|
||||
return filteredLayers, filteredLayers[0].Digest.String(), nil
|
||||
return filteredLayers, nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package clair
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
@ -11,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// Vulnerabilities scans the given repo and tag.
|
||||
func (c *Clair) Vulnerabilities(ctx context.Context, r *registry.Registry, repo, tag string) (VulnerabilityReport, error) {
|
||||
func (c *Clair) Vulnerabilities(r *registry.Registry, repo, tag string) (VulnerabilityReport, error) {
|
||||
report := VulnerabilityReport{
|
||||
RegistryURL: r.Domain,
|
||||
Repo: repo,
|
||||
|
@ -20,7 +19,7 @@ func (c *Clair) Vulnerabilities(ctx context.Context, r *registry.Registry, repo,
|
|||
VulnsBySeverity: make(map[string][]Vulnerability),
|
||||
}
|
||||
|
||||
filteredLayers, _, err := c.getLayers(ctx, r, repo, tag, true)
|
||||
filteredLayers, err := c.getLayers(r, repo, tag, true)
|
||||
if err != nil {
|
||||
return report, fmt.Errorf("getting filtered layers failed: %v", err)
|
||||
}
|
||||
|
@ -32,20 +31,20 @@ func (c *Clair) Vulnerabilities(ctx context.Context, r *registry.Registry, repo,
|
|||
|
||||
for i := len(filteredLayers) - 1; i >= 0; i-- {
|
||||
// Form the clair layer.
|
||||
l, err := c.NewClairLayer(ctx, r, repo, filteredLayers, i)
|
||||
l, err := c.NewClairLayer(r, repo, filteredLayers, i)
|
||||
if err != nil {
|
||||
return report, err
|
||||
}
|
||||
|
||||
// Post the layer.
|
||||
if _, err := c.PostLayer(ctx, l); err != nil {
|
||||
if _, err := c.PostLayer(l); err != nil {
|
||||
return report, err
|
||||
}
|
||||
}
|
||||
|
||||
report.Name = filteredLayers[0].Digest.String()
|
||||
|
||||
vl, err := c.GetLayer(ctx, filteredLayers[0].Digest.String(), true, true)
|
||||
vl, err := c.GetLayer(filteredLayers[0].Digest.String(), true, true)
|
||||
if err != nil {
|
||||
return report, err
|
||||
}
|
||||
|
@ -77,7 +76,7 @@ func (c *Clair) Vulnerabilities(ctx context.Context, r *registry.Registry, repo,
|
|||
}
|
||||
|
||||
// VulnerabilitiesV3 scans the given repo and tag using the clair v3 API.
|
||||
func (c *Clair) VulnerabilitiesV3(ctx context.Context, r *registry.Registry, repo, tag string) (VulnerabilityReport, error) {
|
||||
func (c *Clair) VulnerabilitiesV3(r *registry.Registry, repo, tag string) (VulnerabilityReport, error) {
|
||||
report := VulnerabilityReport{
|
||||
RegistryURL: r.Domain,
|
||||
Repo: repo,
|
||||
|
@ -86,7 +85,7 @@ func (c *Clair) VulnerabilitiesV3(ctx context.Context, r *registry.Registry, rep
|
|||
VulnsBySeverity: make(map[string][]Vulnerability),
|
||||
}
|
||||
|
||||
layers, reportName, err := c.getLayers(ctx, r, repo, tag, false)
|
||||
layers, err := c.getLayers(r, repo, tag, false)
|
||||
if err != nil {
|
||||
return report, fmt.Errorf("getting filtered layers failed: %v", err)
|
||||
}
|
||||
|
@ -96,12 +95,12 @@ func (c *Clair) VulnerabilitiesV3(ctx context.Context, r *registry.Registry, rep
|
|||
return report, nil
|
||||
}
|
||||
|
||||
report.Name = reportName
|
||||
report.Name = layers[0].Digest.String()
|
||||
|
||||
clairLayers := []*clairpb.PostAncestryRequest_PostLayer{}
|
||||
for i := len(layers) - 1; i >= 0; i-- {
|
||||
// Form the clair layer.
|
||||
l, err := c.NewClairV3Layer(ctx, r, repo, layers[i])
|
||||
l, err := c.NewClairV3Layer(r, repo, layers[i])
|
||||
if err != nil {
|
||||
return report, err
|
||||
}
|
||||
|
@ -111,12 +110,12 @@ func (c *Clair) VulnerabilitiesV3(ctx context.Context, r *registry.Registry, rep
|
|||
}
|
||||
|
||||
// Post the ancestry.
|
||||
if err := c.PostAncestry(ctx, reportName, clairLayers); err != nil {
|
||||
if err := c.PostAncestry(layers[0].Digest.String(), clairLayers); err != nil {
|
||||
return report, fmt.Errorf("posting ancestry failed: %v", err)
|
||||
}
|
||||
|
||||
// Get the ancestry.
|
||||
vl, err := c.GetAncestry(ctx, reportName)
|
||||
vl, err := c.GetAncestry(layers[0].Digest.String())
|
||||
if err != nil {
|
||||
return report, err
|
||||
}
|
||||
|
|
|
@ -31,13 +31,13 @@ func (cmd *digestCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, image.Domain)
|
||||
r, err := createRegistryClient(image.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the digest.
|
||||
digest, err := r.Digest(ctx, image)
|
||||
digest, err := r.Digest(image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
39
go.mod
39
go.mod
|
@ -1,39 +0,0 @@
|
|||
module github.com/genuinetools/reg
|
||||
|
||||
replace github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.4.3-0.20190807103436-de736cf91b92
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.14 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.6 // indirect
|
||||
github.com/containerd/containerd v1.2.9 // indirect
|
||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect
|
||||
github.com/coreos/clair v2.0.1-0.20190910143208-94150ab1f4ac+incompatible
|
||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||
github.com/docker/cli v0.0.0-20190913211141-95327f4e6241
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker v1.4.2-0.20190916154449-92cc603036dd
|
||||
github.com/docker/docker-credential-helpers v0.6.3 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e // indirect
|
||||
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb
|
||||
github.com/gogo/protobuf v1.3.0 // indirect
|
||||
github.com/google/go-cmp v0.3.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.11.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.0
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/runc v0.1.1 // indirect
|
||||
github.com/peterhellberg/link v1.0.0
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||
google.golang.org/grpc v1.23.1
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
)
|
124
go.sum
124
go.sum
|
@ -1,124 +0,0 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/containerd/containerd v1.2.9 h1:6tyNjBmAMG47QuFPIT9LgiiexoVxC6qpTGR+eD0R0Z8=
|
||||
github.com/containerd/containerd v1.2.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw=
|
||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/coreos/clair v2.0.1-0.20190910143208-94150ab1f4ac+incompatible h1:V+KI58nlBLYl1KMqBc0Ollhik0gIp2dDkPZQsg3NipQ=
|
||||
github.com/coreos/clair v2.0.1-0.20190910143208-94150ab1f4ac+incompatible/go.mod h1:uXhHPWAoRqw0jJc2f8RrPCwRhIo9otQ8OEWUFtpCiwA=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/docker/cli v0.0.0-20190913211141-95327f4e6241 h1:btTBgRvrdoe+b7NfX/7PnUbiXzGceLCt09QZkg1bgqA=
|
||||
github.com/docker/cli v0.0.0-20190913211141-95327f4e6241/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.4.2-0.20190916154449-92cc603036dd h1:kDIT0qjvLHbdL86aa+VteVpVZOR7coIyIejM/o3CwOo=
|
||||
github.com/docker/docker v1.4.2-0.20190916154449-92cc603036dd/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e h1:P10tZmVD2XclAaT9l7OduMH1OLFzTa1wUuUqHZnEdI0=
|
||||
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
|
||||
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb h1:9MQ4N7zyYTtdjLGqE5McDbgjIjqR5TAPc6lytEOdndc=
|
||||
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
|
||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.11.1 h1:/dBYI+n4xIL+Y9SKXQrjlKTmJJDwCSlNLRwZ5nBhIek=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.11.1/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/peterhellberg/link v1.0.0 h1:mUWkiegowUXEcmlb+ybF75Q/8D2Y0BjZtR8cxoKhaQo=
|
||||
github.com/peterhellberg/link v1.0.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
23
handlers.go
23
handlers.go
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
@ -44,7 +43,7 @@ type Repository struct {
|
|||
VulnerabilityReport clair.VulnerabilityReport `json:"vulnerability"`
|
||||
}
|
||||
|
||||
// An AnalysisResult holds all vulnerabilities of a scan
|
||||
// A AnalysisResult holds all vulnerabilities of a scan
|
||||
type AnalysisResult struct {
|
||||
Repositories []Repository `json:"repositories"`
|
||||
RegistryDomain string `json:"registryDomain"`
|
||||
|
@ -54,7 +53,7 @@ type AnalysisResult struct {
|
|||
UpdateInterval time.Duration
|
||||
}
|
||||
|
||||
func (rc *registryController) repositories(ctx context.Context, staticDir string) error {
|
||||
func (rc *registryController) repositories(staticDir string) error {
|
||||
rc.l.Lock()
|
||||
defer rc.l.Unlock()
|
||||
|
||||
|
@ -66,7 +65,7 @@ func (rc *registryController) repositories(ctx context.Context, staticDir string
|
|||
UpdateInterval: rc.interval,
|
||||
}
|
||||
|
||||
repoList, err := rc.reg.Catalog(ctx, "")
|
||||
repoList, err := rc.reg.Catalog("")
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting catalog for %s failed: %v", rc.reg.Domain, err)
|
||||
}
|
||||
|
@ -95,7 +94,7 @@ func (rc *registryController) repositories(ctx context.Context, staticDir string
|
|||
// Parse and execute the tags templates.
|
||||
// If we are generating the tags files, disable vulnerability links in the
|
||||
// templates since they won't go anywhere without a server side component.
|
||||
b, err := rc.generateTagsTemplate(ctx, repo, false)
|
||||
b, err := rc.generateTagsTemplate(repo, false)
|
||||
if err != nil {
|
||||
logrus.Warnf("generating tags template for repo %q failed: %v", repo, err)
|
||||
}
|
||||
|
@ -157,7 +156,7 @@ func (rc *registryController) tagsHandler(w http.ResponseWriter, r *http.Request
|
|||
}
|
||||
|
||||
// Generate the tags template.
|
||||
b, err := rc.generateTagsTemplate(context.TODO(), repo, rc.cl != nil)
|
||||
b, err := rc.generateTagsTemplate(repo, rc.cl != nil)
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "tags",
|
||||
|
@ -174,9 +173,9 @@ func (rc *registryController) tagsHandler(w http.ResponseWriter, r *http.Request
|
|||
fmt.Fprint(w, string(b))
|
||||
}
|
||||
|
||||
func (rc *registryController) generateTagsTemplate(ctx context.Context, repo string, hasVulns bool) ([]byte, error) {
|
||||
func (rc *registryController) generateTagsTemplate(repo string, hasVulns bool) ([]byte, error) {
|
||||
// Get the tags from the server.
|
||||
tags, err := rc.reg.Tags(ctx, repo)
|
||||
tags, err := rc.reg.Tags(repo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting tags for %s failed: %v", repo, err)
|
||||
}
|
||||
|
@ -197,7 +196,7 @@ func (rc *registryController) generateTagsTemplate(ctx context.Context, repo str
|
|||
|
||||
for _, tag := range tags {
|
||||
// get the manifest
|
||||
m1, err := rc.reg.ManifestV1(ctx, repo, tag)
|
||||
m1, err := rc.reg.ManifestV1(repo, tag)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting v1 manifest for %s:%s failed: %v", repo, tag, err)
|
||||
}
|
||||
|
@ -261,7 +260,7 @@ func (rc *registryController) vulnerabilitiesHandler(w http.ResponseWriter, r *h
|
|||
return
|
||||
}
|
||||
|
||||
image, err := registry.ParseImage(rc.reg.Domain + "/" + repo + ":" + tag)
|
||||
image, err := registry.ParseImage(repo + ":" + tag)
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "vulnerabilities",
|
||||
|
@ -273,10 +272,10 @@ func (rc *registryController) vulnerabilitiesHandler(w http.ResponseWriter, r *h
|
|||
}
|
||||
|
||||
// Get the vulnerability report.
|
||||
result, err := rc.cl.VulnerabilitiesV3(context.TODO(), rc.reg, image.Path, image.Reference())
|
||||
result, err := rc.cl.VulnerabilitiesV3(rc.reg, image.Path, image.Reference())
|
||||
if err != nil {
|
||||
// Fallback to Clair v2 API.
|
||||
result, err = rc.cl.Vulnerabilities(context.TODO(), rc.reg, image.Path, image.Reference())
|
||||
result, err = rc.cl.Vulnerabilities(rc.reg, image.Path, image.Reference())
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "vulnerabilities",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,25 +19,25 @@ var Assets = func() http.FileSystem {
|
|||
fs := vfsgen۰FS{
|
||||
"/": &vfsgen۰DirInfo{
|
||||
name: "/",
|
||||
modTime: time.Date(2018, 10, 4, 17, 36, 7, 550458133, time.UTC),
|
||||
modTime: time.Date(2018, 9, 10, 21, 40, 58, 715425786, time.UTC),
|
||||
},
|
||||
"/repositories.html": &vfsgen۰CompressedFileInfo{
|
||||
name: "repositories.html",
|
||||
modTime: time.Date(2018, 10, 4, 17, 36, 7, 550458133, time.UTC),
|
||||
modTime: time.Date(2018, 9, 10, 21, 40, 58, 715425786, time.UTC),
|
||||
uncompressedSize: 1904,
|
||||
|
||||
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x55\xc9\x6e\xe4\x36\x10\xbd\xf7\x57\x94\x89\x39\x8e\x44\x18\x39\x8c\xd3\xa0\x84\x04\x1e\x1f\x0c\x64\x19\x18\x31\x90\x60\x30\x07\x36\x55\x92\x68\x53\xa4\x86\x2c\xb5\xd1\x51\xf4\xef\x01\xb5\xa0\x57\x1b\xce\x21\xba\x50\x7c\xf5\xea\xb1\x16\xaa\xd4\xf7\x05\x96\xda\x22\x30\x8f\xad\x0b\x9a\x9c\xd7\x18\xd8\x30\xac\xc4\xd5\xe7\xdf\x6f\xff\xf8\xeb\xcb\x1d\xd4\xd4\x98\x7c\x25\xae\x92\xe4\xab\x2e\xc1\x10\xdc\xdf\xc1\xa7\x6f\x39\x8c\x8f\x88\x56\x50\x46\x86\x90\x31\xeb\x92\xa7\x00\x86\x12\x8d\x3f\x4e\xcb\xcd\xb4\x7c\x62\x39\x88\xab\xaf\x68\x0b\x5d\x7e\x4b\x92\xbd\xda\xa1\xd4\x3b\xd4\xde\x90\xb9\x79\x8f\xcc\x6b\xfe\x15\xcd\x12\x11\xc8\x2f\xf8\x8f\x8e\x49\x72\xec\x5c\xa3\x2c\xf2\xd5\x78\x60\x83\x24\x41\xd5\xd2\x07\xa4\x8c\x75\x54\x26\x37\x6c\x36\x6d\x64\x40\xa8\x3d\x96\x19\xe3\x0c\x0e\xf9\x35\x51\x9b\xe0\xf7\x4e\x6f\x33\xf6\x67\xf2\xf8\x73\x72\xeb\x9a\x56\x92\xde\x18\x64\xa0\x9c\x25\xb4\x94\xb1\xfb\xbb\x0c\x8b\x0a\x3f\xaa\xda\xbb\x06\xb3\xeb\x45\x97\x34\x19\xcc\xfb\x1e\xd2\x07\xac\x74\x20\xbf\xfb\xec\x1a\xa9\x2d\x0c\x83\xe0\x93\x71\x22\x1a\x6d\x9f\xc1\xa3\xc9\x98\x56\xce\x32\xa0\x5d\x8b\x19\xd3\x8d\xac\x90\x6b\xe5\xd8\x12\x5c\x20\x49\x5a\xf1\x52\x6e\x23\x2f\x8d\xa6\x33\x85\x40\x3b\x83\xa1\x46\xa4\x53\x37\x15\x02\x9f\xac\xa9\x0a\x81\x01\xcf\x57\x82\x4f\x15\x12\x1b\x57\xec\x66\xa9\xfa\xfa\xb5\x90\xeb\xeb\x99\x52\x3a\xdf\x4c\xaf\xe3\x56\xdb\xb6\x23\xb0\xb2\xc1\x8c\x95\xda\x10\xfa\x25\x85\x80\xd2\xab\x9a\xe5\x42\x2e\xbd\x52\x06\xa5\x67\xf9\xb8\x08\x2e\x67\x41\x3e\x29\x4e\x9b\x42\x6f\x17\xf6\x8b\x97\x6d\x8b\x9e\x1d\x1c\x46\x72\xb3\xd4\x6d\x8f\xf9\x63\x60\x02\xeb\xfc\x61\xf9\x62\x76\xf0\x9b\x6c\x50\x70\xaa\x2f\x13\xbf\x74\xc6\xc0\xad\x6b\x1a\x69\x8b\x73\x96\xe0\xa7\x07\xf4\x3d\x78\x69\x2b\x84\x0f\xcf\xb8\xfb\x08\x1f\xb6\xd2\x74\x08\xeb\x2c\x96\x6d\xff\x91\xc2\x30\xbc\x27\xce\x02\xb6\xd2\xe8\xca\x66\x8c\x5c\xcb\xce\x19\x23\x4b\x2e\xcd\x8c\x53\x80\xf7\xfd\x7c\x66\x1a\xf3\x82\x7f\xa0\xf3\xe6\x7b\x87\x7e\x07\xc3\xc0\x49\x56\xe1\x15\x99\x13\xbf\x93\xf8\xf6\xf9\xca\x0b\x71\x72\x2a\xe6\x0e\x9d\x86\x3f\x47\xef\x75\x55\x13\x03\xeb\x62\xd7\xfe\xd7\x34\x84\x72\x05\xe6\x85\x53\xcf\xe8\xa1\x8d\xbd\xdb\x2b\x3d\x3e\xdc\x8f\x97\x75\xa4\xfc\xd7\xf4\x4e\x90\xf3\xae\xa3\x2d\x0e\xab\x26\xf8\xc1\x75\x14\xbc\xd0\xdb\x0b\x97\xb8\x74\x8e\x8e\xef\x70\x9b\xff\x2a\x0b\x84\x17\x4d\xf5\x9c\x8b\xf8\x61\x8e\x18\x36\xbb\x7d\x95\xe2\xf8\x09\x6b\xce\x2b\x4d\x75\xb7\x49\x95\x6b\xf8\x13\x86\x50\x7a\xf9\x37\xcb\x7f\x5a\x5e\x63\x3e\x82\xb7\x47\xfa\xb7\x35\xaa\x67\xd7\x11\x50\x8d\x10\x5c\xe7\x15\x42\xd4\x07\x49\xeb\x37\xf5\x2b\xb4\x9d\xb6\x48\xce\x99\xc0\x3d\x56\x2c\x7f\xc3\x78\xe9\xe4\x5f\x64\x20\x78\x6c\x0b\x49\x58\xac\x63\xc9\xd2\x88\xcc\xc0\xd8\x99\x63\xfe\x64\x81\x7b\x4b\xe8\xb7\xd2\xac\xc7\x32\xa7\x13\xba\x80\x87\x6e\x53\x95\xe3\xa8\xe7\xe9\x54\xd9\x38\xe9\x47\x4b\x50\x5e\xb7\x04\xc1\xab\xfd\xd0\x7b\x0a\x7c\x82\x43\x1a\xff\x11\x62\xde\xc5\xd1\x37\xcd\x3c\xc1\xa7\xbf\x67\xdf\xa3\x2d\x86\x61\xf5\x6f\x00\x00\x00\xff\xff\x82\xfc\x97\x4b\x70\x07\x00\x00"),
|
||||
},
|
||||
"/tags.html": &vfsgen۰CompressedFileInfo{
|
||||
name: "tags.html",
|
||||
modTime: time.Date(2018, 10, 4, 18, 37, 50, 489870313, time.UTC),
|
||||
modTime: time.Date(2018, 9, 10, 21, 40, 58, 715425786, time.UTC),
|
||||
uncompressedSize: 2868,
|
||||
|
||||
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x56\xdf\x6f\xdb\x36\x10\x7e\xf7\x5f\x71\x25\x0a\xb4\x05\x2c\x31\xe9\xd6\xb5\x73\x24\x61\x85\x9b\x61\x1d\xf6\x0b\x43\x32\x6c\x08\xf2\x40\x4b\x27\x89\x0e\x4d\xaa\xe4\xc9\x89\xa7\xe9\x7f\x1f\x68\xc9\x8e\xec\xd8\x41\x86\xee\xa1\x7e\x11\x7d\x3f\x3e\x7d\xf7\x9d\xc8\x63\xd3\x64\x98\x4b\x8d\xc0\x48\x14\x8e\xb5\xed\x28\x7a\xf6\xe1\xd7\xe9\xc5\x5f\xbf\x9d\x43\x49\x0b\x95\x8c\xa2\x67\x41\x70\x25\x73\x50\x04\x1f\xcf\xe1\xed\x75\x02\xeb\x5f\xe4\xbd\x90\x2a\xe1\x5c\xcc\xb4\x09\xe6\x0e\x14\x05\x12\xbf\xed\x1e\xef\xba\xc7\x5b\x96\x40\xf4\xec\x0a\x75\x26\xf3\xeb\x20\xb8\x47\x1b\x42\x3d\x01\xed\x11\x98\x77\x4f\x81\x39\x96\x5f\x50\x0f\xe1\x0d\xc9\x81\xfc\x75\x62\x10\xec\x26\x97\x28\xb2\x64\xb4\x7e\xe1\x02\x49\x40\x5a\x0a\xeb\x90\x62\x56\x53\x1e\xbc\x63\xbd\x6b\x26\x1c\x42\x69\x31\x8f\x19\x67\x30\x8c\x2f\x89\xaa\x00\x3f\xd5\x72\x19\xb3\x3f\x83\xcb\xf7\xc1\xd4\x2c\x2a\x41\x72\xa6\x90\x41\x6a\x34\xa1\xa6\x98\x7d\x3c\x8f\x31\x2b\x70\x9c\x96\xd6\x2c\x30\x3e\xdd\xe0\x92\x24\x85\x49\xd3\x40\xf8\x3b\x16\xd2\x91\x5d\x7d\x30\x0b\x21\x35\xb4\x2d\xf7\xd6\x5f\xc4\x02\xa1\x6d\x23\xde\x05\x76\x49\x4a\xea\x1b\xb0\xa8\x62\x26\x53\xa3\x19\xd0\xaa\xc2\x98\xc9\x85\x28\x90\xcb\xd4\xb0\x0d\x51\x47\x82\x64\xca\x73\xb1\xf4\x71\xa1\x77\x3d\x40\x70\xb4\x52\xe8\x4a\x44\xda\x4f\x4b\x9d\xe3\x9d\x37\x4c\x9d\x63\xc0\x93\x51\xc4\x3b\xb5\xa2\x99\xc9\x56\x3d\x54\x79\xfa\x14\xfa\xe5\x69\x1f\x9e\xc9\xe5\xa6\x27\xb7\x56\x54\x15\xda\x9e\x53\x27\x87\x98\x6d\xaa\xbc\xb7\xd9\x5d\x43\x67\x2c\x13\x8f\x1d\x71\x2a\x0f\x7b\x2f\x44\x71\xdc\x39\xb5\x28\x08\xb3\xc3\x01\x4d\x23\x73\x08\x7f\x10\xee\x8f\x5a\x69\xd7\xb6\x3e\xc1\x2f\xd1\x8a\x99\x54\x92\x24\xba\x75\x62\xd3\xa0\xce\xda\x76\x97\x2c\xdf\x67\xdb\x34\x60\x85\x2e\x10\x9e\xdf\xe0\x6a\x0c\xcf\x97\x42\xd5\x08\x93\xd8\x2b\x56\x19\x27\xc9\x58\x89\x0e\xf6\x71\x0e\x17\x9d\xc1\x52\x28\x59\xe8\x98\x29\xcc\x89\x81\x36\x5e\xc3\x87\x91\xdb\x32\x9e\x0f\xeb\x10\x9b\x06\x5b\xac\x8c\x6f\x4f\x47\xa6\x6b\xd2\x3f\x50\x5b\xf5\xa9\x46\xbb\xf2\xbd\x23\x51\x0c\x02\x2e\x44\xe1\x8d\x4b\x8f\xc3\x0e\xd6\x3d\xa8\x76\x08\x7a\x34\x6a\x9f\x1a\x17\x47\x61\x23\x4e\xd9\x61\x2d\x7a\x29\xac\x2c\xca\x2f\x5b\x8b\x2e\xe7\x4b\x91\x62\xc3\xaa\xdf\x04\xe1\xf7\xc6\x2e\x04\x01\x3b\x79\x0d\x3f\x0a\x3d\x86\xd7\x27\x27\xdf\xc0\xe9\x9b\xc9\xc9\xd7\x93\x93\x37\x70\x79\x31\x65\x87\xc8\x1f\xe6\xf2\xa0\x9c\xcf\x64\xfb\x3f\xf5\x09\x64\x16\xb3\x07\xdf\xe6\x64\x3f\x9a\x1d\x26\xb1\x7b\x6a\x39\x59\x68\xa1\x58\x12\xf1\x4c\x2e\x8f\xb0\xe6\xe2\x40\x9b\x8e\x08\xf6\xc4\x43\x04\x75\x36\x6c\x43\xc4\x07\x47\x65\x4f\xe5\xc1\x01\x9b\x1b\x43\xbb\xe7\x6b\x95\xfc\x2c\x32\x84\x5b\x49\x25\x44\xa9\xc9\x30\x89\xbe\x8a\xf8\x7a\x01\xb3\xd5\xbd\xdc\x7e\xa8\xb9\x09\xe7\x85\xa4\xb2\x9e\x85\xa9\x59\xf0\x39\x3a\x97\x5b\xf1\x37\x4b\xbe\xdb\x2c\x7d\x9d\x11\xaf\x76\xf0\xa7\x25\xa6\x37\xa6\x26\xa0\x12\xc1\x99\xda\xa6\x08\x1e\x1f\x04\x4d\x1e\xc5\x2f\x50\xd7\x52\x23\x19\xa3\x1c\xb7\x58\xb0\xe4\x11\xe7\xa1\x37\xff\x24\x1c\xc1\x65\x95\xf9\x8f\x7a\xe2\x25\x0b\xbd\xa5\x37\xac\x87\x50\x35\x94\xcb\xdf\x04\x78\xd8\x49\xe4\x2f\x02\x6b\x8f\x4b\xad\xac\x08\x9c\x4d\xef\xe7\xe0\xdc\xf1\xce\xec\x42\x7f\x85\x88\xfa\x7f\x5d\xc6\xfe\xb0\xd8\x81\xe9\xe6\x32\xe1\x1d\xf1\xb9\x58\x8a\xce\xba\x6d\xc7\x52\x58\x10\x73\x71\x37\x15\x4a\x39\x88\xe1\x6a\x34\x68\xf7\x7f\x9e\x19\x2f\x3e\x6b\x87\x84\x73\x67\xf4\x8b\xf1\xe8\xd8\x07\x77\x7d\xd6\x2f\x6e\xa5\xce\xcc\x6d\x68\xb4\x32\x22\x83\x18\xf2\x5a\xa7\x24\x8d\x7e\xf9\x0a\x9a\x6d\xf6\x7b\x6b\xc5\x2a\xac\xac\x21\xe3\x25\x08\x73\x63\xcf\x45\x5a\x86\xa9\x50\xea\xe5\xb6\xe4\xf1\x7d\x72\x6d\xd5\x18\xa4\xce\xf0\xee\x55\x33\xa8\xc9\xbf\x63\x38\x79\x57\x53\x53\x6b\xf2\xd1\xaf\xce\xb6\x61\xed\x76\xdd\x9e\xf5\xed\xdd\x6d\x50\xb7\xc1\x22\xde\xdd\x59\x22\xde\xdd\x84\x37\xf6\x7f\x03\x00\x00\xff\xff\x88\x1c\x69\x6a\x34\x0b\x00\x00"),
|
||||
},
|
||||
"/vulns.html": &vfsgen۰CompressedFileInfo{
|
||||
name: "vulns.html",
|
||||
modTime: time.Date(2018, 10, 4, 17, 36, 7, 550458133, time.UTC),
|
||||
modTime: time.Date(2018, 9, 10, 21, 40, 58, 715425786, time.UTC),
|
||||
uncompressedSize: 2715,
|
||||
|
||||
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\xdf\x6f\xdb\x36\x10\x7e\xcf\x5f\x71\x21\xfa\x18\x99\x48\x82\xa1\x59\x40\x0b\x5b\x93\x60\x2b\xd0\xfd\x40\x9b\x0e\x1b\x8a\x62\xa0\xa4\xb3\xc4\x86\x22\x35\xf2\xe4\xcd\x13\xf4\xbf\x0f\x12\x2d\x5b\x96\xec\x2c\xc3\xfc\x20\x4b\xbe\xbb\xef\xee\xfb\xee\x74\x74\xd3\x64\xb8\x52\x06\x81\xad\x6b\x6d\x3c\x6b\xdb\x33\x71\x7e\xff\xd3\xdd\xe3\x6f\x3f\x3f\x40\x41\xa5\x8e\xcf\xc4\x79\x14\x7d\x52\x2b\xd0\x04\x6f\x1f\xe0\xf5\xe7\x18\xfa\x8f\xe8\xac\x90\x6a\xe9\xfd\x92\x19\x1b\x7d\xf1\xa0\x29\x52\xf8\x75\xf8\xba\x09\x5f\xaf\x59\x0c\xe2\xfc\x13\x9a\x4c\xad\x3e\x47\xd1\x1e\x6d\x0c\xf5\x02\xb4\x67\x60\x6e\x5e\x02\x73\x2a\x3e\xa7\x2d\x44\xf7\x43\x7c\x24\xbe\x0f\x8c\xa2\xc3\xe0\x02\x65\x16\x9f\xf5\x09\x4b\x24\x09\x69\x21\x9d\x47\x5a\xb2\x9a\x56\xd1\x0d\xdb\x9a\x12\xe9\x11\x0a\x87\xab\x25\xe3\x0c\xc6\xfe\x05\x51\x15\xe1\x1f\xb5\x5a\x2f\xd9\xaf\xd1\xc7\x6f\xa3\x3b\x5b\x56\x92\x54\xa2\x91\x41\x6a\x0d\xa1\xa1\x25\x7b\xfb\xb0\xc4\x2c\xc7\x8b\xb4\x70\xb6\xc4\xe5\xe5\x80\x4b\x8a\x34\xc6\x4d\x03\x8b\xf7\x98\x2b\x4f\x6e\xf3\xf1\xfd\x3b\x68\x5b\x1e\x7e\xaa\x2c\xb4\xed\x6d\x77\xff\x28\x73\x68\x5b\xf8\xa5\xd6\x06\x9d\x4c\x94\x56\xb4\x81\xce\xc1\x91\xe0\x01\x25\x20\x6a\x65\x9e\xc0\xa1\x5e\x32\x95\x5a\xc3\x80\x36\x15\x2e\x99\x2a\x65\x8e\x5c\xa5\x96\x0d\x2c\x3c\x49\x52\x29\x5f\xc9\x75\xe7\xb7\xe8\x4c\x33\x04\x4f\x1b\x8d\xbe\x40\xa4\x69\x58\xea\x3d\x4f\xac\x25\x4f\x4e\x56\x8b\x52\x99\x45\xea\x3d\x03\x1e\x9f\x09\x1e\x14\x15\x89\xcd\x36\x5b\xc4\x4c\xad\x87\x46\x74\x8a\x48\x65\xd0\x6d\xb3\xf5\x76\xbb\xeb\x53\xe2\x50\x66\xa9\xab\xcb\x64\x64\xdf\x56\x15\x0b\xb9\x6b\xc1\x11\xc9\x04\x97\xb1\xe0\x5a\xcd\xe2\x06\x6c\x99\x92\x5a\xe3\x10\x3a\x95\xf6\x30\x54\x70\xab\xe3\xb3\xfd\xe3\x88\x41\x25\x73\x8c\x3a\x8e\x07\x1c\xc2\xc4\x5e\xfe\x87\x56\x0a\x5f\x4a\xad\xe3\xe3\x1d\x0d\x36\xc1\x8b\xcb\x71\x4d\x99\x5a\x8f\x1e\xab\xa1\x22\xc2\xbf\x28\x72\x2a\x2f\x88\xc5\xdf\x61\x87\x46\x98\x81\x35\xb7\xd0\x34\x8b\x7b\x49\xd8\xb1\xab\x46\x74\x9a\x26\xbc\x2e\x8b\x37\x32\xeb\xf2\x7b\xf8\xaa\x6d\x8f\x92\x95\x1a\x1d\x41\x7f\x8d\x32\x69\x72\x74\x0c\x9c\xd5\xb8\xb5\x4c\x04\x68\x9a\x1d\x62\xdb\xc2\xf7\x2a\x2f\x2e\xe0\xce\x29\x52\xa9\xd4\x17\x20\x4d\xc6\xad\x83\x7b\x5c\xa5\xd6\x5c\xc2\x7a\x44\x5c\xa1\x87\x95\xad\x4d\x76\x8a\x6c\xd3\xa0\xc9\xda\x76\xd4\x91\xe2\x2a\xfe\x50\x97\xa5\x74\x1b\xc1\x8b\xab\x91\x2c\xf5\x6e\x98\xb4\xf2\x14\xe5\xce\xd6\xd5\x7c\x98\xe6\x3e\x91\x22\x2c\x27\x8e\xbd\xb3\xaf\xa4\xd9\xcd\xa7\xcc\xf2\x30\x42\x1a\x0d\x2c\x82\x78\x9d\xbc\x9d\xd3\x91\xd8\x24\x7e\xb4\x24\xb5\xe0\xc9\xa4\x82\xd9\xa0\x36\x8d\xeb\xf4\x85\x57\x4f\xb8\xb9\x80\x57\x6b\xa9\x6b\x84\xdb\xe5\x36\xc7\x9b\xcd\x07\x5c\xa3\x53\xb4\x19\x35\xea\xff\x51\xd1\x32\x41\x0d\xfd\x35\x6a\x9a\xd4\x6a\xeb\xfa\xe4\x6d\x0b\x55\xad\xf5\x30\x50\x5b\xaa\xdb\x82\x4e\x53\x6d\x9a\x3e\x1a\xa6\xf5\x1d\x21\x1a\x5a\xb9\xf7\xa8\x0f\x5e\xb5\xe2\x2a\xbe\x47\x92\x4a\xfb\xc3\xc6\xee\x04\xea\x4f\xb7\x7f\x91\x66\xef\x3c\xe8\x18\xc2\x4e\x8c\x79\x25\x0d\x6a\xe8\xaf\x51\x86\x2b\x59\xeb\xe9\x68\xcf\xbc\xfb\x15\xa0\x4c\x7e\x4c\xe6\xe2\xfa\xd0\xb5\xdf\xcf\x9d\x94\xa1\x9c\xc5\x8f\xb2\xc4\x89\x4e\x2f\x6f\x51\x80\xd8\x73\x9e\x74\x6b\x66\x3f\x39\x9b\xbc\xb8\x9e\x0e\xe5\xc1\x3b\x77\x9c\x76\xb7\xd6\x8f\x70\xde\x25\xbe\x47\x9f\x3a\x55\x91\xb2\x66\x36\x0a\x2f\x80\x5f\x59\x4b\xb3\xc5\xda\xbb\x0e\xcb\x7f\x97\xe9\x9d\x32\x4f\x6d\xcb\x80\xa4\xcb\xbb\x03\xfb\xf7\x44\x4b\xf3\x34\xd2\x20\x38\x74\xe7\xc2\x73\x75\x9c\xd8\x34\xd3\xe7\xbd\x7f\x28\xf1\x60\xf9\xa6\x68\xe6\x55\x8b\x2a\xfe\x41\x66\x08\x7f\x2a\x2a\x40\xa4\x36\xc3\x58\x5c\x0b\xde\xdf\x40\xb2\xd9\x33\xea\xfe\x42\xf8\x5b\xce\x73\x45\x45\x9d\x2c\x52\x5b\xf2\x2f\xe8\xfd\xca\xc9\xbf\x59\xfc\xcd\x70\x1b\xce\xb7\x6a\x96\xe3\xae\xc0\xf4\xc9\xd6\x04\x54\x20\x78\x5b\xbb\x14\xa1\xcb\x01\x92\x6e\x9f\xcd\x91\xa3\xa9\x95\x41\xb2\x56\x7b\xee\x30\x67\xf1\x33\xc6\x59\x76\xc1\x83\x0e\xdb\x23\x3e\x88\x28\x78\x38\xf5\x05\x0f\xff\x37\x07\xf1\xfe\x09\x00\x00\xff\xff\x30\xe0\x25\xc3\x9b\x0a\x00\x00"),
|
||||
|
|
6
layer.go
6
layer.go
|
@ -38,19 +38,19 @@ func (cmd *layerCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, image.Domain)
|
||||
r, err := createRegistryClient(image.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the digest.
|
||||
digest, err := r.Digest(ctx, image)
|
||||
digest, err := r.Digest(image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Download the layer.
|
||||
layer, err := r.DownloadLayer(ctx, image.Path, digest)
|
||||
layer, err := r.DownloadLayer(image.Path, digest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
10
list.go
10
list.go
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -30,16 +29,13 @@ func (cmd *listCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, args[0])
|
||||
r, err := createRegistryClient(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Get the repositories via catalog.
|
||||
repos, err := r.Catalog(ctx, "")
|
||||
repos, err := r.Catalog("")
|
||||
if err != nil {
|
||||
if _, ok := err.(*json.SyntaxError); ok {
|
||||
return fmt.Errorf("domain %s is not a valid registry", r.Domain)
|
||||
}
|
||||
return err
|
||||
}
|
||||
sort.Strings(repos)
|
||||
|
@ -56,7 +52,7 @@ func (cmd *listCommand) Run(ctx context.Context, args []string) error {
|
|||
for _, repo := range repos {
|
||||
go func(repo string) {
|
||||
// Get the tags.
|
||||
tags, err := r.Tags(ctx, repo)
|
||||
tags, err := r.Tags(repo)
|
||||
if err != nil {
|
||||
fmt.Printf("Get tags of [%s] error: %s", repo, err)
|
||||
}
|
||||
|
|
22
main.go
22
main.go
|
@ -24,7 +24,6 @@ var (
|
|||
|
||||
timeout time.Duration
|
||||
|
||||
authURL string
|
||||
username string
|
||||
password string
|
||||
|
||||
|
@ -65,8 +64,6 @@ func main() {
|
|||
|
||||
p.FlagSet.DurationVar(&timeout, "timeout", time.Minute, "timeout for HTTP requests")
|
||||
|
||||
p.FlagSet.StringVar(&authURL, "auth-url", "", "alternate URL for registry authentication (ex. auth.docker.io)")
|
||||
|
||||
p.FlagSet.StringVar(&username, "username", "", "username for the registry")
|
||||
p.FlagSet.StringVar(&username, "u", "", "username for the registry")
|
||||
|
||||
|
@ -78,7 +75,7 @@ func main() {
|
|||
// Set the before function.
|
||||
p.Before = func(ctx context.Context) error {
|
||||
// On ^C, or SIGTERM handle exit.
|
||||
signals := make(chan os.Signal)
|
||||
signals := make(chan os.Signal, 0)
|
||||
signal.Notify(signals, os.Interrupt)
|
||||
signal.Notify(signals, syscall.SIGTERM)
|
||||
_, cancel := context.WithCancel(ctx)
|
||||
|
@ -102,31 +99,22 @@ func main() {
|
|||
p.Run()
|
||||
}
|
||||
|
||||
func createRegistryClient(ctx context.Context, domain string) (*registry.Registry, error) {
|
||||
// Use the auth-url domain if provided.
|
||||
authDomain := authURL
|
||||
if authDomain == "" {
|
||||
authDomain = domain
|
||||
}
|
||||
auth, err := repoutils.GetAuthConfig(username, password, authDomain)
|
||||
func createRegistryClient(domain string) (*registry.Registry, error) {
|
||||
auth, err := repoutils.GetAuthConfig(username, password, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Prevent non-ssl unless explicitly forced
|
||||
if !forceNonSSL && strings.HasPrefix(auth.ServerAddress, "http:") {
|
||||
return nil, fmt.Errorf("attempted to use insecure protocol! Use force-non-ssl option to force")
|
||||
return nil, fmt.Errorf("Attempted to use insecure protocol! Use force-non-ssl option to force")
|
||||
}
|
||||
|
||||
// Create the registry client.
|
||||
logrus.Infof("domain: %s", domain)
|
||||
logrus.Infof("server address: %s", auth.ServerAddress)
|
||||
return registry.New(ctx, auth, registry.Opt{
|
||||
Domain: domain,
|
||||
return registry.New(auth, registry.Opt{
|
||||
Insecure: insecure,
|
||||
Debug: debug,
|
||||
SkipPing: skipPing,
|
||||
NonSSL: forceNonSSL,
|
||||
Timeout: timeout,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ func (cmd *manifestCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, image.Domain)
|
||||
r, err := createRegistryClient(image.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -44,13 +44,13 @@ func (cmd *manifestCommand) Run(ctx context.Context, args []string) error {
|
|||
var manifest interface{}
|
||||
if cmd.v1 {
|
||||
// Get the v1 manifest if it was explicitly asked for.
|
||||
manifest, err = r.ManifestV1(ctx, image.Path, image.Reference())
|
||||
manifest, err = r.ManifestV1(image.Path, image.Reference())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Get the v2 manifest.
|
||||
manifest, err = r.Manifest(ctx, image.Path, image.Reference())
|
||||
manifest, err = r.Manifest(image.Path, image.Reference())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -29,16 +29,3 @@ func TestManifestV1(t *testing.T) {
|
|||
t.Fatalf("expected: %s\ngot: %s", expected, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestManifestWithHubDomain(t *testing.T) {
|
||||
// Regression test for https://github.com/genuinetools/reg/issues/164
|
||||
out, err := run("manifest", "busybox")
|
||||
if err != nil {
|
||||
t.Fatalf("output: %s, error: %v", out, err)
|
||||
}
|
||||
|
||||
expected := `"schemaVersion": 2,`
|
||||
if !strings.Contains(out, expected) {
|
||||
t.Fatalf("expected: %s\ngot: %s", expected, out)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/peterhellberg/link"
|
||||
|
@ -12,7 +11,7 @@ type catalogResponse struct {
|
|||
}
|
||||
|
||||
// Catalog returns the repositories in a registry.
|
||||
func (r *Registry) Catalog(ctx context.Context, u string) ([]string, error) {
|
||||
func (r *Registry) Catalog(u string) ([]string, error) {
|
||||
if u == "" {
|
||||
u = "/v2/_catalog"
|
||||
}
|
||||
|
@ -20,7 +19,7 @@ func (r *Registry) Catalog(ctx context.Context, u string) ([]string, error) {
|
|||
r.Logf("registry.catalog url=%s", uri)
|
||||
|
||||
var response catalogResponse
|
||||
h, err := r.getJSON(ctx, uri, &response)
|
||||
h, err := r.getJSON(uri, &response, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -28,7 +27,7 @@ func (r *Registry) Catalog(ctx context.Context, u string) ([]string, error) {
|
|||
for _, l := range link.ParseHeader(h) {
|
||||
if l.Rel == "next" {
|
||||
unescaped, _ := url.QueryUnescape(l.URI)
|
||||
repos, err := r.Catalog(ctx, unescaped)
|
||||
repos, err := r.Catalog(unescaped)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
|
@ -11,7 +10,7 @@ import (
|
|||
|
||||
// Delete removes a repository digest from the registry.
|
||||
// https://docs.docker.com/registry/spec/api/#deleting-an-image
|
||||
func (r *Registry) Delete(ctx context.Context, repository string, digest digest.Digest) (err error) {
|
||||
func (r *Registry) Delete(repository string, digest digest.Digest) (err error) {
|
||||
url := r.url("/v2/%s/manifests/%s", repository, digest)
|
||||
r.Logf("registry.manifests.delete url=%s repository=%s digest=%s",
|
||||
url, repository, digest)
|
||||
|
@ -22,7 +21,7 @@ func (r *Registry) Delete(ctx context.Context, repository string, digest digest.
|
|||
}
|
||||
|
||||
req.Header.Add("Accept", fmt.Sprintf("%s;q=0.9", schema2.MediaTypeManifest))
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -32,5 +31,5 @@ func (r *Registry) Delete(ctx context.Context, repository string, digest digest.
|
|||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("got status code: %d", resp.StatusCode)
|
||||
return fmt.Errorf("Got status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
|
@ -10,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
// Digest returns the digest for an image.
|
||||
func (r *Registry) Digest(ctx context.Context, image Image) (digest.Digest, error) {
|
||||
func (r *Registry) Digest(image Image) (digest.Digest, error) {
|
||||
if len(image.Digest) > 1 {
|
||||
// return early if we already have an image digest.
|
||||
return image.Digest, nil
|
||||
|
@ -26,14 +25,14 @@ func (r *Registry) Digest(ctx context.Context, image Image) (digest.Digest, erro
|
|||
}
|
||||
|
||||
req.Header.Add("Accept", schema2.MediaTypeManifest)
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound {
|
||||
return "", fmt.Errorf("got status code: %d", resp.StatusCode)
|
||||
return "", fmt.Errorf("Got status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return digest.Parse(resp.Header.Get("Docker-Content-Digest"))
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/genuinetools/reg/repoutils"
|
||||
)
|
||||
|
||||
func TestDigestFromDockerHub(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
auth, err := repoutils.GetAuthConfig("", "", "docker.io")
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get auth config: %s", err)
|
||||
}
|
||||
|
||||
r, err := New(ctx, auth, Opt{})
|
||||
r, err := New(auth, Opt{})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not create registry instance: %s", err)
|
||||
}
|
||||
|
||||
d, err := r.Digest(ctx, Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"})
|
||||
d, err := r.Digest(Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get digest: %s", err)
|
||||
}
|
||||
|
@ -30,18 +28,17 @@ func TestDigestFromDockerHub(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDigestFromGCR(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
auth, err := repoutils.GetAuthConfig("", "", "gcr.io")
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get auth config: %s", err)
|
||||
}
|
||||
|
||||
r, err := New(ctx, auth, Opt{SkipPing: true})
|
||||
r, err := New(auth, Opt{})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not create registry instance: %s", err)
|
||||
}
|
||||
|
||||
d, err := r.Digest(ctx, Image{Domain: "gcr.io", Path: "google-containers/hyperkube", Tag: "v1.9.9"})
|
||||
d, err := r.Digest(Image{Domain: "gcr.io", Path: "google_containers/hyperkube", Tag: "v1.9.9"})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get digest: %s", err)
|
||||
}
|
||||
|
|
|
@ -1,27 +1,21 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// DownloadLayer downloads a specific layer by digest for a repository.
|
||||
func (r *Registry) DownloadLayer(ctx context.Context, repository string, digest digest.Digest) (io.ReadCloser, error) {
|
||||
func (r *Registry) DownloadLayer(repository string, digest digest.Digest) (io.ReadCloser, error) {
|
||||
url := r.url("/v2/%s/blobs/%s", repository, digest)
|
||||
r.Logf("registry.layer.download url=%s repository=%s digest=%s", url, repository, digest)
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -30,8 +24,8 @@ func (r *Registry) DownloadLayer(ctx context.Context, repository string, digest
|
|||
}
|
||||
|
||||
// UploadLayer uploads a specific layer by digest for a repository.
|
||||
func (r *Registry) UploadLayer(ctx context.Context, repository string, digest reference.Reference, content io.Reader) error {
|
||||
uploadURL, token, err := r.initiateUpload(ctx, repository)
|
||||
func (r *Registry) UploadLayer(repository string, digest reference.Reference, content io.Reader) error {
|
||||
uploadURL, token, err := r.initiateUpload(repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,20 +42,16 @@ func (r *Registry) UploadLayer(ctx context.Context, repository string, digest re
|
|||
upload.Header.Set("Content-Type", "application/octet-stream")
|
||||
upload.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
|
||||
_, err = r.Client.Do(upload.WithContext(ctx))
|
||||
_, err = r.Client.Do(upload)
|
||||
return err
|
||||
}
|
||||
|
||||
// HasLayer returns if the registry contains the specific digest for a repository.
|
||||
func (r *Registry) HasLayer(ctx context.Context, repository string, digest digest.Digest) (bool, error) {
|
||||
func (r *Registry) HasLayer(repository string, digest digest.Digest) (bool, error) {
|
||||
checkURL := r.url("/v2/%s/blobs/%s", repository, digest)
|
||||
r.Logf("registry.layer.check url=%s repository=%s digest=%s", checkURL, repository, digest)
|
||||
|
||||
req, err := http.NewRequest("HEAD", checkURL, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Head(checkURL)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
|
@ -82,16 +72,11 @@ func (r *Registry) HasLayer(ctx context.Context, repository string, digest diges
|
|||
return false, err
|
||||
}
|
||||
|
||||
func (r *Registry) initiateUpload(ctx context.Context, repository string) (*url.URL, string, error) {
|
||||
func (r *Registry) initiateUpload(repository string) (*url.URL, string, error) {
|
||||
initiateURL := r.url("/v2/%s/blobs/uploads/", repository)
|
||||
r.Logf("registry.layer.initiate-upload url=%s repository=%s", initiateURL, repository)
|
||||
|
||||
req, err := http.NewRequest("POST", initiateURL, nil)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Post(initiateURL, "application/octet-stream", nil)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@ package registry
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
|
@ -14,13 +13,8 @@ import (
|
|||
"github.com/docker/distribution/manifest/schema2"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnexpectedSchemaVersion a specific schema version was requested, but was not returned
|
||||
ErrUnexpectedSchemaVersion = errors.New("recieved a different schema version than expected")
|
||||
)
|
||||
|
||||
// Manifest returns the manifest for a specific repository:tag.
|
||||
func (r *Registry) Manifest(ctx context.Context, repository, ref string) (distribution.Manifest, error) {
|
||||
func (r *Registry) Manifest(repository, ref string) (distribution.Manifest, error) {
|
||||
uri := r.url("/v2/%s/manifests/%s", repository, ref)
|
||||
r.Logf("registry.manifests uri=%s repository=%s ref=%s", uri, repository, ref)
|
||||
|
||||
|
@ -29,9 +23,9 @@ func (r *Registry) Manifest(ctx context.Context, repository, ref string) (distri
|
|||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Accept", schema2.MediaTypeManifest)
|
||||
req.Header.Add("Accept", fmt.Sprintf("%s;q=0.9", schema2.MediaTypeManifest))
|
||||
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -52,12 +46,12 @@ func (r *Registry) Manifest(ctx context.Context, repository, ref string) (distri
|
|||
}
|
||||
|
||||
// ManifestList gets the registry v2 manifest list.
|
||||
func (r *Registry) ManifestList(ctx context.Context, repository, ref string) (manifestlist.ManifestList, error) {
|
||||
func (r *Registry) ManifestList(repository, ref string) (manifestlist.ManifestList, error) {
|
||||
uri := r.url("/v2/%s/manifests/%s", repository, ref)
|
||||
r.Logf("registry.manifests uri=%s repository=%s ref=%s", uri, repository, ref)
|
||||
|
||||
var m manifestlist.ManifestList
|
||||
if _, err := r.getJSON(ctx, uri, &m); err != nil {
|
||||
if _, err := r.getJSON(uri, &m, true); err != nil {
|
||||
r.Logf("registry.manifests response=%v", m)
|
||||
return m, err
|
||||
}
|
||||
|
@ -66,43 +60,35 @@ func (r *Registry) ManifestList(ctx context.Context, repository, ref string) (ma
|
|||
}
|
||||
|
||||
// ManifestV2 gets the registry v2 manifest.
|
||||
func (r *Registry) ManifestV2(ctx context.Context, repository, ref string) (schema2.Manifest, error) {
|
||||
func (r *Registry) ManifestV2(repository, ref string) (schema2.Manifest, error) {
|
||||
uri := r.url("/v2/%s/manifests/%s", repository, ref)
|
||||
r.Logf("registry.manifests uri=%s repository=%s ref=%s", uri, repository, ref)
|
||||
|
||||
var m schema2.Manifest
|
||||
if _, err := r.getJSON(ctx, uri, &m); err != nil {
|
||||
if _, err := r.getJSON(uri, &m, true); err != nil {
|
||||
r.Logf("registry.manifests response=%v", m)
|
||||
return m, err
|
||||
}
|
||||
|
||||
if m.Versioned.SchemaVersion != 2 {
|
||||
return m, ErrUnexpectedSchemaVersion
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// ManifestV1 gets the registry v1 manifest.
|
||||
func (r *Registry) ManifestV1(ctx context.Context, repository, ref string) (schema1.SignedManifest, error) {
|
||||
func (r *Registry) ManifestV1(repository, ref string) (schema1.SignedManifest, error) {
|
||||
uri := r.url("/v2/%s/manifests/%s", repository, ref)
|
||||
r.Logf("registry.manifests uri=%s repository=%s ref=%s", uri, repository, ref)
|
||||
|
||||
var m schema1.SignedManifest
|
||||
if _, err := r.getJSON(ctx, uri, &m); err != nil {
|
||||
if _, err := r.getJSON(uri, &m, false); err != nil {
|
||||
r.Logf("registry.manifests response=%v", m)
|
||||
return m, err
|
||||
}
|
||||
|
||||
if m.Versioned.SchemaVersion != 1 {
|
||||
return m, ErrUnexpectedSchemaVersion
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// PutManifest calls a PUT for the specific manifest for an image.
|
||||
func (r *Registry) PutManifest(ctx context.Context, repository, ref string, manifest distribution.Manifest) error {
|
||||
func (r *Registry) PutManifest(repository, ref string, manifest distribution.Manifest) error {
|
||||
url := r.url("/v2/%s/manifests/%s", repository, ref)
|
||||
r.Logf("registry.manifest.put url=%s repository=%s reference=%s", url, repository, ref)
|
||||
|
||||
|
@ -117,7 +103,7 @@ func (r *Registry) PutManifest(ctx context.Context, repository, ref string, mani
|
|||
}
|
||||
|
||||
req.Header.Set("Content-Type", schema2.MediaTypeManifest)
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Do(req)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pingable checks pingable
|
||||
func (r *Registry) Pingable() bool {
|
||||
// Currently *.gcr.io/v2 can't be ping if users have each projects auth
|
||||
return !strings.HasSuffix(r.URL, "gcr.io")
|
||||
}
|
||||
|
||||
// Ping tries to contact a registry URL to make sure it is up and accessible.
|
||||
func (r *Registry) Ping(ctx context.Context) error {
|
||||
func (r *Registry) Ping() error {
|
||||
url := r.url("/v2/")
|
||||
r.Logf("registry.ping url=%s", url)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Get(url)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPingable(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
registry Registry
|
||||
expect bool
|
||||
}{
|
||||
"Docker": {
|
||||
registry: Registry{URL: "https://registry-1.docker.io"},
|
||||
expect: true,
|
||||
},
|
||||
"GCR_global": {
|
||||
registry: Registry{URL: "https://gcr.io"},
|
||||
expect: false,
|
||||
},
|
||||
"GCR_asia": {
|
||||
registry: Registry{URL: "https://asia.gcr.io"},
|
||||
expect: false,
|
||||
},
|
||||
}
|
||||
for label, testcase := range testcases {
|
||||
actual := testcase.registry.Pingable()
|
||||
if testcase.expect != actual {
|
||||
t.Fatalf("%s: expected (%v), got (%v)", label, testcase.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -16,7 +15,7 @@ import (
|
|||
"github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
// Registry defines the client for retrieving information from the registry API.
|
||||
// Registry defines the client for retriving information from the registry API.
|
||||
type Registry struct {
|
||||
URL string
|
||||
Domain string
|
||||
|
@ -42,17 +41,15 @@ func Log(format string, args ...interface{}) {
|
|||
|
||||
// Opt holds the options for a new registry.
|
||||
type Opt struct {
|
||||
Domain string
|
||||
Insecure bool
|
||||
Debug bool
|
||||
SkipPing bool
|
||||
NonSSL bool
|
||||
Timeout time.Duration
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// New creates a new Registry struct with the given URL and credentials.
|
||||
func New(ctx context.Context, auth types.AuthConfig, opt Opt) (*Registry, error) {
|
||||
func New(auth types.AuthConfig, opt Opt) (*Registry, error) {
|
||||
transport := http.DefaultTransport
|
||||
|
||||
if opt.Insecure {
|
||||
|
@ -63,30 +60,14 @@ func New(ctx context.Context, auth types.AuthConfig, opt Opt) (*Registry, error)
|
|||
}
|
||||
}
|
||||
|
||||
return newFromTransport(ctx, auth, transport, opt)
|
||||
return newFromTransport(auth, transport, opt)
|
||||
}
|
||||
|
||||
func newFromTransport(ctx context.Context, auth types.AuthConfig, transport http.RoundTripper, opt Opt) (*Registry, error) {
|
||||
if len(opt.Domain) < 1 || opt.Domain == "docker.io" {
|
||||
opt.Domain = auth.ServerAddress
|
||||
}
|
||||
url := strings.TrimSuffix(opt.Domain, "/")
|
||||
authURL := strings.TrimSuffix(auth.ServerAddress, "/")
|
||||
func newFromTransport(auth types.AuthConfig, transport http.RoundTripper, opt Opt) (*Registry, error) {
|
||||
url := strings.TrimSuffix(auth.ServerAddress, "/")
|
||||
|
||||
if !reProtocol.MatchString(url) {
|
||||
if !opt.NonSSL {
|
||||
url = "https://" + url
|
||||
} else {
|
||||
url = "http://" + url
|
||||
}
|
||||
}
|
||||
|
||||
if !reProtocol.MatchString(authURL) {
|
||||
if !opt.NonSSL {
|
||||
authURL = "https://" + authURL
|
||||
} else {
|
||||
authURL = "http://" + authURL
|
||||
}
|
||||
}
|
||||
|
||||
tokenTransport := &TokenTransport{
|
||||
|
@ -96,7 +77,7 @@ func newFromTransport(ctx context.Context, auth types.AuthConfig, transport http
|
|||
}
|
||||
basicAuthTransport := &BasicTransport{
|
||||
Transport: tokenTransport,
|
||||
URL: authURL,
|
||||
URL: url,
|
||||
Username: auth.Username,
|
||||
Password: auth.Password,
|
||||
}
|
||||
|
@ -127,8 +108,8 @@ func newFromTransport(ctx context.Context, auth types.AuthConfig, transport http
|
|||
Opt: opt,
|
||||
}
|
||||
|
||||
if registry.Pingable() && !opt.SkipPing {
|
||||
if err := registry.Ping(ctx); err != nil {
|
||||
if !opt.SkipPing {
|
||||
if err := registry.Ping(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -143,20 +124,15 @@ func (r *Registry) url(pathTemplate string, args ...interface{}) string {
|
|||
return url
|
||||
}
|
||||
|
||||
func (r *Registry) getJSON(ctx context.Context, url string, response interface{}) (http.Header, error) {
|
||||
func (r *Registry) getJSON(url string, response interface{}, addV2Header bool) (http.Header, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch response.(type) {
|
||||
case *schema2.Manifest:
|
||||
req.Header.Add("Accept", schema2.MediaTypeManifest)
|
||||
case *manifestlist.ManifestList:
|
||||
req.Header.Add("Accept", manifestlist.MediaTypeManifestList)
|
||||
if addV2Header {
|
||||
req.Header.Add("Accept", fmt.Sprintf("%s,%s;q=0.9", schema2.MediaTypeManifest, manifestlist.MediaTypeManifestList))
|
||||
}
|
||||
|
||||
resp, err := r.Client.Do(req.WithContext(ctx))
|
||||
resp, err := r.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package registry
|
||||
|
||||
import "context"
|
||||
|
||||
type tagsResponse struct {
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// Tags returns the tags for a specific repository.
|
||||
func (r *Registry) Tags(ctx context.Context, repository string) ([]string, error) {
|
||||
func (r *Registry) Tags(repository string) ([]string, error) {
|
||||
url := r.url("/v2/%s/tags/list", repository)
|
||||
r.Logf("registry.tags url=%s repository=%s", url, repository)
|
||||
|
||||
var response tagsResponse
|
||||
if _, err := r.getJSON(ctx, url, &response); err != nil {
|
||||
if _, err := r.getJSON(url, &response, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
@ -9,11 +8,8 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var gcrMatcher = regexp.MustCompile(`https://([a-z]+\.|)gcr\.io/`)
|
||||
|
||||
// TokenTransport defines the data structure for authentication via tokens.
|
||||
type TokenTransport struct {
|
||||
Transport http.RoundTripper
|
||||
|
@ -30,7 +26,6 @@ func (t *TokenTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
|
||||
authService, err := isTokenDemand(resp)
|
||||
if err != nil {
|
||||
resp.Body.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -38,28 +33,15 @@ func (t *TokenTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
resp.Body.Close()
|
||||
|
||||
return t.authAndRetry(authService, req)
|
||||
}
|
||||
|
||||
type authToken struct {
|
||||
Token string `json:"token"`
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
func (t authToken) String() (string, error) {
|
||||
if t.Token != "" {
|
||||
return t.Token, nil
|
||||
}
|
||||
if t.AccessToken != "" {
|
||||
return t.AccessToken, nil
|
||||
}
|
||||
return "", errors.New("auth token cannot be empty")
|
||||
}
|
||||
|
||||
func (t *TokenTransport) authAndRetry(authService *authService, req *http.Request) (*http.Response, error) {
|
||||
token, authResp, err := t.auth(req.Context(), authService)
|
||||
token, authResp, err := t.auth(authService)
|
||||
if err != nil {
|
||||
return authResp, err
|
||||
}
|
||||
|
@ -71,7 +53,7 @@ func (t *TokenTransport) authAndRetry(authService *authService, req *http.Reques
|
|||
return response, err
|
||||
}
|
||||
|
||||
func (t *TokenTransport) auth(ctx context.Context, authService *authService) (string, *http.Response, error) {
|
||||
func (t *TokenTransport) auth(authService *authService) (string, *http.Response, error) {
|
||||
authReq, err := authService.Request(t.Username, t.Password)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
|
@ -81,7 +63,7 @@ func (t *TokenTransport) auth(ctx context.Context, authService *authService) (st
|
|||
Transport: t.Transport,
|
||||
}
|
||||
|
||||
resp, err := c.Do(authReq.WithContext(ctx))
|
||||
resp, err := c.Do(authReq)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -96,8 +78,7 @@ func (t *TokenTransport) auth(ctx context.Context, authService *authService) (st
|
|||
return "", nil, err
|
||||
}
|
||||
|
||||
token, err := authToken.String()
|
||||
return token, nil, err
|
||||
return authToken.Token, nil, nil
|
||||
}
|
||||
|
||||
func (t *TokenTransport) retry(req *http.Request, token string) (*http.Response, error) {
|
||||
|
@ -141,7 +122,7 @@ func isTokenDemand(resp *http.Response) (*authService, error) {
|
|||
|
||||
// Token returns the required token for the specific resource url. If the registry requires basic authentication, this
|
||||
// function returns ErrBasicAuth.
|
||||
func (r *Registry) Token(ctx context.Context, url string) (string, error) {
|
||||
func (r *Registry) Token(url string) (string, error) {
|
||||
r.Logf("registry.token url=%s", url)
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
|
@ -161,19 +142,12 @@ func (r *Registry) Token(ctx context.Context, url string) (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
resp, err := client.Do(req.WithContext(ctx))
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusForbidden && gcrMatcher.MatchString(url) {
|
||||
// GCR is not sending HTTP 401 on missing credentials but a HTTP 403 without
|
||||
// any further information about why the request failed. Sending the credentials
|
||||
// from the Docker config fixes this.
|
||||
return "", ErrBasicAuth
|
||||
}
|
||||
|
||||
a, err := isTokenDemand(resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -188,14 +162,14 @@ func (r *Registry) Token(ctx context.Context, url string) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err = http.DefaultClient.Do(authReq.WithContext(ctx))
|
||||
resp, err = http.DefaultClient.Do(authReq)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("getting token failed with StatusCode != StatusOK but %d", resp.StatusCode)
|
||||
return "", fmt.Errorf("Getting token failed with StatusCode != StatusOK but %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var authToken authToken
|
||||
|
@ -203,13 +177,17 @@ func (r *Registry) Token(ctx context.Context, url string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
return authToken.String()
|
||||
if authToken.Token == "" {
|
||||
return "", errors.New("Auth token cannot be empty")
|
||||
}
|
||||
|
||||
return authToken.Token, nil
|
||||
}
|
||||
|
||||
// Headers returns the authorization headers for a specific uri.
|
||||
func (r *Registry) Headers(ctx context.Context, uri string) (map[string]string, error) {
|
||||
func (r *Registry) Headers(uri string) (map[string]string, error) {
|
||||
// Get the token.
|
||||
token, err := r.Token(ctx, uri)
|
||||
token, err := r.Token(uri)
|
||||
if err != nil {
|
||||
if err == ErrBasicAuth {
|
||||
// If we couldn't get a token because the server requires basic auth, just return basic auth headers.
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
func TestErrBasicAuth(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/" {
|
||||
w.Header().Set("www-authenticate", `Basic realm="Registry Realm",service="Docker registry"`)
|
||||
|
@ -28,11 +24,11 @@ func TestErrBasicAuth(t *testing.T) {
|
|||
Password: "ss3j",
|
||||
ServerAddress: ts.URL,
|
||||
}
|
||||
r, err := New(ctx, authConfig, Opt{Insecure: true, Debug: true})
|
||||
r, err := New(authConfig, Opt{Insecure: true, Debug: true})
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error creating client, got %v", err)
|
||||
}
|
||||
token, err := r.Token(ctx, ts.URL)
|
||||
token, err := r.Token(ts.URL)
|
||||
if err != ErrBasicAuth {
|
||||
t.Fatalf("expected ErrBasicAuth getting token, got %v", err)
|
||||
}
|
||||
|
@ -40,157 +36,3 @@ func TestErrBasicAuth(t *testing.T) {
|
|||
t.Fatalf("expected empty token, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var authURI string
|
||||
|
||||
func oauthFlow(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/oauth2/accesstoken") {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"access_token":"abcdef1234"}`))
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(r.URL.Path, "/oauth2/token") {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"token":"abcdef1234"}`))
|
||||
return
|
||||
}
|
||||
auth := r.Header.Get("authorization")
|
||||
if !strings.HasPrefix(auth, "Bearer") {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
if authURI != "" {
|
||||
w.Header().Set("www-authenticate", `Bearer realm="`+authURI+`/oauth2/token",service="my.endpoint.here"`)
|
||||
}
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}`))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func TestBothTokenAndAccessTokenWork(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(oauthFlow))
|
||||
defer ts.Close()
|
||||
|
||||
for _, which := range []string{"token", "accesstoken"} {
|
||||
ctx := context.Background()
|
||||
authURI = ts.URL + "/oauth2/" + which + "?service=my.endpoint.here"
|
||||
authConfig := types.AuthConfig{
|
||||
Username: "abc",
|
||||
Password: "123",
|
||||
ServerAddress: ts.URL,
|
||||
}
|
||||
authConfig.Email = "me@email.com"
|
||||
r, err := New(ctx, authConfig, Opt{Insecure: true, Debug: true})
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error creating client, got %v", err)
|
||||
}
|
||||
token, err := r.Token(ctx, ts.URL)
|
||||
if err != nil {
|
||||
t.Fatalf("err getting token from url: %v err: %v", ts.URL, err)
|
||||
}
|
||||
if token == "" {
|
||||
t.Fatalf("error got empty token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testTransport func(*http.Request) (*http.Response, error)
|
||||
|
||||
func (tt testTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return tt(req)
|
||||
}
|
||||
|
||||
func TestTokenTransportErrorHandling(t *testing.T) {
|
||||
tokenTransport := &TokenTransport{
|
||||
Transport: testTransport(func(req *http.Request) (*http.Response, error) {
|
||||
return nil, errors.New("transport failed")
|
||||
}),
|
||||
}
|
||||
_, err := tokenTransport.RoundTrip(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
if err == nil {
|
||||
t.Fatalf("got no error from round trip: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
type testBody struct {
|
||||
t *testing.T
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (tb *testBody) Read(p []byte) (n int, err error) {
|
||||
tb.t.Helper()
|
||||
panic("unexpected read")
|
||||
}
|
||||
|
||||
func (tb *testBody) Close() error {
|
||||
tb.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestTokenTransportTokenDemandErr(t *testing.T) {
|
||||
body := &testBody{t: t}
|
||||
tokenTransport := &TokenTransport{
|
||||
Transport: testTransport(func(req *http.Request) (*http.Response, error) {
|
||||
return &http.Response{
|
||||
Body: body,
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
}, nil
|
||||
}),
|
||||
}
|
||||
resp, err := tokenTransport.RoundTrip(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
if err == nil {
|
||||
t.Fatal("Expected error due to missing auth challenge header, got none")
|
||||
}
|
||||
if resp != nil {
|
||||
t.Fatal("Expected no response")
|
||||
}
|
||||
if !body.closed {
|
||||
t.Fatal("Expected body to be closed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenTransportAuthLeak(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(oauthFlow))
|
||||
authURI = ts.URL + "/oauth2/token?service=my.endpoint.here"
|
||||
callCounter := 0
|
||||
body := &testBody{t: t}
|
||||
tokenTransport := &TokenTransport{
|
||||
Transport: testTransport(func(req *http.Request) (*http.Response, error) {
|
||||
callCounter++
|
||||
switch callCounter {
|
||||
case 1: // failing authentication
|
||||
header := http.Header{}
|
||||
header.Set("www-authenticate", `Bearer realm="`+authURI+`/oauth2/token",service="my.endpoint.here"`)
|
||||
return &http.Response{
|
||||
Body: body,
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
Header: header,
|
||||
}, nil
|
||||
case 2: // auth request
|
||||
return ts.Client().Transport.RoundTrip(req)
|
||||
default:
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: &testBody{t: t},
|
||||
Header: http.Header{},
|
||||
}, nil
|
||||
|
||||
}
|
||||
}),
|
||||
}
|
||||
resp, err := tokenTransport.RoundTrip(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %s", err)
|
||||
}
|
||||
if resp == nil {
|
||||
t.Fatal("Response is missing")
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
if !body.closed {
|
||||
t.Fatal("Expected body to be closed")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,13 +31,13 @@ func (cmd *removeCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, image.Domain)
|
||||
r, err := createRegistryClient(image.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the digest.
|
||||
digest, err := r.Digest(ctx, image)
|
||||
digest, err := r.Digest(image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func (cmd *removeCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Delete the reference.
|
||||
if err := r.Delete(ctx, image.Path, digest); err != nil {
|
||||
if err := r.Delete(image.Path, digest); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Deleted %s\n", image.String())
|
||||
|
|
|
@ -4,9 +4,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
clitypes "github.com/docker/cli/cli/config/types"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker-ce/components/cli/cli/config"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
@ -32,7 +31,7 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
|
|||
|
||||
dcfg, err := config.Load(config.Dir())
|
||||
if err != nil {
|
||||
return types.AuthConfig{}, fmt.Errorf("loading config file failed: %v", err)
|
||||
return types.AuthConfig{}, fmt.Errorf("Loading config file failed: %v", err)
|
||||
}
|
||||
|
||||
// return error early if there are no auths saved
|
||||
|
@ -50,42 +49,35 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
|
|||
|
||||
authConfigs, err := dcfg.GetAllCredentials()
|
||||
if err != nil {
|
||||
return types.AuthConfig{}, fmt.Errorf("getting credentials failed: %v", err)
|
||||
return types.AuthConfig{}, fmt.Errorf("Getting credentials failed: %v", err)
|
||||
}
|
||||
|
||||
// if they passed a specific registry, return those creds _if_ they exist
|
||||
if registry != "" {
|
||||
// try with the user input
|
||||
if creds, ok := authConfigs[registry]; ok {
|
||||
c := fixAuthConfig(creds, registry)
|
||||
return c, nil
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// remove https:// from user input and try again
|
||||
if strings.HasPrefix(registry, "https://") {
|
||||
registryCleaned := strings.TrimPrefix(registry, "https://")
|
||||
if creds, ok := authConfigs[registryCleaned]; ok {
|
||||
c := fixAuthConfig(creds, registryCleaned)
|
||||
return c, nil
|
||||
if creds, ok := authConfigs[strings.TrimPrefix(registry, "https://")]; ok {
|
||||
return creds, nil
|
||||
}
|
||||
}
|
||||
|
||||
// remove http:// from user input and try again
|
||||
if strings.HasPrefix(registry, "http://") {
|
||||
registryCleaned := strings.TrimPrefix(registry, "http://")
|
||||
if creds, ok := authConfigs[registryCleaned]; ok {
|
||||
c := fixAuthConfig(creds, registryCleaned)
|
||||
return c, nil
|
||||
if creds, ok := authConfigs[strings.TrimPrefix(registry, "http://")]; ok {
|
||||
return creds, nil
|
||||
}
|
||||
}
|
||||
|
||||
// add https:// to user input and try again
|
||||
// see https://github.com/genuinetools/reg/issues/32
|
||||
if !strings.HasPrefix(registry, "https://") && !strings.HasPrefix(registry, "http://") {
|
||||
registryCleaned := "https://" + registry
|
||||
if creds, ok := authConfigs[registryCleaned]; ok {
|
||||
c := fixAuthConfig(creds, registryCleaned)
|
||||
return c, nil
|
||||
if creds, ok := authConfigs["https://"+registry]; ok {
|
||||
return creds, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +93,7 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
|
|||
// found in the auth config.
|
||||
for _, creds := range authConfigs {
|
||||
fmt.Printf("No registry passed. Using registry %q\n", creds.ServerAddress)
|
||||
c := fixAuthConfig(creds, creds.ServerAddress)
|
||||
return c, nil
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// Don't use any authentication.
|
||||
|
@ -111,26 +102,6 @@ func GetAuthConfig(username, password, registry string) (types.AuthConfig, error
|
|||
return types.AuthConfig{}, nil
|
||||
}
|
||||
|
||||
// fixAuthConfig overwrites the AuthConfig's ServerAddress field with the
|
||||
// registry value if ServerAddress is empty. For example, config.Load() will
|
||||
// return AuthConfigs with empty ServerAddresses if the configuration file
|
||||
// contains only an "credsHelper" object.
|
||||
func fixAuthConfig(creds clitypes.AuthConfig, registry string) (c types.AuthConfig) {
|
||||
c.Username = creds.Username
|
||||
c.Password = creds.Password
|
||||
c.Auth = creds.Auth
|
||||
c.Email = creds.Email
|
||||
c.IdentityToken = creds.IdentityToken
|
||||
c.RegistryToken = creds.RegistryToken
|
||||
|
||||
c.ServerAddress = creds.ServerAddress
|
||||
if creds.ServerAddress == "" {
|
||||
c.ServerAddress = registry
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// GetRepoAndRef parses the repo name and reference.
|
||||
func GetRepoAndRef(image string) (repo, ref string, err error) {
|
||||
if image == "" {
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker-ce/components/cli/cli/config"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
@ -35,7 +35,7 @@ func TestGetAuthConfig(t *testing.T) {
|
|||
{
|
||||
name: "invalid config dir",
|
||||
configdir: "testdata/invalid",
|
||||
err: errors.New("loading config file failed: "),
|
||||
err: errors.New("Loading config file failed: "),
|
||||
config: types.AuthConfig{},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -61,7 +61,7 @@ type serverCommand struct {
|
|||
|
||||
func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, cmd.registryServer)
|
||||
r, err := createRegistryClient(cmd.registryServer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
|
|||
|
||||
// Create the initial index.
|
||||
logrus.Info("creating initial static index")
|
||||
if err := rc.repositories(ctx, staticDir); err != nil {
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
return fmt.Errorf("creating index failed: %v", err)
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
|
|||
// Create more indexes every X minutes based off interval.
|
||||
for range ticker.C {
|
||||
logrus.Info("creating timer based static index")
|
||||
if err := rc.repositories(ctx, staticDir); err != nil {
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
logrus.Warnf("creating static index failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
4
tags.go
4
tags.go
|
@ -33,12 +33,12 @@ func (cmd *tagsCommand) Run(ctx context.Context, args []string) error {
|
|||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(ctx, image.Domain)
|
||||
r, err := createRegistryClient(image.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tags, err := r.Tags(ctx, image.Path)
|
||||
tags, err := r.Tags(image.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDAjCCAeqgAwIBAgIQD5bBaNvi21NmTHx8qe8gQjANBgkqhkiG9w0BAQsFADAS
|
||||
MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDcyNTAwNDQwOFoXDTIwMDcyNDAwNDQw
|
||||
OFowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAOSu1L+Cvn/WbcRO71oWVzjvhhkxPjVYUDHwWIq4c354GjapYYsMD7G5
|
||||
mabMpxm7IER9Xa18+RRvFReykzwYmHWKTBisXvmndUd+Dtwo5sumStNyxmz+lAHr
|
||||
fJn/JbQP+7RjY5wL/6oO5u4hTEtQB+QY3gjoHVcx12pBY7MohHzqG3nLTRYdshi9
|
||||
As8NZhKOZ11Rm+mx+YzkUENc0WDmUOyaWKhCtZ7iz6F+g1qoAIny2EzTSpsXdDkl
|
||||
3b+kc1C0WNbFRu9IkIoedOQbxZlZpx+C0eO1RMDnCDJTVOHjKwPoGoyyIrHCS433
|
||||
8AjxircOmJg6yY8J4ieveKwUExVE4bMCAwEAAaNUMFIwDgYDVR0PAQH/BAQDAgKk
|
||||
MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wGgYDVR0RBBMw
|
||||
EYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCsPLe9GuLwxmhR
|
||||
5c2FcdsfxutFfFMPQr1LV0IQx/sOw36Lt6jq1S3i9Opea3Tj8nPontnwPVYJMAIY
|
||||
qdjlOMqXPEcrp3uoCUp6JHk0P1j82xFeT3dgHitN5rGLZH1/4e9zTtYyvR/xivKs
|
||||
yif8BU7lwES6pcFas3OCqN4RRBPjTzvz2P5/zLsi8bHmBdakKMSiSrvmY2BsmKYv
|
||||
fjT7YJzkgpIsoK4qts5agI3UhkrsNLBZOXhZ21nwN0Vts4W1pkJ/8ATJPJRceJ3k
|
||||
61n6UYX6PiqAeAN6L1lUx46eUrRY8daXmIe9Fi9adzqtYOvfinZ56EcnkXDtPGSt
|
||||
+ojNIRcf
|
||||
MIIDAzCCAeugAwIBAgIRAKiO1JljWQroJypQxJGTyQYwDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODA2MDYxNjE4MzFaFw0xOTA2MDYxNjE4
|
||||
MzFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQDIjs9fg/lVbozhiYuu7kswhXGTdLlbvRTpfCX/wNpeVi8AIWRLetsO
|
||||
Q/L/Os3rz+3ejozFREZViqJ5hDODgzMCP93M7lAZhzhrgxwe8+ZYPhj3WHqAc+TK
|
||||
fnW0SNa+gOYPDo98xx1eWQKSLZ8Qj+NjkbBnUu92/zkSKFIvR6RFZwRxrItGZ003
|
||||
OtsSwDn5yVGfcbtJyXMrR1669LvInIRlz9ekumG7cGi8odSKl3xErmGTZYEzozeP
|
||||
MuJLDVM0fh5oOOucsn1sJJXqTNzFXQqvmnXJp62jop9tJcioeyDJvqwWjyVQpwIN
|
||||
ZiqGFFu8LDvba4t+PVwsqrMoUCWEq1yjAgMBAAGjVDBSMA4GA1UdDwEB/wQEAwIC
|
||||
pDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQT
|
||||
MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAbwh3lknBACmn
|
||||
lAm5e/OUpFiGEwV3otRR7tLiQFFPGtQ3hI8kHCjWplDyA9dCiPrH3z84cV/fH5sK
|
||||
4SfG40ucO4r9BVof7dnahl4dejafymxlicD87zUsWRJFIgAlJlpVBkjv9Xd2Fupr
|
||||
PWpbT8fHxeaZ5+Q5vvF7j2qCv+8i3GNgVVFC86HFc0DHRT78a2EW9YkWKdkFUh1W
|
||||
zvuBDwoYv4rVKlhyhrPHMIHGBwdb0meRghqRilSR0qOnLy3fyrKQYpB4WAsBRl+/
|
||||
dFYS9krqSOeqhIZTYkQzI6wlxexZ6vcb7NRhxX33BaFQNmsJnW9oZ2sHkpJ/Ceoe
|
||||
7QaSRcCbtQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA5K7Uv4K+f9ZtxE7vWhZXOO+GGTE+NVhQMfBYirhzfngaNqlh
|
||||
iwwPsbmZpsynGbsgRH1drXz5FG8VF7KTPBiYdYpMGKxe+ad1R34O3Cjmy6ZK03LG
|
||||
bP6UAet8mf8ltA/7tGNjnAv/qg7m7iFMS1AH5BjeCOgdVzHXakFjsyiEfOobectN
|
||||
Fh2yGL0Czw1mEo5nXVGb6bH5jORQQ1zRYOZQ7JpYqEK1nuLPoX6DWqgAifLYTNNK
|
||||
mxd0OSXdv6RzULRY1sVG70iQih505BvFmVmnH4LR47VEwOcIMlNU4eMrA+gajLIi
|
||||
scJLjffwCPGKtw6YmDrJjwniJ694rBQTFUThswIDAQABAoIBACC69TBD4kghxKwo
|
||||
MBHQyMMZZTQN3D1+WlwLbmDMbZtYTUgtjgx8uXJSgi9hczk3kzK6TsIZ9Px7uaUe
|
||||
pfwf+RI5rRKK+Tz6Psrwu+e+4uma73K8JrJK7ZwovDi+UAMplnkHEKaxAPKyF1NV
|
||||
6LmOxtJazMyxjCGCvLY0jbSCxBOsmNpfVULFV61Sx0xbQDniUPTFxrCAbBxRCNAd
|
||||
QJten23Ib4J/CtCOtVOiT3ZZKk4vkhP7+AyDd88iVKQrHUefmTzzDQ8Q2QG4NtSx
|
||||
6HK3+pOlNdAd9r/kbLfCWGmJ8Mt/13TYin+iUeW5iTKHqJMhVweBHsElt+/aMQcZ
|
||||
ePgimAECgYEA+11MSRqRea5h33l+Mk+qTNquwnyvp+cwshEhQIkHZMbonRWX41Fh
|
||||
hPzUE22AGAky9XrjkwA0ljvkcCCKPrmg6a8Y7VyN8z5qD92p4CfuRoHH6ZK4z4ob
|
||||
zxKBFy1wxkoe/vhcqxWBaZGFAbnWtTuCkNG1JUdeLL4oAy1eBJ5tuLMCgYEA6OZz
|
||||
4/BXbNpLunJrYQkEVwO1NE0MBKnRm8NezrmLATSnb4L8jYmdg8iXk2NeQZoidToi
|
||||
6pLSJ9NGyJmKnAHRlQV+4YoNeKd7ZMgy3/evWp9Dp97pRnB1EpUz8S5S46Y6ICVP
|
||||
QzRpc52Y132yRmVVYyBdFB2gwx/kOmZMYSuGswECgYBZjN+Em8aABzQvHWVsHx2Y
|
||||
y7++4hTiSGb8yUWDbE4KBSMR84NtJK0NZ9VWJoigB4b0FZfF4yjY7PVxTOZzekZt
|
||||
ekfzKCoaIn4+sMW4agFldQ73k6HrrlRB7WG4FCQ9QGLSi0DYYoz8Qy+TcdWgM1dM
|
||||
qKlUYpyWbBhtKVh5ZMfKKQKBgCr4ulFIOxk+fdJ84gsZWs+jQ3/O53TE0IPo3ElQ
|
||||
OrGSQYJ1rJuA1KtIC4+KOg3onor6mw6k4FmwxdKlYcm/HChexzZd/nZQkJfbyGdC
|
||||
j/wsfpMusePpQ/CVzuulHG4ccYUU3TcNKJfIcDbyXj5W3BZaFlJr1QmrjLSpw1X6
|
||||
bfQBAoGAbIO/OfsvAyjCo7xtceVW3PbbEmPgrfwLFqzTb40mEIQzxjtSrz5u4U2e
|
||||
/jYm4340ihr8cCCKcPC+KydJ3GqxHWUS7QUVeknJ7ZmwUA7LTVokWZgdWQGvrAlp
|
||||
NtUJP5v4YrnGcPT/PJcYvIRgJHKyEsQUuQHoXP/9zK4/5wicyq4=
|
||||
MIIEpAIBAAKCAQEAyI7PX4P5VW6M4YmLru5LMIVxk3S5W70U6Xwl/8DaXlYvACFk
|
||||
S3rbDkPy/zrN68/t3o6MxURGVYqieYQzg4MzAj/dzO5QGYc4a4McHvPmWD4Y91h6
|
||||
gHPkyn51tEjWvoDmDw6PfMcdXlkCki2fEI/jY5GwZ1Lvdv85EihSL0ekRWcEcayL
|
||||
RmdNNzrbEsA5+clRn3G7SclzK0deuvS7yJyEZc/XpLphu3BovKHUipd8RK5hk2WB
|
||||
M6M3jzLiSw1TNH4eaDjrnLJ9bCSV6kzcxV0Kr5p1yaeto6KfbSXIqHsgyb6sFo8l
|
||||
UKcCDWYqhhRbvCw722uLfj1cLKqzKFAlhKtcowIDAQABAoIBABrnzboqolBrvEql
|
||||
gS++mCeyP0Jg7lz4SM3p8c8VuDXfqf6CfEoD+U84nmjPIsD37BlnVktAlY70Qke7
|
||||
DI4gE7/Bgaf0cJp8IX2K4ULlxYkhC4hjPkvtQExKGtBM1UJJWJO8iFNdAvudRVMG
|
||||
+8flBcRdzySNY8K7CpT9A8mD+u20X1n5yQt4wiBlda2IqEgDmTOJ1pxq99bR+nVu
|
||||
Z1jglgKvVgSuL0JFR3flT2zcRZlRiF3LESfuTy46VXdRGm5wX8rlQaxntsq3BCIs
|
||||
d5+Sy0ajnESZlr4FlHN4h0aNpchntLGKtU5lmyraomRHiD2pxJ3ZM+A5veDVGx9J
|
||||
Y+hJ+gECgYEA0zhPogEmIYVNl1l9LA2Hz2GXvS2hNCswLL/lxUXSrFrbdpl0lXGE
|
||||
d2hgnIFA8CjdMj3P/3VTY71SiDYROEuGbOB87CRpDGdmkpFueIrxbgW92divamVj
|
||||
7gIV9Jdm4hKKALANPDF3JeF7j4M1nNDnRJPQl8KR2x7c7LniVvJ3fAMCgYEA8xPT
|
||||
n0aZhkZSLueqT1v0IzpE2Vs82o0y4LPBBaxA6Hx5IkQ4Z+D3ifyH0baJfUVOOV7N
|
||||
NbfOGzMzZ0+6IelaC5UZCl6fiSxn2/IgByr52tEHJv/wthfqw1Lskxp8ebS3bszI
|
||||
/ZaZkZ4e3TKRC6M7lP2YG0qH626emzWxf8nvyuECgYATLfbVMCOFQbSE/MRH/saJ
|
||||
R0RfEkikExPhzF8R5cA2lF1/THnwpAkySpETRQ1fgWZsjH5ZpQ64bNWUtswjf4Aq
|
||||
XMwbKUc8sBr5Tilo2r0Hj4/ouytajvBfCWNy/ViDSMmtPE9HWvqFvw7YPkLdBX8q
|
||||
k/2J+koCSrAm8s4htQyyfwKBgQCRcuirIsSUqxlcBbVL/TrNpX0zDjwQjnLGL+ks
|
||||
6tCADJMzJN0Xk26re5cNrosAkWroO0jRfuVuMynsBLHcvtPpoFK2eL4/h3myC2SM
|
||||
xXNyMqdz96viWddY/xKeRzf6X19vhkwyKV5E2vee5jYSX580XLYahnNkNfHj77IB
|
||||
RCUfIQKBgQDHtgkK1nRyh3Vv7IpFFGXVOd4HiJ12nWFyXpS1mjzdQ5ARIrEFNz2Z
|
||||
y13bfrfjbEkVWXeCDBzkICWMnRBDtQc1hb6APfodUlakpLyxvFCA5SzygXvrK+MK
|
||||
aDPwY39N3pu0mvfM2Zs2LEXnAIp9VUvWCP+S4GvmHKbp+2tr6PtgkQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
func StartRegistry(dcli *client.Client, config, username, password string) (string, string, error) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", "", errors.New("no caller information")
|
||||
return "", "", errors.New("No caller information")
|
||||
}
|
||||
|
||||
image := "registry:2"
|
||||
|
@ -126,7 +126,7 @@ func startClairDB(dcli *client.Client) (string, error) {
|
|||
func StartClair(dcli *client.Client) (string, string, error) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", "", errors.New("no caller information")
|
||||
return "", "", errors.New("No caller information")
|
||||
}
|
||||
|
||||
// start the database container.
|
||||
|
@ -284,7 +284,7 @@ func imageExists(dcli *client.Client, image string) (bool, error) {
|
|||
func waitForConn(addr, cert, key string) error {
|
||||
tlsCert, err := tls.LoadX509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not load X509 key pair: %v. Make sure the key is not encrypted", err)
|
||||
return fmt.Errorf("Could not load X509 key pair: %v. Make sure the key is not encrypted", err)
|
||||
}
|
||||
|
||||
certPool, err := x509.SystemCertPool()
|
||||
|
|
12
vendor/github.com/Azure/go-ansiterm/README.md
generated
vendored
12
vendor/github.com/Azure/go-ansiterm/README.md
generated
vendored
|
@ -1,12 +0,0 @@
|
|||
# go-ansiterm
|
||||
|
||||
This is a cross platform Ansi Terminal Emulation library. It reads a stream of Ansi characters and produces the appropriate function calls. The results of the function calls are platform dependent.
|
||||
|
||||
For example the parser might receive "ESC, [, A" as a stream of three characters. This is the code for Cursor Up (http://www.vt100.net/docs/vt510-rm/CUU). The parser then calls the cursor up function (CUU()) on an event handler. The event handler determines what platform specific work must be done to cause the cursor to move up one position.
|
||||
|
||||
The parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png). There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go).
|
||||
|
||||
See parser_test.go for examples exercising the state machine and generating appropriate function calls.
|
||||
|
||||
-----
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
1
vendor/github.com/Microsoft/go-winio/.gitignore
generated
vendored
1
vendor/github.com/Microsoft/go-winio/.gitignore
generated
vendored
|
@ -1 +0,0 @@
|
|||
*.exe
|
22
vendor/github.com/Microsoft/go-winio/README.md
generated
vendored
22
vendor/github.com/Microsoft/go-winio/README.md
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
# go-winio
|
||||
|
||||
This repository contains utilities for efficiently performing Win32 IO operations in
|
||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
|
||||
for using named pipes as a net transport.
|
||||
|
||||
This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
|
||||
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
|
||||
newer operating systems. This is similar to the implementation of network sockets in Go's net
|
||||
package.
|
||||
|
||||
Please see the LICENSE file for licensing information.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of
|
||||
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
|
||||
see the [Code of Conduct
|
||||
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
|
||||
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional
|
||||
questions or comments.
|
||||
|
||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
|
||||
for another named pipe implementation.
|
27
vendor/github.com/Microsoft/go-winio/archive/tar/LICENSE
generated
vendored
Normal file
27
vendor/github.com/Microsoft/go-winio/archive/tar/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2012 The Go Authors. 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 Google Inc. 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
|
||||
OWNER 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.
|
18
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
18
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
|
@ -16,7 +16,6 @@ import (
|
|||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||
//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
|
||||
|
||||
type atomicBool int32
|
||||
|
||||
|
@ -80,7 +79,6 @@ type win32File struct {
|
|||
wg sync.WaitGroup
|
||||
wgLock sync.RWMutex
|
||||
closing atomicBool
|
||||
socket bool
|
||||
readDeadline deadlineHandler
|
||||
writeDeadline deadlineHandler
|
||||
}
|
||||
|
@ -111,13 +109,7 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
|
|||
}
|
||||
|
||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||
// If we return the result of makeWin32File directly, it can result in an
|
||||
// interface-wrapped nil, rather than a nil interface value.
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
return makeWin32File(h)
|
||||
}
|
||||
|
||||
// closeHandle closes the resources associated with a Win32 handle
|
||||
|
@ -198,10 +190,6 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
|
|||
if f.closing.isSet() {
|
||||
err = ErrFileClosed
|
||||
}
|
||||
} else if err != nil && f.socket {
|
||||
// err is from Win32. Query the overlapped structure to get the winsock error.
|
||||
var bytes, flags uint32
|
||||
err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
|
||||
}
|
||||
case <-timeout:
|
||||
cancelIoEx(f.handle, &c.o)
|
||||
|
@ -277,10 +265,6 @@ func (f *win32File) Flush() error {
|
|||
return syscall.FlushFileBuffers(f.handle)
|
||||
}
|
||||
|
||||
func (f *win32File) Fd() uintptr {
|
||||
return uintptr(f.handle)
|
||||
}
|
||||
|
||||
func (d *deadlineHandler) set(deadline time.Time) error {
|
||||
d.setLock.Lock()
|
||||
defer d.setLock.Unlock()
|
||||
|
|
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
module github.com/Microsoft/go-winio
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
|
||||
)
|
16
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
16
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
305
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
305
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
|
@ -1,305 +0,0 @@
|
|||
package winio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/go-winio/pkg/guid"
|
||||
)
|
||||
|
||||
//sys bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
|
||||
|
||||
const (
|
||||
afHvSock = 34 // AF_HYPERV
|
||||
|
||||
socketError = ^uintptr(0)
|
||||
)
|
||||
|
||||
// An HvsockAddr is an address for a AF_HYPERV socket.
|
||||
type HvsockAddr struct {
|
||||
VMID guid.GUID
|
||||
ServiceID guid.GUID
|
||||
}
|
||||
|
||||
type rawHvsockAddr struct {
|
||||
Family uint16
|
||||
_ uint16
|
||||
VMID guid.GUID
|
||||
ServiceID guid.GUID
|
||||
}
|
||||
|
||||
// Network returns the address's network name, "hvsock".
|
||||
func (addr *HvsockAddr) Network() string {
|
||||
return "hvsock"
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) String() string {
|
||||
return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
|
||||
}
|
||||
|
||||
// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
|
||||
func VsockServiceID(port uint32) guid.GUID {
|
||||
g, _ := guid.FromString("00000000-facb-11e6-bd58-64006a7986d3")
|
||||
g.Data1 = port
|
||||
return g
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) raw() rawHvsockAddr {
|
||||
return rawHvsockAddr{
|
||||
Family: afHvSock,
|
||||
VMID: addr.VMID,
|
||||
ServiceID: addr.ServiceID,
|
||||
}
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
|
||||
addr.VMID = raw.VMID
|
||||
addr.ServiceID = raw.ServiceID
|
||||
}
|
||||
|
||||
// HvsockListener is a socket listener for the AF_HYPERV address family.
|
||||
type HvsockListener struct {
|
||||
sock *win32File
|
||||
addr HvsockAddr
|
||||
}
|
||||
|
||||
// HvsockConn is a connected socket of the AF_HYPERV address family.
|
||||
type HvsockConn struct {
|
||||
sock *win32File
|
||||
local, remote HvsockAddr
|
||||
}
|
||||
|
||||
func newHvSocket() (*win32File, error) {
|
||||
fd, err := syscall.Socket(afHvSock, syscall.SOCK_STREAM, 1)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("socket", err)
|
||||
}
|
||||
f, err := makeWin32File(fd)
|
||||
if err != nil {
|
||||
syscall.Close(fd)
|
||||
return nil, err
|
||||
}
|
||||
f.socket = true
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// ListenHvsock listens for connections on the specified hvsock address.
|
||||
func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
|
||||
l := &HvsockListener{addr: *addr}
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", err)
|
||||
}
|
||||
sa := addr.raw()
|
||||
err = bind(sock.handle, unsafe.Pointer(&sa), int32(unsafe.Sizeof(sa)))
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("socket", err))
|
||||
}
|
||||
err = syscall.Listen(sock.handle, 16)
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("listen", err))
|
||||
}
|
||||
return &HvsockListener{sock: sock, addr: *addr}, nil
|
||||
}
|
||||
|
||||
func (l *HvsockListener) opErr(op string, err error) error {
|
||||
return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
|
||||
}
|
||||
|
||||
// Addr returns the listener's network address.
|
||||
func (l *HvsockListener) Addr() net.Addr {
|
||||
return &l.addr
|
||||
}
|
||||
|
||||
// Accept waits for the next connection and returns it.
|
||||
func (l *HvsockListener) Accept() (_ net.Conn, err error) {
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", err)
|
||||
}
|
||||
defer func() {
|
||||
if sock != nil {
|
||||
sock.Close()
|
||||
}
|
||||
}()
|
||||
c, err := l.sock.prepareIo()
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", err)
|
||||
}
|
||||
defer l.sock.wg.Done()
|
||||
|
||||
// AcceptEx, per documentation, requires an extra 16 bytes per address.
|
||||
const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
|
||||
var addrbuf [addrlen * 2]byte
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0, addrlen, addrlen, &bytes, &c.o)
|
||||
_, err = l.sock.asyncIo(c, nil, bytes, err)
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
|
||||
}
|
||||
conn := &HvsockConn{
|
||||
sock: sock,
|
||||
}
|
||||
conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
|
||||
conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
|
||||
sock = nil
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Close closes the listener, causing any pending Accept calls to fail.
|
||||
func (l *HvsockListener) Close() error {
|
||||
return l.sock.Close()
|
||||
}
|
||||
|
||||
/* Need to finish ConnectEx handling
|
||||
func DialHvsock(ctx context.Context, addr *HvsockAddr) (*HvsockConn, error) {
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if sock != nil {
|
||||
sock.Close()
|
||||
}
|
||||
}()
|
||||
c, err := sock.prepareIo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer sock.wg.Done()
|
||||
var bytes uint32
|
||||
err = windows.ConnectEx(windows.Handle(sock.handle), sa, nil, 0, &bytes, &c.o)
|
||||
_, err = sock.asyncIo(ctx, c, nil, bytes, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn := &HvsockConn{
|
||||
sock: sock,
|
||||
remote: *addr,
|
||||
}
|
||||
sock = nil
|
||||
return conn, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (conn *HvsockConn) opErr(op string, err error) error {
|
||||
return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) Read(b []byte) (int, error) {
|
||||
c, err := conn.sock.prepareIo()
|
||||
if err != nil {
|
||||
return 0, conn.opErr("read", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var flags, bytes uint32
|
||||
err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
|
||||
n, err := conn.sock.asyncIo(c, &conn.sock.readDeadline, bytes, err)
|
||||
if err != nil {
|
||||
if _, ok := err.(syscall.Errno); ok {
|
||||
err = os.NewSyscallError("wsarecv", err)
|
||||
}
|
||||
return 0, conn.opErr("read", err)
|
||||
} else if n == 0 {
|
||||
err = io.EOF
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) Write(b []byte) (int, error) {
|
||||
t := 0
|
||||
for len(b) != 0 {
|
||||
n, err := conn.write(b)
|
||||
if err != nil {
|
||||
return t + n, err
|
||||
}
|
||||
t += n
|
||||
b = b[n:]
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) write(b []byte) (int, error) {
|
||||
c, err := conn.sock.prepareIo()
|
||||
if err != nil {
|
||||
return 0, conn.opErr("write", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var bytes uint32
|
||||
err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
|
||||
n, err := conn.sock.asyncIo(c, &conn.sock.writeDeadline, bytes, err)
|
||||
if err != nil {
|
||||
if _, ok := err.(syscall.Errno); ok {
|
||||
err = os.NewSyscallError("wsasend", err)
|
||||
}
|
||||
return 0, conn.opErr("write", err)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Close closes the socket connection, failing any pending read or write calls.
|
||||
func (conn *HvsockConn) Close() error {
|
||||
return conn.sock.Close()
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) shutdown(how int) error {
|
||||
err := syscall.Shutdown(conn.sock.handle, syscall.SHUT_RD)
|
||||
if err != nil {
|
||||
return os.NewSyscallError("shutdown", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseRead shuts down the read end of the socket.
|
||||
func (conn *HvsockConn) CloseRead() error {
|
||||
err := conn.shutdown(syscall.SHUT_RD)
|
||||
if err != nil {
|
||||
return conn.opErr("close", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseWrite shuts down the write end of the socket, notifying the other endpoint that
|
||||
// no more data will be written.
|
||||
func (conn *HvsockConn) CloseWrite() error {
|
||||
err := conn.shutdown(syscall.SHUT_WR)
|
||||
if err != nil {
|
||||
return conn.opErr("close", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LocalAddr returns the local address of the connection.
|
||||
func (conn *HvsockConn) LocalAddr() net.Addr {
|
||||
return &conn.local
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote address of the connection.
|
||||
func (conn *HvsockConn) RemoteAddr() net.Addr {
|
||||
return &conn.remote
|
||||
}
|
||||
|
||||
// SetDeadline implements the net.Conn SetDeadline method.
|
||||
func (conn *HvsockConn) SetDeadline(t time.Time) error {
|
||||
conn.SetReadDeadline(t)
|
||||
conn.SetWriteDeadline(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReadDeadline implements the net.Conn SetReadDeadline method.
|
||||
func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
|
||||
return conn.sock.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
|
||||
func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
|
||||
return conn.sock.SetWriteDeadline(t)
|
||||
}
|
205
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
205
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
|
@ -3,13 +3,10 @@
|
|||
package winio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
@ -21,48 +18,6 @@ import (
|
|||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
||||
//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) = ntdll.NtCreateNamedPipeFile
|
||||
//sys rtlNtStatusToDosError(status ntstatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
|
||||
//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) = ntdll.RtlDosPathNameToNtPathName_U
|
||||
//sys rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) = ntdll.RtlDefaultNpAcl
|
||||
|
||||
type ioStatusBlock struct {
|
||||
Status, Information uintptr
|
||||
}
|
||||
|
||||
type objectAttributes struct {
|
||||
Length uintptr
|
||||
RootDirectory uintptr
|
||||
ObjectName *unicodeString
|
||||
Attributes uintptr
|
||||
SecurityDescriptor *securityDescriptor
|
||||
SecurityQoS uintptr
|
||||
}
|
||||
|
||||
type unicodeString struct {
|
||||
Length uint16
|
||||
MaximumLength uint16
|
||||
Buffer uintptr
|
||||
}
|
||||
|
||||
type securityDescriptor struct {
|
||||
Revision byte
|
||||
Sbz1 byte
|
||||
Control uint16
|
||||
Owner uintptr
|
||||
Group uintptr
|
||||
Sacl uintptr
|
||||
Dacl uintptr
|
||||
}
|
||||
|
||||
type ntstatus int32
|
||||
|
||||
func (status ntstatus) Err() error {
|
||||
if status >= 0 {
|
||||
return nil
|
||||
}
|
||||
return rtlNtStatusToDosError(status)
|
||||
}
|
||||
|
||||
const (
|
||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
||||
|
@ -70,20 +25,21 @@ const (
|
|||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
||||
|
||||
cPIPE_ACCESS_DUPLEX = 0x3
|
||||
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
|
||||
cSECURITY_SQOS_PRESENT = 0x100000
|
||||
cSECURITY_ANONYMOUS = 0
|
||||
|
||||
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
|
||||
|
||||
cPIPE_UNLIMITED_INSTANCES = 255
|
||||
|
||||
cNMPWAIT_USE_DEFAULT_WAIT = 0
|
||||
cNMPWAIT_NOWAIT = 1
|
||||
|
||||
cPIPE_TYPE_MESSAGE = 4
|
||||
|
||||
cPIPE_READMODE_MESSAGE = 2
|
||||
|
||||
cFILE_OPEN = 1
|
||||
cFILE_CREATE = 2
|
||||
|
||||
cFILE_PIPE_MESSAGE_TYPE = 1
|
||||
cFILE_PIPE_REJECT_REMOTE_CLIENTS = 2
|
||||
|
||||
cSE_DACL_PRESENT = 4
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -181,30 +137,9 @@ func (s pipeAddress) String() string {
|
|||
return string(s)
|
||||
}
|
||||
|
||||
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
|
||||
func tryDialPipe(ctx context.Context, path *string) (syscall.Handle, error) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return syscall.Handle(0), ctx.Err()
|
||||
default:
|
||||
h, err := createFile(*path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err == nil {
|
||||
return h, nil
|
||||
}
|
||||
if err != cERROR_PIPE_BUSY {
|
||||
return h, &os.PathError{Err: err, Op: "open", Path: *path}
|
||||
}
|
||||
// Wait 10 msec and try again. This is a rather simplistic
|
||||
// view, as we always try each 10 milliseconds.
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
||||
// takes longer than the specified duration. If timeout is nil, then we use
|
||||
// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
|
||||
// a default timeout of 5 seconds. (We do not use WaitNamedPipe.)
|
||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||
var absTimeout time.Time
|
||||
if timeout != nil {
|
||||
|
@ -212,22 +147,23 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
|||
} else {
|
||||
absTimeout = time.Now().Add(time.Second * 2)
|
||||
}
|
||||
ctx, _ := context.WithDeadline(context.Background(), absTimeout)
|
||||
conn, err := DialPipeContext(ctx, path)
|
||||
if err == context.DeadlineExceeded {
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
|
||||
// cancellation or timeout.
|
||||
func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
|
||||
var err error
|
||||
var h syscall.Handle
|
||||
h, err = tryDialPipe(ctx, &path)
|
||||
for {
|
||||
h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err != cERROR_PIPE_BUSY {
|
||||
break
|
||||
}
|
||||
if time.Now().After(absTimeout) {
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
|
||||
// Wait 10 msec and try again. This is a rather simplistic
|
||||
// view, as we always try each 10 milliseconds.
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
|
||||
var flags uint32
|
||||
|
@ -260,85 +196,41 @@ type acceptResponse struct {
|
|||
type win32PipeListener struct {
|
||||
firstHandle syscall.Handle
|
||||
path string
|
||||
securityDescriptor []byte
|
||||
config PipeConfig
|
||||
acceptCh chan (chan acceptResponse)
|
||||
closeCh chan int
|
||||
doneCh chan int
|
||||
}
|
||||
|
||||
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
||||
path16, err := syscall.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
|
||||
var oa objectAttributes
|
||||
oa.Length = unsafe.Sizeof(oa)
|
||||
|
||||
var ntPath unicodeString
|
||||
if err := rtlDosPathNameToNtPathName(&path16[0], &ntPath, 0, 0).Err(); err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
defer localFree(ntPath.Buffer)
|
||||
oa.ObjectName = &ntPath
|
||||
|
||||
// The security descriptor is only needed for the first pipe.
|
||||
func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
||||
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
|
||||
if first {
|
||||
if sd != nil {
|
||||
len := uint32(len(sd))
|
||||
sdb := localAlloc(0, len)
|
||||
defer localFree(sdb)
|
||||
copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
|
||||
oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
|
||||
} else {
|
||||
// Construct the default named pipe security descriptor.
|
||||
var dacl uintptr
|
||||
if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
|
||||
return 0, fmt.Errorf("getting default named pipe ACL: %s", err)
|
||||
}
|
||||
defer localFree(dacl)
|
||||
|
||||
sdb := &securityDescriptor{
|
||||
Revision: 1,
|
||||
Control: cSE_DACL_PRESENT,
|
||||
Dacl: dacl,
|
||||
}
|
||||
oa.SecurityDescriptor = sdb
|
||||
}
|
||||
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
}
|
||||
|
||||
typ := uint32(cFILE_PIPE_REJECT_REMOTE_CLIENTS)
|
||||
var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS
|
||||
if c.MessageMode {
|
||||
typ |= cFILE_PIPE_MESSAGE_TYPE
|
||||
mode |= cPIPE_TYPE_MESSAGE
|
||||
}
|
||||
|
||||
disposition := uint32(cFILE_OPEN)
|
||||
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
|
||||
if first {
|
||||
disposition = cFILE_CREATE
|
||||
// By not asking for read or write access, the named pipe file system
|
||||
// will put this pipe into an initially disconnected state, blocking
|
||||
// client connections until the next call with first == false.
|
||||
access = syscall.SYNCHRONIZE
|
||||
sa := &syscall.SecurityAttributes{}
|
||||
sa.Length = uint32(unsafe.Sizeof(*sa))
|
||||
if securityDescriptor != nil {
|
||||
len := uint32(len(securityDescriptor))
|
||||
sa.SecurityDescriptor = localAlloc(0, len)
|
||||
defer localFree(sa.SecurityDescriptor)
|
||||
copy((*[0xffff]byte)(unsafe.Pointer(sa.SecurityDescriptor))[:], securityDescriptor)
|
||||
}
|
||||
|
||||
timeout := int64(-50 * 10000) // 50ms
|
||||
|
||||
var (
|
||||
h syscall.Handle
|
||||
iosb ioStatusBlock
|
||||
)
|
||||
err = ntCreateNamedPipeFile(&h, access, &oa, &iosb, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, disposition, 0, typ, 0, 0, 0xffffffff, uint32(c.InputBufferSize), uint32(c.OutputBufferSize), &timeout).Err()
|
||||
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
|
||||
runtime.KeepAlive(ntPath)
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
||||
h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
|
||||
h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -449,9 +341,28 @@ func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create a client handle and connect it. This results in the pipe
|
||||
// instance always existing, so that clients see ERROR_PIPE_BUSY
|
||||
// rather than ERROR_FILE_NOT_FOUND. This ties the first instance
|
||||
// up so that no other instances can be used. This would have been
|
||||
// cleaner if the Win32 API matched CreateFile with ConnectNamedPipe
|
||||
// instead of CreateNamedPipe. (Apparently created named pipes are
|
||||
// considered to be in listening state regardless of whether any
|
||||
// active calls to ConnectNamedPipe are outstanding.)
|
||||
h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
// Close the client handle. The server side of the instance will
|
||||
// still be busy, leading to ERROR_PIPE_BUSY instead of
|
||||
// ERROR_NOT_FOUND, as long as we don't close the server handle,
|
||||
// or disconnect the client with DisconnectNamedPipe.
|
||||
syscall.Close(h2)
|
||||
l := &win32PipeListener{
|
||||
firstHandle: h,
|
||||
path: path,
|
||||
securityDescriptor: sd,
|
||||
config: *c,
|
||||
acceptCh: make(chan (chan acceptResponse)),
|
||||
closeCh: make(chan int),
|
||||
|
|
235
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
235
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
|
@ -1,235 +0,0 @@
|
|||
// Package guid provides a GUID type. The backing structure for a GUID is
|
||||
// identical to that used by the golang.org/x/sys/windows GUID type.
|
||||
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
||||
// and the Windows (mixed-endian) encoding. See here for details:
|
||||
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
|
||||
package guid
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Variant specifies which GUID variant (or "type") of the GUID. It determines
|
||||
// how the entirety of the rest of the GUID is interpreted.
|
||||
type Variant uint8
|
||||
|
||||
// The variants specified by RFC 4122.
|
||||
const (
|
||||
// VariantUnknown specifies a GUID variant which does not conform to one of
|
||||
// the variant encodings specified in RFC 4122.
|
||||
VariantUnknown Variant = iota
|
||||
VariantNCS
|
||||
VariantRFC4122
|
||||
VariantMicrosoft
|
||||
VariantFuture
|
||||
)
|
||||
|
||||
// Version specifies how the bits in the GUID were generated. For instance, a
|
||||
// version 4 GUID is randomly generated, and a version 5 is generated from the
|
||||
// hash of an input string.
|
||||
type Version uint8
|
||||
|
||||
var _ = (encoding.TextMarshaler)(GUID{})
|
||||
var _ = (encoding.TextUnmarshaler)(&GUID{})
|
||||
|
||||
// GUID represents a GUID/UUID. It has the same structure as
|
||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||
// that type. It is defined as its own type so that stringification and
|
||||
// marshaling can be supported. The representation matches that used by native
|
||||
// Windows code.
|
||||
type GUID windows.GUID
|
||||
|
||||
// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
|
||||
func NewV4() (GUID, error) {
|
||||
var b [16]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return GUID{}, err
|
||||
}
|
||||
|
||||
g := FromArray(b)
|
||||
g.setVersion(4) // Version 4 means randomly generated.
|
||||
g.setVariant(VariantRFC4122)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
|
||||
// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
|
||||
// and the sample code treats it as a series of bytes, so we do the same here.
|
||||
//
|
||||
// Some implementations, such as those found on Windows, treat the name as a
|
||||
// big-endian UTF16 stream of bytes. If that is desired, the string can be
|
||||
// encoded as such before being passed to this function.
|
||||
func NewV5(namespace GUID, name []byte) (GUID, error) {
|
||||
b := sha1.New()
|
||||
namespaceBytes := namespace.ToArray()
|
||||
b.Write(namespaceBytes[:])
|
||||
b.Write(name)
|
||||
|
||||
a := [16]byte{}
|
||||
copy(a[:], b.Sum(nil))
|
||||
|
||||
g := FromArray(a)
|
||||
g.setVersion(5) // Version 5 means generated from a string.
|
||||
g.setVariant(VariantRFC4122)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func fromArray(b [16]byte, order binary.ByteOrder) GUID {
|
||||
var g GUID
|
||||
g.Data1 = order.Uint32(b[0:4])
|
||||
g.Data2 = order.Uint16(b[4:6])
|
||||
g.Data3 = order.Uint16(b[6:8])
|
||||
copy(g.Data4[:], b[8:16])
|
||||
return g
|
||||
}
|
||||
|
||||
func (g GUID) toArray(order binary.ByteOrder) [16]byte {
|
||||
b := [16]byte{}
|
||||
order.PutUint32(b[0:4], g.Data1)
|
||||
order.PutUint16(b[4:6], g.Data2)
|
||||
order.PutUint16(b[6:8], g.Data3)
|
||||
copy(b[8:16], g.Data4[:])
|
||||
return b
|
||||
}
|
||||
|
||||
// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
|
||||
func FromArray(b [16]byte) GUID {
|
||||
return fromArray(b, binary.BigEndian)
|
||||
}
|
||||
|
||||
// ToArray returns an array of 16 bytes representing the GUID in big-endian
|
||||
// encoding.
|
||||
func (g GUID) ToArray() [16]byte {
|
||||
return g.toArray(binary.BigEndian)
|
||||
}
|
||||
|
||||
// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
|
||||
func FromWindowsArray(b [16]byte) GUID {
|
||||
return fromArray(b, binary.LittleEndian)
|
||||
}
|
||||
|
||||
// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
|
||||
// encoding.
|
||||
func (g GUID) ToWindowsArray() [16]byte {
|
||||
return g.toArray(binary.LittleEndian)
|
||||
}
|
||||
|
||||
func (g GUID) String() string {
|
||||
return fmt.Sprintf(
|
||||
"%08x-%04x-%04x-%04x-%012x",
|
||||
g.Data1,
|
||||
g.Data2,
|
||||
g.Data3,
|
||||
g.Data4[:2],
|
||||
g.Data4[2:])
|
||||
}
|
||||
|
||||
// FromString parses a string containing a GUID and returns the GUID. The only
|
||||
// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||
// format.
|
||||
func FromString(s string) (GUID, error) {
|
||||
if len(s) != 36 {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
|
||||
var g GUID
|
||||
|
||||
data1, err := strconv.ParseUint(s[0:8], 16, 32)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data1 = uint32(data1)
|
||||
|
||||
data2, err := strconv.ParseUint(s[9:13], 16, 16)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data2 = uint16(data2)
|
||||
|
||||
data3, err := strconv.ParseUint(s[14:18], 16, 16)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data3 = uint16(data3)
|
||||
|
||||
for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
|
||||
v, err := strconv.ParseUint(s[x:x+2], 16, 8)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data4[i] = uint8(v)
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *GUID) setVariant(v Variant) {
|
||||
d := g.Data4[0]
|
||||
switch v {
|
||||
case VariantNCS:
|
||||
d = (d & 0x7f)
|
||||
case VariantRFC4122:
|
||||
d = (d & 0x3f) | 0x80
|
||||
case VariantMicrosoft:
|
||||
d = (d & 0x1f) | 0xc0
|
||||
case VariantFuture:
|
||||
d = (d & 0x0f) | 0xe0
|
||||
case VariantUnknown:
|
||||
fallthrough
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid variant: %d", v))
|
||||
}
|
||||
g.Data4[0] = d
|
||||
}
|
||||
|
||||
// Variant returns the GUID variant, as defined in RFC 4122.
|
||||
func (g GUID) Variant() Variant {
|
||||
b := g.Data4[0]
|
||||
if b&0x80 == 0 {
|
||||
return VariantNCS
|
||||
} else if b&0xc0 == 0x80 {
|
||||
return VariantRFC4122
|
||||
} else if b&0xe0 == 0xc0 {
|
||||
return VariantMicrosoft
|
||||
} else if b&0xe0 == 0xe0 {
|
||||
return VariantFuture
|
||||
}
|
||||
return VariantUnknown
|
||||
}
|
||||
|
||||
func (g *GUID) setVersion(v Version) {
|
||||
g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
|
||||
}
|
||||
|
||||
// Version returns the GUID version, as defined in RFC 4122.
|
||||
func (g GUID) Version() Version {
|
||||
return Version((g.Data3 & 0xF000) >> 12)
|
||||
}
|
||||
|
||||
// MarshalText returns the textual representation of the GUID.
|
||||
func (g GUID) MarshalText() ([]byte, error) {
|
||||
return []byte(g.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText takes the textual representation of a GUID, and unmarhals it
|
||||
// into this GUID.
|
||||
func (g *GUID) UnmarshalText(text []byte) error {
|
||||
g2, err := FromString(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*g = g2
|
||||
return nil
|
||||
}
|
2
vendor/github.com/Microsoft/go-winio/syscall.go
generated
vendored
2
vendor/github.com/Microsoft/go-winio/syscall.go
generated
vendored
|
@ -1,3 +1,3 @@
|
|||
package winio
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go
|
||||
|
|
88
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
88
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
// Code generated by 'go generate'; DO NOT EDIT.
|
||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package winio
|
||||
|
||||
|
@ -38,25 +38,19 @@ func errnoErr(e syscall.Errno) error {
|
|||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||
|
@ -75,7 +69,6 @@ var (
|
|||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||
procbind = modws2_32.NewProc("bind")
|
||||
)
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
|
@ -127,24 +120,6 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro
|
|||
return
|
||||
}
|
||||
|
||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
|
@ -201,6 +176,27 @@ func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityA
|
|||
return
|
||||
}
|
||||
|
||||
func waitNamedPipe(name string, timeout uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _waitNamedPipe(_p0, timeout)
|
||||
}
|
||||
|
||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||
if r1 == 0 {
|
||||
|
@ -231,32 +227,6 @@ func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
|||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||
|
@ -548,15 +518,3 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||
if r1 == socketError {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
51
vendor/github.com/Microsoft/hcsshim/osversion/osversion.go
generated
vendored
51
vendor/github.com/Microsoft/hcsshim/osversion/osversion.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
package osversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// OSVersion is a wrapper for Windows version information
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
|
||||
type OSVersion struct {
|
||||
Version uint32
|
||||
MajorVersion uint8
|
||||
MinorVersion uint8
|
||||
Build uint16
|
||||
}
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
|
||||
type osVersionInfoEx struct {
|
||||
OSVersionInfoSize uint32
|
||||
MajorVersion uint32
|
||||
MinorVersion uint32
|
||||
BuildNumber uint32
|
||||
PlatformID uint32
|
||||
CSDVersion [128]uint16
|
||||
ServicePackMajor uint16
|
||||
ServicePackMinor uint16
|
||||
SuiteMask uint16
|
||||
ProductType byte
|
||||
Reserve byte
|
||||
}
|
||||
|
||||
// Get gets the operating system version on Windows.
|
||||
// The calling application must be manifested to get the correct version information.
|
||||
func Get() OSVersion {
|
||||
var err error
|
||||
osv := OSVersion{}
|
||||
osv.Version, err = windows.GetVersion()
|
||||
if err != nil {
|
||||
// GetVersion never fails.
|
||||
panic(err)
|
||||
}
|
||||
osv.MajorVersion = uint8(osv.Version & 0xFF)
|
||||
osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF)
|
||||
osv.Build = uint16(osv.Version >> 16)
|
||||
return osv
|
||||
}
|
||||
|
||||
func (osv OSVersion) ToString() string {
|
||||
return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build)
|
||||
}
|
10
vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
generated
vendored
10
vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
package osversion
|
||||
|
||||
const (
|
||||
|
||||
// RS2 was a client-only release in case you're asking why it's not in the list.
|
||||
RS1 = 14393
|
||||
RS3 = 16299
|
||||
RS4 = 17134
|
||||
RS5 = 17763
|
||||
)
|
26
vendor/github.com/Nvveen/Gotty/LICENSE
generated
vendored
Normal file
26
vendor/github.com/Nvveen/Gotty/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2012, Neal van Veen (nealvanveen@gmail.com)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. 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.
|
||||
|
||||
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 OWNER 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.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
514
vendor/github.com/Nvveen/Gotty/attributes.go
generated
vendored
Normal file
514
vendor/github.com/Nvveen/Gotty/attributes.go
generated
vendored
Normal file
|
@ -0,0 +1,514 @@
|
|||
// Copyright 2012 Neal van Veen. All rights reserved.
|
||||
// Usage of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package gotty
|
||||
|
||||
// Boolean capabilities
|
||||
var BoolAttr = [...]string{
|
||||
"auto_left_margin", "bw",
|
||||
"auto_right_margin", "am",
|
||||
"no_esc_ctlc", "xsb",
|
||||
"ceol_standout_glitch", "xhp",
|
||||
"eat_newline_glitch", "xenl",
|
||||
"erase_overstrike", "eo",
|
||||
"generic_type", "gn",
|
||||
"hard_copy", "hc",
|
||||
"has_meta_key", "km",
|
||||
"has_status_line", "hs",
|
||||
"insert_null_glitch", "in",
|
||||
"memory_above", "da",
|
||||
"memory_below", "db",
|
||||
"move_insert_mode", "mir",
|
||||
"move_standout_mode", "msgr",
|
||||
"over_strike", "os",
|
||||
"status_line_esc_ok", "eslok",
|
||||
"dest_tabs_magic_smso", "xt",
|
||||
"tilde_glitch", "hz",
|
||||
"transparent_underline", "ul",
|
||||
"xon_xoff", "nxon",
|
||||
"needs_xon_xoff", "nxon",
|
||||
"prtr_silent", "mc5i",
|
||||
"hard_cursor", "chts",
|
||||
"non_rev_rmcup", "nrrmc",
|
||||
"no_pad_char", "npc",
|
||||
"non_dest_scroll_region", "ndscr",
|
||||
"can_change", "ccc",
|
||||
"back_color_erase", "bce",
|
||||
"hue_lightness_saturation", "hls",
|
||||
"col_addr_glitch", "xhpa",
|
||||
"cr_cancels_micro_mode", "crxm",
|
||||
"has_print_wheel", "daisy",
|
||||
"row_addr_glitch", "xvpa",
|
||||
"semi_auto_right_margin", "sam",
|
||||
"cpi_changes_res", "cpix",
|
||||
"lpi_changes_res", "lpix",
|
||||
"backspaces_with_bs", "",
|
||||
"crt_no_scrolling", "",
|
||||
"no_correctly_working_cr", "",
|
||||
"gnu_has_meta_key", "",
|
||||
"linefeed_is_newline", "",
|
||||
"has_hardware_tabs", "",
|
||||
"return_does_clr_eol", "",
|
||||
}
|
||||
|
||||
// Numerical capabilities
|
||||
var NumAttr = [...]string{
|
||||
"columns", "cols",
|
||||
"init_tabs", "it",
|
||||
"lines", "lines",
|
||||
"lines_of_memory", "lm",
|
||||
"magic_cookie_glitch", "xmc",
|
||||
"padding_baud_rate", "pb",
|
||||
"virtual_terminal", "vt",
|
||||
"width_status_line", "wsl",
|
||||
"num_labels", "nlab",
|
||||
"label_height", "lh",
|
||||
"label_width", "lw",
|
||||
"max_attributes", "ma",
|
||||
"maximum_windows", "wnum",
|
||||
"max_colors", "colors",
|
||||
"max_pairs", "pairs",
|
||||
"no_color_video", "ncv",
|
||||
"buffer_capacity", "bufsz",
|
||||
"dot_vert_spacing", "spinv",
|
||||
"dot_horz_spacing", "spinh",
|
||||
"max_micro_address", "maddr",
|
||||
"max_micro_jump", "mjump",
|
||||
"micro_col_size", "mcs",
|
||||
"micro_line_size", "mls",
|
||||
"number_of_pins", "npins",
|
||||
"output_res_char", "orc",
|
||||
"output_res_line", "orl",
|
||||
"output_res_horz_inch", "orhi",
|
||||
"output_res_vert_inch", "orvi",
|
||||
"print_rate", "cps",
|
||||
"wide_char_size", "widcs",
|
||||
"buttons", "btns",
|
||||
"bit_image_entwining", "bitwin",
|
||||
"bit_image_type", "bitype",
|
||||
"magic_cookie_glitch_ul", "",
|
||||
"carriage_return_delay", "",
|
||||
"new_line_delay", "",
|
||||
"backspace_delay", "",
|
||||
"horizontal_tab_delay", "",
|
||||
"number_of_function_keys", "",
|
||||
}
|
||||
|
||||
// String capabilities
|
||||
var StrAttr = [...]string{
|
||||
"back_tab", "cbt",
|
||||
"bell", "bel",
|
||||
"carriage_return", "cr",
|
||||
"change_scroll_region", "csr",
|
||||
"clear_all_tabs", "tbc",
|
||||
"clear_screen", "clear",
|
||||
"clr_eol", "el",
|
||||
"clr_eos", "ed",
|
||||
"column_address", "hpa",
|
||||
"command_character", "cmdch",
|
||||
"cursor_address", "cup",
|
||||
"cursor_down", "cud1",
|
||||
"cursor_home", "home",
|
||||
"cursor_invisible", "civis",
|
||||
"cursor_left", "cub1",
|
||||
"cursor_mem_address", "mrcup",
|
||||
"cursor_normal", "cnorm",
|
||||
"cursor_right", "cuf1",
|
||||
"cursor_to_ll", "ll",
|
||||
"cursor_up", "cuu1",
|
||||
"cursor_visible", "cvvis",
|
||||
"delete_character", "dch1",
|
||||
"delete_line", "dl1",
|
||||
"dis_status_line", "dsl",
|
||||
"down_half_line", "hd",
|
||||
"enter_alt_charset_mode", "smacs",
|
||||
"enter_blink_mode", "blink",
|
||||
"enter_bold_mode", "bold",
|
||||
"enter_ca_mode", "smcup",
|
||||
"enter_delete_mode", "smdc",
|
||||
"enter_dim_mode", "dim",
|
||||
"enter_insert_mode", "smir",
|
||||
"enter_secure_mode", "invis",
|
||||
"enter_protected_mode", "prot",
|
||||
"enter_reverse_mode", "rev",
|
||||
"enter_standout_mode", "smso",
|
||||
"enter_underline_mode", "smul",
|
||||
"erase_chars", "ech",
|
||||
"exit_alt_charset_mode", "rmacs",
|
||||
"exit_attribute_mode", "sgr0",
|
||||
"exit_ca_mode", "rmcup",
|
||||
"exit_delete_mode", "rmdc",
|
||||
"exit_insert_mode", "rmir",
|
||||
"exit_standout_mode", "rmso",
|
||||
"exit_underline_mode", "rmul",
|
||||
"flash_screen", "flash",
|
||||
"form_feed", "ff",
|
||||
"from_status_line", "fsl",
|
||||
"init_1string", "is1",
|
||||
"init_2string", "is2",
|
||||
"init_3string", "is3",
|
||||
"init_file", "if",
|
||||
"insert_character", "ich1",
|
||||
"insert_line", "il1",
|
||||
"insert_padding", "ip",
|
||||
"key_backspace", "kbs",
|
||||
"key_catab", "ktbc",
|
||||
"key_clear", "kclr",
|
||||
"key_ctab", "kctab",
|
||||
"key_dc", "kdch1",
|
||||
"key_dl", "kdl1",
|
||||
"key_down", "kcud1",
|
||||
"key_eic", "krmir",
|
||||
"key_eol", "kel",
|
||||
"key_eos", "ked",
|
||||
"key_f0", "kf0",
|
||||
"key_f1", "kf1",
|
||||
"key_f10", "kf10",
|
||||
"key_f2", "kf2",
|
||||
"key_f3", "kf3",
|
||||
"key_f4", "kf4",
|
||||
"key_f5", "kf5",
|
||||
"key_f6", "kf6",
|
||||
"key_f7", "kf7",
|
||||
"key_f8", "kf8",
|
||||
"key_f9", "kf9",
|
||||
"key_home", "khome",
|
||||
"key_ic", "kich1",
|
||||
"key_il", "kil1",
|
||||
"key_left", "kcub1",
|
||||
"key_ll", "kll",
|
||||
"key_npage", "knp",
|
||||
"key_ppage", "kpp",
|
||||
"key_right", "kcuf1",
|
||||
"key_sf", "kind",
|
||||
"key_sr", "kri",
|
||||
"key_stab", "khts",
|
||||
"key_up", "kcuu1",
|
||||
"keypad_local", "rmkx",
|
||||
"keypad_xmit", "smkx",
|
||||
"lab_f0", "lf0",
|
||||
"lab_f1", "lf1",
|
||||
"lab_f10", "lf10",
|
||||
"lab_f2", "lf2",
|
||||
"lab_f3", "lf3",
|
||||
"lab_f4", "lf4",
|
||||
"lab_f5", "lf5",
|
||||
"lab_f6", "lf6",
|
||||
"lab_f7", "lf7",
|
||||
"lab_f8", "lf8",
|
||||
"lab_f9", "lf9",
|
||||
"meta_off", "rmm",
|
||||
"meta_on", "smm",
|
||||
"newline", "_glitch",
|
||||
"pad_char", "npc",
|
||||
"parm_dch", "dch",
|
||||
"parm_delete_line", "dl",
|
||||
"parm_down_cursor", "cud",
|
||||
"parm_ich", "ich",
|
||||
"parm_index", "indn",
|
||||
"parm_insert_line", "il",
|
||||
"parm_left_cursor", "cub",
|
||||
"parm_right_cursor", "cuf",
|
||||
"parm_rindex", "rin",
|
||||
"parm_up_cursor", "cuu",
|
||||
"pkey_key", "pfkey",
|
||||
"pkey_local", "pfloc",
|
||||
"pkey_xmit", "pfx",
|
||||
"print_screen", "mc0",
|
||||
"prtr_off", "mc4",
|
||||
"prtr_on", "mc5",
|
||||
"repeat_char", "rep",
|
||||
"reset_1string", "rs1",
|
||||
"reset_2string", "rs2",
|
||||
"reset_3string", "rs3",
|
||||
"reset_file", "rf",
|
||||
"restore_cursor", "rc",
|
||||
"row_address", "mvpa",
|
||||
"save_cursor", "row_address",
|
||||
"scroll_forward", "ind",
|
||||
"scroll_reverse", "ri",
|
||||
"set_attributes", "sgr",
|
||||
"set_tab", "hts",
|
||||
"set_window", "wind",
|
||||
"tab", "s_magic_smso",
|
||||
"to_status_line", "tsl",
|
||||
"underline_char", "uc",
|
||||
"up_half_line", "hu",
|
||||
"init_prog", "iprog",
|
||||
"key_a1", "ka1",
|
||||
"key_a3", "ka3",
|
||||
"key_b2", "kb2",
|
||||
"key_c1", "kc1",
|
||||
"key_c3", "kc3",
|
||||
"prtr_non", "mc5p",
|
||||
"char_padding", "rmp",
|
||||
"acs_chars", "acsc",
|
||||
"plab_norm", "pln",
|
||||
"key_btab", "kcbt",
|
||||
"enter_xon_mode", "smxon",
|
||||
"exit_xon_mode", "rmxon",
|
||||
"enter_am_mode", "smam",
|
||||
"exit_am_mode", "rmam",
|
||||
"xon_character", "xonc",
|
||||
"xoff_character", "xoffc",
|
||||
"ena_acs", "enacs",
|
||||
"label_on", "smln",
|
||||
"label_off", "rmln",
|
||||
"key_beg", "kbeg",
|
||||
"key_cancel", "kcan",
|
||||
"key_close", "kclo",
|
||||
"key_command", "kcmd",
|
||||
"key_copy", "kcpy",
|
||||
"key_create", "kcrt",
|
||||
"key_end", "kend",
|
||||
"key_enter", "kent",
|
||||
"key_exit", "kext",
|
||||
"key_find", "kfnd",
|
||||
"key_help", "khlp",
|
||||
"key_mark", "kmrk",
|
||||
"key_message", "kmsg",
|
||||
"key_move", "kmov",
|
||||
"key_next", "knxt",
|
||||
"key_open", "kopn",
|
||||
"key_options", "kopt",
|
||||
"key_previous", "kprv",
|
||||
"key_print", "kprt",
|
||||
"key_redo", "krdo",
|
||||
"key_reference", "kref",
|
||||
"key_refresh", "krfr",
|
||||
"key_replace", "krpl",
|
||||
"key_restart", "krst",
|
||||
"key_resume", "kres",
|
||||
"key_save", "ksav",
|
||||
"key_suspend", "kspd",
|
||||
"key_undo", "kund",
|
||||
"key_sbeg", "kBEG",
|
||||
"key_scancel", "kCAN",
|
||||
"key_scommand", "kCMD",
|
||||
"key_scopy", "kCPY",
|
||||
"key_screate", "kCRT",
|
||||
"key_sdc", "kDC",
|
||||
"key_sdl", "kDL",
|
||||
"key_select", "kslt",
|
||||
"key_send", "kEND",
|
||||
"key_seol", "kEOL",
|
||||
"key_sexit", "kEXT",
|
||||
"key_sfind", "kFND",
|
||||
"key_shelp", "kHLP",
|
||||
"key_shome", "kHOM",
|
||||
"key_sic", "kIC",
|
||||
"key_sleft", "kLFT",
|
||||
"key_smessage", "kMSG",
|
||||
"key_smove", "kMOV",
|
||||
"key_snext", "kNXT",
|
||||
"key_soptions", "kOPT",
|
||||
"key_sprevious", "kPRV",
|
||||
"key_sprint", "kPRT",
|
||||
"key_sredo", "kRDO",
|
||||
"key_sreplace", "kRPL",
|
||||
"key_sright", "kRIT",
|
||||
"key_srsume", "kRES",
|
||||
"key_ssave", "kSAV",
|
||||
"key_ssuspend", "kSPD",
|
||||
"key_sundo", "kUND",
|
||||
"req_for_input", "rfi",
|
||||
"key_f11", "kf11",
|
||||
"key_f12", "kf12",
|
||||
"key_f13", "kf13",
|
||||
"key_f14", "kf14",
|
||||
"key_f15", "kf15",
|
||||
"key_f16", "kf16",
|
||||
"key_f17", "kf17",
|
||||
"key_f18", "kf18",
|
||||
"key_f19", "kf19",
|
||||
"key_f20", "kf20",
|
||||
"key_f21", "kf21",
|
||||
"key_f22", "kf22",
|
||||
"key_f23", "kf23",
|
||||
"key_f24", "kf24",
|
||||
"key_f25", "kf25",
|
||||
"key_f26", "kf26",
|
||||
"key_f27", "kf27",
|
||||
"key_f28", "kf28",
|
||||
"key_f29", "kf29",
|
||||
"key_f30", "kf30",
|
||||
"key_f31", "kf31",
|
||||
"key_f32", "kf32",
|
||||
"key_f33", "kf33",
|
||||
"key_f34", "kf34",
|
||||
"key_f35", "kf35",
|
||||
"key_f36", "kf36",
|
||||
"key_f37", "kf37",
|
||||
"key_f38", "kf38",
|
||||
"key_f39", "kf39",
|
||||
"key_f40", "kf40",
|
||||
"key_f41", "kf41",
|
||||
"key_f42", "kf42",
|
||||
"key_f43", "kf43",
|
||||
"key_f44", "kf44",
|
||||
"key_f45", "kf45",
|
||||
"key_f46", "kf46",
|
||||
"key_f47", "kf47",
|
||||
"key_f48", "kf48",
|
||||
"key_f49", "kf49",
|
||||
"key_f50", "kf50",
|
||||
"key_f51", "kf51",
|
||||
"key_f52", "kf52",
|
||||
"key_f53", "kf53",
|
||||
"key_f54", "kf54",
|
||||
"key_f55", "kf55",
|
||||
"key_f56", "kf56",
|
||||
"key_f57", "kf57",
|
||||
"key_f58", "kf58",
|
||||
"key_f59", "kf59",
|
||||
"key_f60", "kf60",
|
||||
"key_f61", "kf61",
|
||||
"key_f62", "kf62",
|
||||
"key_f63", "kf63",
|
||||
"clr_bol", "el1",
|
||||
"clear_margins", "mgc",
|
||||
"set_left_margin", "smgl",
|
||||
"set_right_margin", "smgr",
|
||||
"label_format", "fln",
|
||||
"set_clock", "sclk",
|
||||
"display_clock", "dclk",
|
||||
"remove_clock", "rmclk",
|
||||
"create_window", "cwin",
|
||||
"goto_window", "wingo",
|
||||
"hangup", "hup",
|
||||
"dial_phone", "dial",
|
||||
"quick_dial", "qdial",
|
||||
"tone", "tone",
|
||||
"pulse", "pulse",
|
||||
"flash_hook", "hook",
|
||||
"fixed_pause", "pause",
|
||||
"wait_tone", "wait",
|
||||
"user0", "u0",
|
||||
"user1", "u1",
|
||||
"user2", "u2",
|
||||
"user3", "u3",
|
||||
"user4", "u4",
|
||||
"user5", "u5",
|
||||
"user6", "u6",
|
||||
"user7", "u7",
|
||||
"user8", "u8",
|
||||
"user9", "u9",
|
||||
"orig_pair", "op",
|
||||
"orig_colors", "oc",
|
||||
"initialize_color", "initc",
|
||||
"initialize_pair", "initp",
|
||||
"set_color_pair", "scp",
|
||||
"set_foreground", "setf",
|
||||
"set_background", "setb",
|
||||
"change_char_pitch", "cpi",
|
||||
"change_line_pitch", "lpi",
|
||||
"change_res_horz", "chr",
|
||||
"change_res_vert", "cvr",
|
||||
"define_char", "defc",
|
||||
"enter_doublewide_mode", "swidm",
|
||||
"enter_draft_quality", "sdrfq",
|
||||
"enter_italics_mode", "sitm",
|
||||
"enter_leftward_mode", "slm",
|
||||
"enter_micro_mode", "smicm",
|
||||
"enter_near_letter_quality", "snlq",
|
||||
"enter_normal_quality", "snrmq",
|
||||
"enter_shadow_mode", "sshm",
|
||||
"enter_subscript_mode", "ssubm",
|
||||
"enter_superscript_mode", "ssupm",
|
||||
"enter_upward_mode", "sum",
|
||||
"exit_doublewide_mode", "rwidm",
|
||||
"exit_italics_mode", "ritm",
|
||||
"exit_leftward_mode", "rlm",
|
||||
"exit_micro_mode", "rmicm",
|
||||
"exit_shadow_mode", "rshm",
|
||||
"exit_subscript_mode", "rsubm",
|
||||
"exit_superscript_mode", "rsupm",
|
||||
"exit_upward_mode", "rum",
|
||||
"micro_column_address", "mhpa",
|
||||
"micro_down", "mcud1",
|
||||
"micro_left", "mcub1",
|
||||
"micro_right", "mcuf1",
|
||||
"micro_row_address", "mvpa",
|
||||
"micro_up", "mcuu1",
|
||||
"order_of_pins", "porder",
|
||||
"parm_down_micro", "mcud",
|
||||
"parm_left_micro", "mcub",
|
||||
"parm_right_micro", "mcuf",
|
||||
"parm_up_micro", "mcuu",
|
||||
"select_char_set", "scs",
|
||||
"set_bottom_margin", "smgb",
|
||||
"set_bottom_margin_parm", "smgbp",
|
||||
"set_left_margin_parm", "smglp",
|
||||
"set_right_margin_parm", "smgrp",
|
||||
"set_top_margin", "smgt",
|
||||
"set_top_margin_parm", "smgtp",
|
||||
"start_bit_image", "sbim",
|
||||
"start_char_set_def", "scsd",
|
||||
"stop_bit_image", "rbim",
|
||||
"stop_char_set_def", "rcsd",
|
||||
"subscript_characters", "subcs",
|
||||
"superscript_characters", "supcs",
|
||||
"these_cause_cr", "docr",
|
||||
"zero_motion", "zerom",
|
||||
"char_set_names", "csnm",
|
||||
"key_mouse", "kmous",
|
||||
"mouse_info", "minfo",
|
||||
"req_mouse_pos", "reqmp",
|
||||
"get_mouse", "getm",
|
||||
"set_a_foreground", "setaf",
|
||||
"set_a_background", "setab",
|
||||
"pkey_plab", "pfxl",
|
||||
"device_type", "devt",
|
||||
"code_set_init", "csin",
|
||||
"set0_des_seq", "s0ds",
|
||||
"set1_des_seq", "s1ds",
|
||||
"set2_des_seq", "s2ds",
|
||||
"set3_des_seq", "s3ds",
|
||||
"set_lr_margin", "smglr",
|
||||
"set_tb_margin", "smgtb",
|
||||
"bit_image_repeat", "birep",
|
||||
"bit_image_newline", "binel",
|
||||
"bit_image_carriage_return", "bicr",
|
||||
"color_names", "colornm",
|
||||
"define_bit_image_region", "defbi",
|
||||
"end_bit_image_region", "endbi",
|
||||
"set_color_band", "setcolor",
|
||||
"set_page_length", "slines",
|
||||
"display_pc_char", "dispc",
|
||||
"enter_pc_charset_mode", "smpch",
|
||||
"exit_pc_charset_mode", "rmpch",
|
||||
"enter_scancode_mode", "smsc",
|
||||
"exit_scancode_mode", "rmsc",
|
||||
"pc_term_options", "pctrm",
|
||||
"scancode_escape", "scesc",
|
||||
"alt_scancode_esc", "scesa",
|
||||
"enter_horizontal_hl_mode", "ehhlm",
|
||||
"enter_left_hl_mode", "elhlm",
|
||||
"enter_low_hl_mode", "elohlm",
|
||||
"enter_right_hl_mode", "erhlm",
|
||||
"enter_top_hl_mode", "ethlm",
|
||||
"enter_vertical_hl_mode", "evhlm",
|
||||
"set_a_attributes", "sgr1",
|
||||
"set_pglen_inch", "slength",
|
||||
"termcap_init2", "",
|
||||
"termcap_reset", "",
|
||||
"linefeed_if_not_lf", "",
|
||||
"backspace_if_not_bs", "",
|
||||
"other_non_function_keys", "",
|
||||
"arrow_key_map", "",
|
||||
"acs_ulcorner", "",
|
||||
"acs_llcorner", "",
|
||||
"acs_urcorner", "",
|
||||
"acs_lrcorner", "",
|
||||
"acs_ltee", "",
|
||||
"acs_rtee", "",
|
||||
"acs_btee", "",
|
||||
"acs_ttee", "",
|
||||
"acs_hline", "",
|
||||
"acs_vline", "",
|
||||
"acs_plus", "",
|
||||
"memory_lock", "",
|
||||
"memory_unlock", "",
|
||||
"box_chars_1", "",
|
||||
}
|
238
vendor/github.com/Nvveen/Gotty/gotty.go
generated
vendored
Normal file
238
vendor/github.com/Nvveen/Gotty/gotty.go
generated
vendored
Normal file
|
@ -0,0 +1,238 @@
|
|||
// Copyright 2012 Neal van Veen. All rights reserved.
|
||||
// Usage of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Gotty is a Go-package for reading and parsing the terminfo database
|
||||
package gotty
|
||||
|
||||
// TODO add more concurrency to name lookup, look for more opportunities.
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Open a terminfo file by the name given and construct a TermInfo object.
|
||||
// If something went wrong reading the terminfo database file, an error is
|
||||
// returned.
|
||||
func OpenTermInfo(termName string) (*TermInfo, error) {
|
||||
var term *TermInfo
|
||||
var err error
|
||||
// Find the environment variables
|
||||
termloc := os.Getenv("TERMINFO")
|
||||
if len(termloc) == 0 {
|
||||
// Search like ncurses
|
||||
locations := []string{os.Getenv("HOME") + "/.terminfo/", "/etc/terminfo/",
|
||||
"/lib/terminfo/", "/usr/share/terminfo/"}
|
||||
var path string
|
||||
for _, str := range locations {
|
||||
// Construct path
|
||||
path = str + string(termName[0]) + "/" + termName
|
||||
// Check if path can be opened
|
||||
file, _ := os.Open(path)
|
||||
if file != nil {
|
||||
// Path can open, fall out and use current path
|
||||
file.Close()
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(path) > 0 {
|
||||
term, err = readTermInfo(path)
|
||||
} else {
|
||||
err = errors.New(fmt.Sprintf("No terminfo file(-location) found"))
|
||||
}
|
||||
}
|
||||
return term, err
|
||||
}
|
||||
|
||||
// Open a terminfo file from the environment variable containing the current
|
||||
// terminal name and construct a TermInfo object. If something went wrong
|
||||
// reading the terminfo database file, an error is returned.
|
||||
func OpenTermInfoEnv() (*TermInfo, error) {
|
||||
termenv := os.Getenv("TERM")
|
||||
return OpenTermInfo(termenv)
|
||||
}
|
||||
|
||||
// Return an attribute by the name attr provided. If none can be found,
|
||||
// an error is returned.
|
||||
func (term *TermInfo) GetAttribute(attr string) (stacker, error) {
|
||||
// Channel to store the main value in.
|
||||
var value stacker
|
||||
// Add a blocking WaitGroup
|
||||
var block sync.WaitGroup
|
||||
// Keep track of variable being written.
|
||||
written := false
|
||||
// Function to put into goroutine.
|
||||
f := func(ats interface{}) {
|
||||
var ok bool
|
||||
var v stacker
|
||||
// Switch on type of map to use and assign value to it.
|
||||
switch reflect.TypeOf(ats).Elem().Kind() {
|
||||
case reflect.Bool:
|
||||
v, ok = ats.(map[string]bool)[attr]
|
||||
case reflect.Int16:
|
||||
v, ok = ats.(map[string]int16)[attr]
|
||||
case reflect.String:
|
||||
v, ok = ats.(map[string]string)[attr]
|
||||
}
|
||||
// If ok, a value is found, so we can write.
|
||||
if ok {
|
||||
value = v
|
||||
written = true
|
||||
}
|
||||
// Goroutine is done
|
||||
block.Done()
|
||||
}
|
||||
block.Add(3)
|
||||
// Go for all 3 attribute lists.
|
||||
go f(term.boolAttributes)
|
||||
go f(term.numAttributes)
|
||||
go f(term.strAttributes)
|
||||
// Wait until every goroutine is done.
|
||||
block.Wait()
|
||||
// If a value has been written, return it.
|
||||
if written {
|
||||
return value, nil
|
||||
}
|
||||
// Otherwise, error.
|
||||
return nil, fmt.Errorf("Erorr finding attribute")
|
||||
}
|
||||
|
||||
// Return an attribute by the name attr provided. If none can be found,
|
||||
// an error is returned. A name is first converted to its termcap value.
|
||||
func (term *TermInfo) GetAttributeName(name string) (stacker, error) {
|
||||
tc := GetTermcapName(name)
|
||||
return term.GetAttribute(tc)
|
||||
}
|
||||
|
||||
// A utility function that finds and returns the termcap equivalent of a
|
||||
// variable name.
|
||||
func GetTermcapName(name string) string {
|
||||
// Termcap name
|
||||
var tc string
|
||||
// Blocking group
|
||||
var wait sync.WaitGroup
|
||||
// Function to put into a goroutine
|
||||
f := func(attrs []string) {
|
||||
// Find the string corresponding to the name
|
||||
for i, s := range attrs {
|
||||
if s == name {
|
||||
tc = attrs[i+1]
|
||||
}
|
||||
}
|
||||
// Goroutine is finished
|
||||
wait.Done()
|
||||
}
|
||||
wait.Add(3)
|
||||
// Go for all 3 attribute lists
|
||||
go f(BoolAttr[:])
|
||||
go f(NumAttr[:])
|
||||
go f(StrAttr[:])
|
||||
// Wait until every goroutine is done
|
||||
wait.Wait()
|
||||
// Return the termcap name
|
||||
return tc
|
||||
}
|
||||
|
||||
// This function takes a path to a terminfo file and reads it in binary
|
||||
// form to construct the actual TermInfo file.
|
||||
func readTermInfo(path string) (*TermInfo, error) {
|
||||
// Open the terminfo file
|
||||
file, err := os.Open(path)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// magic, nameSize, boolSize, nrSNum, nrOffsetsStr, strSize
|
||||
// Header is composed of the magic 0432 octal number, size of the name
|
||||
// section, size of the boolean section, the amount of number values,
|
||||
// the number of offsets of strings, and the size of the string section.
|
||||
var header [6]int16
|
||||
// Byte array is used to read in byte values
|
||||
var byteArray []byte
|
||||
// Short array is used to read in short values
|
||||
var shArray []int16
|
||||
// TermInfo object to store values
|
||||
var term TermInfo
|
||||
|
||||
// Read in the header
|
||||
err = binary.Read(file, binary.LittleEndian, &header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If magic number isn't there or isn't correct, we have the wrong filetype
|
||||
if header[0] != 0432 {
|
||||
return nil, errors.New(fmt.Sprintf("Wrong filetype"))
|
||||
}
|
||||
|
||||
// Read in the names
|
||||
byteArray = make([]byte, header[1])
|
||||
err = binary.Read(file, binary.LittleEndian, &byteArray)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
term.Names = strings.Split(string(byteArray), "|")
|
||||
|
||||
// Read in the booleans
|
||||
byteArray = make([]byte, header[2])
|
||||
err = binary.Read(file, binary.LittleEndian, &byteArray)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
term.boolAttributes = make(map[string]bool)
|
||||
for i, b := range byteArray {
|
||||
if b == 1 {
|
||||
term.boolAttributes[BoolAttr[i*2+1]] = true
|
||||
}
|
||||
}
|
||||
// If the number of bytes read is not even, a byte for alignment is added
|
||||
if len(byteArray)%2 != 0 {
|
||||
err = binary.Read(file, binary.LittleEndian, make([]byte, 1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Read in shorts
|
||||
shArray = make([]int16, header[3])
|
||||
err = binary.Read(file, binary.LittleEndian, &shArray)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
term.numAttributes = make(map[string]int16)
|
||||
for i, n := range shArray {
|
||||
if n != 0377 && n > -1 {
|
||||
term.numAttributes[NumAttr[i*2+1]] = n
|
||||
}
|
||||
}
|
||||
|
||||
// Read the offsets into the short array
|
||||
shArray = make([]int16, header[4])
|
||||
err = binary.Read(file, binary.LittleEndian, &shArray)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Read the actual strings in the byte array
|
||||
byteArray = make([]byte, header[5])
|
||||
err = binary.Read(file, binary.LittleEndian, &byteArray)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
term.strAttributes = make(map[string]string)
|
||||
// We get an offset, and then iterate until the string is null-terminated
|
||||
for i, offset := range shArray {
|
||||
if offset > -1 {
|
||||
r := offset
|
||||
for ; byteArray[r] != 0; r++ {
|
||||
}
|
||||
term.strAttributes[StrAttr[i*2+1]] = string(byteArray[offset:r])
|
||||
}
|
||||
}
|
||||
return &term, nil
|
||||
}
|
362
vendor/github.com/Nvveen/Gotty/parser.go
generated
vendored
Normal file
362
vendor/github.com/Nvveen/Gotty/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,362 @@
|
|||
// Copyright 2012 Neal van Veen. All rights reserved.
|
||||
// Usage of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package gotty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var exp = [...]string{
|
||||
"%%",
|
||||
"%c",
|
||||
"%s",
|
||||
"%p(\\d)",
|
||||
"%P([A-z])",
|
||||
"%g([A-z])",
|
||||
"%'(.)'",
|
||||
"%{([0-9]+)}",
|
||||
"%l",
|
||||
"%\\+|%-|%\\*|%/|%m",
|
||||
"%&|%\\||%\\^",
|
||||
"%=|%>|%<",
|
||||
"%A|%O",
|
||||
"%!|%~",
|
||||
"%i",
|
||||
"%(:[\\ #\\-\\+]{0,4})?(\\d+\\.\\d+|\\d+)?[doxXs]",
|
||||
"%\\?(.*?);",
|
||||
}
|
||||
|
||||
var regex *regexp.Regexp
|
||||
var staticVar map[byte]stacker
|
||||
|
||||
// Parses the attribute that is received with name attr and parameters params.
|
||||
func (term *TermInfo) Parse(attr string, params ...interface{}) (string, error) {
|
||||
// Get the attribute name first.
|
||||
iface, err := term.GetAttribute(attr)
|
||||
str, ok := iface.(string)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !ok {
|
||||
return str, errors.New("Only string capabilities can be parsed.")
|
||||
}
|
||||
// Construct the hidden parser struct so we can use a recursive stack based
|
||||
// parser.
|
||||
ps := &parser{}
|
||||
// Dynamic variables only exist in this context.
|
||||
ps.dynamicVar = make(map[byte]stacker, 26)
|
||||
ps.parameters = make([]stacker, len(params))
|
||||
// Convert the parameters to insert them into the parser struct.
|
||||
for i, x := range params {
|
||||
ps.parameters[i] = x
|
||||
}
|
||||
// Recursively walk and return.
|
||||
result, err := ps.walk(str)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Parses the attribute that is received with name attr and parameters params.
|
||||
// Only works on full name of a capability that is given, which it uses to
|
||||
// search for the termcap name.
|
||||
func (term *TermInfo) ParseName(attr string, params ...interface{}) (string, error) {
|
||||
tc := GetTermcapName(attr)
|
||||
return term.Parse(tc, params)
|
||||
}
|
||||
|
||||
// Identify each token in a stack based manner and do the actual parsing.
|
||||
func (ps *parser) walk(attr string) (string, error) {
|
||||
// We use a buffer to get the modified string.
|
||||
var buf bytes.Buffer
|
||||
// Next, find and identify all tokens by their indices and strings.
|
||||
tokens := regex.FindAllStringSubmatch(attr, -1)
|
||||
if len(tokens) == 0 {
|
||||
return attr, nil
|
||||
}
|
||||
indices := regex.FindAllStringIndex(attr, -1)
|
||||
q := 0 // q counts the matches of one token
|
||||
// Iterate through the string per character.
|
||||
for i := 0; i < len(attr); i++ {
|
||||
// If the current position is an identified token, execute the following
|
||||
// steps.
|
||||
if q < len(indices) && i >= indices[q][0] && i < indices[q][1] {
|
||||
// Switch on token.
|
||||
switch {
|
||||
case tokens[q][0][:2] == "%%":
|
||||
// Literal percentage character.
|
||||
buf.WriteByte('%')
|
||||
case tokens[q][0][:2] == "%c":
|
||||
// Pop a character.
|
||||
c, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
buf.WriteByte(c.(byte))
|
||||
case tokens[q][0][:2] == "%s":
|
||||
// Pop a string.
|
||||
str, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
if _, ok := str.(string); !ok {
|
||||
return buf.String(), errors.New("Stack head is not a string")
|
||||
}
|
||||
buf.WriteString(str.(string))
|
||||
case tokens[q][0][:2] == "%p":
|
||||
// Push a parameter on the stack.
|
||||
index, err := strconv.ParseInt(tokens[q][1], 10, 8)
|
||||
index--
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
if int(index) >= len(ps.parameters) {
|
||||
return buf.String(), errors.New("Parameters index out of bound")
|
||||
}
|
||||
ps.st.push(ps.parameters[index])
|
||||
case tokens[q][0][:2] == "%P":
|
||||
// Pop a variable from the stack as a dynamic or static variable.
|
||||
val, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
index := tokens[q][2]
|
||||
if len(index) > 1 {
|
||||
errorStr := fmt.Sprintf("%s is not a valid dynamic variables index",
|
||||
index)
|
||||
return buf.String(), errors.New(errorStr)
|
||||
}
|
||||
// Specify either dynamic or static.
|
||||
if index[0] >= 'a' && index[0] <= 'z' {
|
||||
ps.dynamicVar[index[0]] = val
|
||||
} else if index[0] >= 'A' && index[0] <= 'Z' {
|
||||
staticVar[index[0]] = val
|
||||
}
|
||||
case tokens[q][0][:2] == "%g":
|
||||
// Push a variable from the stack as a dynamic or static variable.
|
||||
index := tokens[q][3]
|
||||
if len(index) > 1 {
|
||||
errorStr := fmt.Sprintf("%s is not a valid static variables index",
|
||||
index)
|
||||
return buf.String(), errors.New(errorStr)
|
||||
}
|
||||
var val stacker
|
||||
if index[0] >= 'a' && index[0] <= 'z' {
|
||||
val = ps.dynamicVar[index[0]]
|
||||
} else if index[0] >= 'A' && index[0] <= 'Z' {
|
||||
val = staticVar[index[0]]
|
||||
}
|
||||
ps.st.push(val)
|
||||
case tokens[q][0][:2] == "%'":
|
||||
// Push a character constant.
|
||||
con := tokens[q][4]
|
||||
if len(con) > 1 {
|
||||
errorStr := fmt.Sprintf("%s is not a valid character constant", con)
|
||||
return buf.String(), errors.New(errorStr)
|
||||
}
|
||||
ps.st.push(con[0])
|
||||
case tokens[q][0][:2] == "%{":
|
||||
// Push an integer constant.
|
||||
con, err := strconv.ParseInt(tokens[q][5], 10, 32)
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
ps.st.push(con)
|
||||
case tokens[q][0][:2] == "%l":
|
||||
// Push the length of the string that is popped from the stack.
|
||||
popStr, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
if _, ok := popStr.(string); !ok {
|
||||
errStr := fmt.Sprintf("Stack head is not a string")
|
||||
return buf.String(), errors.New(errStr)
|
||||
}
|
||||
ps.st.push(len(popStr.(string)))
|
||||
case tokens[q][0][:2] == "%?":
|
||||
// If-then-else construct. First, the whole string is identified and
|
||||
// then inside this substring, we can specify which parts to switch on.
|
||||
ifReg, _ := regexp.Compile("%\\?(.*)%t(.*)%e(.*);|%\\?(.*)%t(.*);")
|
||||
ifTokens := ifReg.FindStringSubmatch(tokens[q][0])
|
||||
var (
|
||||
ifStr string
|
||||
err error
|
||||
)
|
||||
// Parse the if-part to determine if-else.
|
||||
if len(ifTokens[1]) > 0 {
|
||||
ifStr, err = ps.walk(ifTokens[1])
|
||||
} else { // else
|
||||
ifStr, err = ps.walk(ifTokens[4])
|
||||
}
|
||||
// Return any errors
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
} else if len(ifStr) > 0 {
|
||||
// Self-defined limitation, not sure if this is correct, but didn't
|
||||
// seem like it.
|
||||
return buf.String(), errors.New("If-clause cannot print statements")
|
||||
}
|
||||
var thenStr string
|
||||
// Pop the first value that is set by parsing the if-clause.
|
||||
choose, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
// Switch to if or else.
|
||||
if choose.(int) == 0 && len(ifTokens[1]) > 0 {
|
||||
thenStr, err = ps.walk(ifTokens[3])
|
||||
} else if choose.(int) != 0 {
|
||||
if len(ifTokens[1]) > 0 {
|
||||
thenStr, err = ps.walk(ifTokens[2])
|
||||
} else {
|
||||
thenStr, err = ps.walk(ifTokens[5])
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
buf.WriteString(thenStr)
|
||||
case tokens[q][0][len(tokens[q][0])-1] == 'd': // Fallthrough for printing
|
||||
fallthrough
|
||||
case tokens[q][0][len(tokens[q][0])-1] == 'o': // digits.
|
||||
fallthrough
|
||||
case tokens[q][0][len(tokens[q][0])-1] == 'x':
|
||||
fallthrough
|
||||
case tokens[q][0][len(tokens[q][0])-1] == 'X':
|
||||
fallthrough
|
||||
case tokens[q][0][len(tokens[q][0])-1] == 's':
|
||||
token := tokens[q][0]
|
||||
// Remove the : that comes before a flag.
|
||||
if token[1] == ':' {
|
||||
token = token[:1] + token[2:]
|
||||
}
|
||||
digit, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
// The rest is determined like the normal formatted prints.
|
||||
digitStr := fmt.Sprintf(token, digit.(int))
|
||||
buf.WriteString(digitStr)
|
||||
case tokens[q][0][:2] == "%i":
|
||||
// Increment the parameters by one.
|
||||
if len(ps.parameters) < 2 {
|
||||
return buf.String(), errors.New("Not enough parameters to increment.")
|
||||
}
|
||||
val1, val2 := ps.parameters[0].(int), ps.parameters[1].(int)
|
||||
val1++
|
||||
val2++
|
||||
ps.parameters[0], ps.parameters[1] = val1, val2
|
||||
default:
|
||||
// The rest of the tokens is a special case, where two values are
|
||||
// popped and then operated on by the token that comes after them.
|
||||
op1, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
op2, err := ps.st.pop()
|
||||
if err != nil {
|
||||
return buf.String(), err
|
||||
}
|
||||
var result stacker
|
||||
switch tokens[q][0][:2] {
|
||||
case "%+":
|
||||
// Addition
|
||||
result = op2.(int) + op1.(int)
|
||||
case "%-":
|
||||
// Subtraction
|
||||
result = op2.(int) - op1.(int)
|
||||
case "%*":
|
||||
// Multiplication
|
||||
result = op2.(int) * op1.(int)
|
||||
case "%/":
|
||||
// Division
|
||||
result = op2.(int) / op1.(int)
|
||||
case "%m":
|
||||
// Modulo
|
||||
result = op2.(int) % op1.(int)
|
||||
case "%&":
|
||||
// Bitwise AND
|
||||
result = op2.(int) & op1.(int)
|
||||
case "%|":
|
||||
// Bitwise OR
|
||||
result = op2.(int) | op1.(int)
|
||||
case "%^":
|
||||
// Bitwise XOR
|
||||
result = op2.(int) ^ op1.(int)
|
||||
case "%=":
|
||||
// Equals
|
||||
result = op2 == op1
|
||||
case "%>":
|
||||
// Greater-than
|
||||
result = op2.(int) > op1.(int)
|
||||
case "%<":
|
||||
// Lesser-than
|
||||
result = op2.(int) < op1.(int)
|
||||
case "%A":
|
||||
// Logical AND
|
||||
result = op2.(bool) && op1.(bool)
|
||||
case "%O":
|
||||
// Logical OR
|
||||
result = op2.(bool) || op1.(bool)
|
||||
case "%!":
|
||||
// Logical complement
|
||||
result = !op1.(bool)
|
||||
case "%~":
|
||||
// Bitwise complement
|
||||
result = ^(op1.(int))
|
||||
}
|
||||
ps.st.push(result)
|
||||
}
|
||||
|
||||
i = indices[q][1] - 1
|
||||
q++
|
||||
} else {
|
||||
// We are not "inside" a token, so just skip until the end or the next
|
||||
// token, and add all characters to the buffer.
|
||||
j := i
|
||||
if q != len(indices) {
|
||||
for !(j >= indices[q][0] && j < indices[q][1]) {
|
||||
j++
|
||||
}
|
||||
} else {
|
||||
j = len(attr)
|
||||
}
|
||||
buf.WriteString(string(attr[i:j]))
|
||||
i = j
|
||||
}
|
||||
}
|
||||
// Return the buffer as a string.
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// Push a stacker-value onto the stack.
|
||||
func (st *stack) push(s stacker) {
|
||||
*st = append(*st, s)
|
||||
}
|
||||
|
||||
// Pop a stacker-value from the stack.
|
||||
func (st *stack) pop() (stacker, error) {
|
||||
if len(*st) == 0 {
|
||||
return nil, errors.New("Stack is empty.")
|
||||
}
|
||||
newStack := make(stack, len(*st)-1)
|
||||
val := (*st)[len(*st)-1]
|
||||
copy(newStack, (*st)[:len(*st)-1])
|
||||
*st = newStack
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// Initialize regexes and the static vars (that don't get changed between
|
||||
// calls.
|
||||
func init() {
|
||||
// Initialize the main regex.
|
||||
expStr := strings.Join(exp[:], "|")
|
||||
regex, _ = regexp.Compile(expStr)
|
||||
// Initialize the static variables.
|
||||
staticVar = make(map[byte]stacker, 26)
|
||||
}
|
23
vendor/github.com/Nvveen/Gotty/types.go
generated
vendored
Normal file
23
vendor/github.com/Nvveen/Gotty/types.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2012 Neal van Veen. All rights reserved.
|
||||
// Usage of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package gotty
|
||||
|
||||
type TermInfo struct {
|
||||
boolAttributes map[string]bool
|
||||
numAttributes map[string]int16
|
||||
strAttributes map[string]string
|
||||
// The various names of the TermInfo file.
|
||||
Names []string
|
||||
}
|
||||
|
||||
type stacker interface {
|
||||
}
|
||||
type stack []stacker
|
||||
|
||||
type parser struct {
|
||||
st stack
|
||||
parameters []stacker
|
||||
dynamicVar map[byte]stacker
|
||||
}
|
20
vendor/github.com/beorn7/perks/LICENSE
generated
vendored
Normal file
20
vendor/github.com/beorn7/perks/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Copyright (C) 2013 Blake Mizerany
|
||||
|
||||
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.
|
316
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
Normal file
316
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
Normal file
|
@ -0,0 +1,316 @@
|
|||
// Package quantile computes approximate quantiles over an unbounded data
|
||||
// stream within low memory and CPU bounds.
|
||||
//
|
||||
// A small amount of accuracy is traded to achieve the above properties.
|
||||
//
|
||||
// Multiple streams can be merged before calling Query to generate a single set
|
||||
// of results. This is meaningful when the streams represent the same type of
|
||||
// data. See Merge and Samples.
|
||||
//
|
||||
// For more detailed information about the algorithm used, see:
|
||||
//
|
||||
// Effective Computation of Biased Quantiles over Data Streams
|
||||
//
|
||||
// http://www.cs.rutgers.edu/~muthu/bquant.pdf
|
||||
package quantile
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Sample holds an observed value and meta information for compression. JSON
|
||||
// tags have been added for convenience.
|
||||
type Sample struct {
|
||||
Value float64 `json:",string"`
|
||||
Width float64 `json:",string"`
|
||||
Delta float64 `json:",string"`
|
||||
}
|
||||
|
||||
// Samples represents a slice of samples. It implements sort.Interface.
|
||||
type Samples []Sample
|
||||
|
||||
func (a Samples) Len() int { return len(a) }
|
||||
func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }
|
||||
func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
type invariant func(s *stream, r float64) float64
|
||||
|
||||
// NewLowBiased returns an initialized Stream for low-biased quantiles
|
||||
// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
|
||||
// error guarantees can still be given even for the lower ranks of the data
|
||||
// distribution.
|
||||
//
|
||||
// The provided epsilon is a relative error, i.e. the true quantile of a value
|
||||
// returned by a query is guaranteed to be within (1±Epsilon)*Quantile.
|
||||
//
|
||||
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
|
||||
// properties.
|
||||
func NewLowBiased(epsilon float64) *Stream {
|
||||
ƒ := func(s *stream, r float64) float64 {
|
||||
return 2 * epsilon * r
|
||||
}
|
||||
return newStream(ƒ)
|
||||
}
|
||||
|
||||
// NewHighBiased returns an initialized Stream for high-biased quantiles
|
||||
// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
|
||||
// error guarantees can still be given even for the higher ranks of the data
|
||||
// distribution.
|
||||
//
|
||||
// The provided epsilon is a relative error, i.e. the true quantile of a value
|
||||
// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile).
|
||||
//
|
||||
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
|
||||
// properties.
|
||||
func NewHighBiased(epsilon float64) *Stream {
|
||||
ƒ := func(s *stream, r float64) float64 {
|
||||
return 2 * epsilon * (s.n - r)
|
||||
}
|
||||
return newStream(ƒ)
|
||||
}
|
||||
|
||||
// NewTargeted returns an initialized Stream concerned with a particular set of
|
||||
// quantile values that are supplied a priori. Knowing these a priori reduces
|
||||
// space and computation time. The targets map maps the desired quantiles to
|
||||
// their absolute errors, i.e. the true quantile of a value returned by a query
|
||||
// is guaranteed to be within (Quantile±Epsilon).
|
||||
//
|
||||
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
|
||||
func NewTargeted(targetMap map[float64]float64) *Stream {
|
||||
// Convert map to slice to avoid slow iterations on a map.
|
||||
// ƒ is called on the hot path, so converting the map to a slice
|
||||
// beforehand results in significant CPU savings.
|
||||
targets := targetMapToSlice(targetMap)
|
||||
|
||||
ƒ := func(s *stream, r float64) float64 {
|
||||
var m = math.MaxFloat64
|
||||
var f float64
|
||||
for _, t := range targets {
|
||||
if t.quantile*s.n <= r {
|
||||
f = (2 * t.epsilon * r) / t.quantile
|
||||
} else {
|
||||
f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)
|
||||
}
|
||||
if f < m {
|
||||
m = f
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
return newStream(ƒ)
|
||||
}
|
||||
|
||||
type target struct {
|
||||
quantile float64
|
||||
epsilon float64
|
||||
}
|
||||
|
||||
func targetMapToSlice(targetMap map[float64]float64) []target {
|
||||
targets := make([]target, 0, len(targetMap))
|
||||
|
||||
for quantile, epsilon := range targetMap {
|
||||
t := target{
|
||||
quantile: quantile,
|
||||
epsilon: epsilon,
|
||||
}
|
||||
targets = append(targets, t)
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
// Stream computes quantiles for a stream of float64s. It is not thread-safe by
|
||||
// design. Take care when using across multiple goroutines.
|
||||
type Stream struct {
|
||||
*stream
|
||||
b Samples
|
||||
sorted bool
|
||||
}
|
||||
|
||||
func newStream(ƒ invariant) *Stream {
|
||||
x := &stream{ƒ: ƒ}
|
||||
return &Stream{x, make(Samples, 0, 500), true}
|
||||
}
|
||||
|
||||
// Insert inserts v into the stream.
|
||||
func (s *Stream) Insert(v float64) {
|
||||
s.insert(Sample{Value: v, Width: 1})
|
||||
}
|
||||
|
||||
func (s *Stream) insert(sample Sample) {
|
||||
s.b = append(s.b, sample)
|
||||
s.sorted = false
|
||||
if len(s.b) == cap(s.b) {
|
||||
s.flush()
|
||||
}
|
||||
}
|
||||
|
||||
// Query returns the computed qth percentiles value. If s was created with
|
||||
// NewTargeted, and q is not in the set of quantiles provided a priori, Query
|
||||
// will return an unspecified result.
|
||||
func (s *Stream) Query(q float64) float64 {
|
||||
if !s.flushed() {
|
||||
// Fast path when there hasn't been enough data for a flush;
|
||||
// this also yields better accuracy for small sets of data.
|
||||
l := len(s.b)
|
||||
if l == 0 {
|
||||
return 0
|
||||
}
|
||||
i := int(math.Ceil(float64(l) * q))
|
||||
if i > 0 {
|
||||
i -= 1
|
||||
}
|
||||
s.maybeSort()
|
||||
return s.b[i].Value
|
||||
}
|
||||
s.flush()
|
||||
return s.stream.query(q)
|
||||
}
|
||||
|
||||
// Merge merges samples into the underlying streams samples. This is handy when
|
||||
// merging multiple streams from separate threads, database shards, etc.
|
||||
//
|
||||
// ATTENTION: This method is broken and does not yield correct results. The
|
||||
// underlying algorithm is not capable of merging streams correctly.
|
||||
func (s *Stream) Merge(samples Samples) {
|
||||
sort.Sort(samples)
|
||||
s.stream.merge(samples)
|
||||
}
|
||||
|
||||
// Reset reinitializes and clears the list reusing the samples buffer memory.
|
||||
func (s *Stream) Reset() {
|
||||
s.stream.reset()
|
||||
s.b = s.b[:0]
|
||||
}
|
||||
|
||||
// Samples returns stream samples held by s.
|
||||
func (s *Stream) Samples() Samples {
|
||||
if !s.flushed() {
|
||||
return s.b
|
||||
}
|
||||
s.flush()
|
||||
return s.stream.samples()
|
||||
}
|
||||
|
||||
// Count returns the total number of samples observed in the stream
|
||||
// since initialization.
|
||||
func (s *Stream) Count() int {
|
||||
return len(s.b) + s.stream.count()
|
||||
}
|
||||
|
||||
func (s *Stream) flush() {
|
||||
s.maybeSort()
|
||||
s.stream.merge(s.b)
|
||||
s.b = s.b[:0]
|
||||
}
|
||||
|
||||
func (s *Stream) maybeSort() {
|
||||
if !s.sorted {
|
||||
s.sorted = true
|
||||
sort.Sort(s.b)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stream) flushed() bool {
|
||||
return len(s.stream.l) > 0
|
||||
}
|
||||
|
||||
type stream struct {
|
||||
n float64
|
||||
l []Sample
|
||||
ƒ invariant
|
||||
}
|
||||
|
||||
func (s *stream) reset() {
|
||||
s.l = s.l[:0]
|
||||
s.n = 0
|
||||
}
|
||||
|
||||
func (s *stream) insert(v float64) {
|
||||
s.merge(Samples{{v, 1, 0}})
|
||||
}
|
||||
|
||||
func (s *stream) merge(samples Samples) {
|
||||
// TODO(beorn7): This tries to merge not only individual samples, but
|
||||
// whole summaries. The paper doesn't mention merging summaries at
|
||||
// all. Unittests show that the merging is inaccurate. Find out how to
|
||||
// do merges properly.
|
||||
var r float64
|
||||
i := 0
|
||||
for _, sample := range samples {
|
||||
for ; i < len(s.l); i++ {
|
||||
c := s.l[i]
|
||||
if c.Value > sample.Value {
|
||||
// Insert at position i.
|
||||
s.l = append(s.l, Sample{})
|
||||
copy(s.l[i+1:], s.l[i:])
|
||||
s.l[i] = Sample{
|
||||
sample.Value,
|
||||
sample.Width,
|
||||
math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1),
|
||||
// TODO(beorn7): How to calculate delta correctly?
|
||||
}
|
||||
i++
|
||||
goto inserted
|
||||
}
|
||||
r += c.Width
|
||||
}
|
||||
s.l = append(s.l, Sample{sample.Value, sample.Width, 0})
|
||||
i++
|
||||
inserted:
|
||||
s.n += sample.Width
|
||||
r += sample.Width
|
||||
}
|
||||
s.compress()
|
||||
}
|
||||
|
||||
func (s *stream) count() int {
|
||||
return int(s.n)
|
||||
}
|
||||
|
||||
func (s *stream) query(q float64) float64 {
|
||||
t := math.Ceil(q * s.n)
|
||||
t += math.Ceil(s.ƒ(s, t) / 2)
|
||||
p := s.l[0]
|
||||
var r float64
|
||||
for _, c := range s.l[1:] {
|
||||
r += p.Width
|
||||
if r+c.Width+c.Delta > t {
|
||||
return p.Value
|
||||
}
|
||||
p = c
|
||||
}
|
||||
return p.Value
|
||||
}
|
||||
|
||||
func (s *stream) compress() {
|
||||
if len(s.l) < 2 {
|
||||
return
|
||||
}
|
||||
x := s.l[len(s.l)-1]
|
||||
xi := len(s.l) - 1
|
||||
r := s.n - 1 - x.Width
|
||||
|
||||
for i := len(s.l) - 2; i >= 0; i-- {
|
||||
c := s.l[i]
|
||||
if c.Width+x.Width+x.Delta <= s.ƒ(s, r) {
|
||||
x.Width += c.Width
|
||||
s.l[xi] = x
|
||||
// Remove element at i.
|
||||
copy(s.l[i:], s.l[i+1:])
|
||||
s.l = s.l[:len(s.l)-1]
|
||||
xi -= 1
|
||||
} else {
|
||||
x = c
|
||||
xi = i
|
||||
}
|
||||
r -= c.Width
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stream) samples() Samples {
|
||||
samples := make(Samples, len(s.l))
|
||||
copy(samples, s.l)
|
||||
return samples
|
||||
}
|
78
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
78
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
Copyright The containerd 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 errdefs defines the common errors used throughout containerd
|
||||
// packages.
|
||||
//
|
||||
// Use with errors.Wrap and error.Wrapf to add context to an error.
|
||||
//
|
||||
// To detect an error class, use the IsXXX functions to tell whether an error
|
||||
// is of a certain type.
|
||||
//
|
||||
// The functions ToGRPC and FromGRPC can be used to map server-side and
|
||||
// client-side errors to the correct types.
|
||||
package errdefs
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
// Definitions of common error types used throughout containerd. All containerd
|
||||
// errors returned by most packages will map into one of these errors classes.
|
||||
// Packages should return errors of these types when they want to instruct a
|
||||
// client to take a particular action.
|
||||
//
|
||||
// For the most part, we just try to provide local grpc errors. Most conditions
|
||||
// map very well to those defined by grpc.
|
||||
var (
|
||||
ErrUnknown = errors.New("unknown") // used internally to represent a missed mapping.
|
||||
ErrInvalidArgument = errors.New("invalid argument")
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrAlreadyExists = errors.New("already exists")
|
||||
ErrFailedPrecondition = errors.New("failed precondition")
|
||||
ErrUnavailable = errors.New("unavailable")
|
||||
ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented
|
||||
)
|
||||
|
||||
// IsInvalidArgument returns true if the error is due to an invalid argument
|
||||
func IsInvalidArgument(err error) bool {
|
||||
return errors.Cause(err) == ErrInvalidArgument
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is due to a missing object
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Cause(err) == ErrNotFound
|
||||
}
|
||||
|
||||
// IsAlreadyExists returns true if the error is due to an already existing
|
||||
// metadata item
|
||||
func IsAlreadyExists(err error) bool {
|
||||
return errors.Cause(err) == ErrAlreadyExists
|
||||
}
|
||||
|
||||
// IsFailedPrecondition returns true if an operation could not proceed to the
|
||||
// lack of a particular condition
|
||||
func IsFailedPrecondition(err error) bool {
|
||||
return errors.Cause(err) == ErrFailedPrecondition
|
||||
}
|
||||
|
||||
// IsUnavailable returns true if the error is due to a resource being unavailable
|
||||
func IsUnavailable(err error) bool {
|
||||
return errors.Cause(err) == ErrUnavailable
|
||||
}
|
||||
|
||||
// IsNotImplemented returns true if the error is due to not being implemented
|
||||
func IsNotImplemented(err error) bool {
|
||||
return errors.Cause(err) == ErrNotImplemented
|
||||
}
|
138
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
138
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
Copyright The containerd 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 errdefs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// ToGRPC will attempt to map the backend containerd error into a grpc error,
|
||||
// using the original error message as a description.
|
||||
//
|
||||
// Further information may be extracted from certain errors depending on their
|
||||
// type.
|
||||
//
|
||||
// If the error is unmapped, the original error will be returned to be handled
|
||||
// by the regular grpc error handling stack.
|
||||
func ToGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if isGRPCError(err) {
|
||||
// error has already been mapped to grpc
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case IsInvalidArgument(err):
|
||||
return status.Errorf(codes.InvalidArgument, err.Error())
|
||||
case IsNotFound(err):
|
||||
return status.Errorf(codes.NotFound, err.Error())
|
||||
case IsAlreadyExists(err):
|
||||
return status.Errorf(codes.AlreadyExists, err.Error())
|
||||
case IsFailedPrecondition(err):
|
||||
return status.Errorf(codes.FailedPrecondition, err.Error())
|
||||
case IsUnavailable(err):
|
||||
return status.Errorf(codes.Unavailable, err.Error())
|
||||
case IsNotImplemented(err):
|
||||
return status.Errorf(codes.Unimplemented, err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
|
||||
// and combining it with the target error string.
|
||||
//
|
||||
// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
|
||||
func ToGRPCf(err error, format string, args ...interface{}) error {
|
||||
return ToGRPC(errors.Wrapf(err, format, args...))
|
||||
}
|
||||
|
||||
// FromGRPC returns the underlying error from a grpc service based on the grpc error code
|
||||
func FromGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cls error // divide these into error classes, becomes the cause
|
||||
|
||||
switch code(err) {
|
||||
case codes.InvalidArgument:
|
||||
cls = ErrInvalidArgument
|
||||
case codes.AlreadyExists:
|
||||
cls = ErrAlreadyExists
|
||||
case codes.NotFound:
|
||||
cls = ErrNotFound
|
||||
case codes.Unavailable:
|
||||
cls = ErrUnavailable
|
||||
case codes.FailedPrecondition:
|
||||
cls = ErrFailedPrecondition
|
||||
case codes.Unimplemented:
|
||||
cls = ErrNotImplemented
|
||||
default:
|
||||
cls = ErrUnknown
|
||||
}
|
||||
|
||||
msg := rebaseMessage(cls, err)
|
||||
if msg != "" {
|
||||
err = errors.Wrapf(cls, msg)
|
||||
} else {
|
||||
err = errors.WithStack(cls)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// rebaseMessage removes the repeats for an error at the end of an error
|
||||
// string. This will happen when taking an error over grpc then remapping it.
|
||||
//
|
||||
// Effectively, we just remove the string of cls from the end of err if it
|
||||
// appears there.
|
||||
func rebaseMessage(cls error, err error) string {
|
||||
desc := errDesc(err)
|
||||
clss := cls.Error()
|
||||
if desc == clss {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimSuffix(desc, ": "+clss)
|
||||
}
|
||||
|
||||
func isGRPCError(err error) bool {
|
||||
_, ok := status.FromError(err)
|
||||
return ok
|
||||
}
|
||||
|
||||
func code(err error) codes.Code {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Code()
|
||||
}
|
||||
return codes.Unknown
|
||||
}
|
||||
|
||||
func errDesc(err error) string {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Message()
|
||||
}
|
||||
return err.Error()
|
||||
}
|
16
vendor/github.com/containerd/continuity/AUTHORS
generated
vendored
Normal file
16
vendor/github.com/containerd/continuity/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
Aaron Lehmann <aaron.lehmann@docker.com>
|
||||
Akash Gupta <akagup@microsoft.com>
|
||||
Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
|
||||
Andrew Pennebaker <apennebaker@datapipe.com>
|
||||
Brandon Philips <brandon.philips@coreos.com>
|
||||
Christopher Jones <tophj@linux.vnet.ibm.com>
|
||||
Daniel, Dao Quang Minh <dqminh89@gmail.com>
|
||||
Derek McGowan <derek@mcgstyle.net>
|
||||
Edward Pilatowicz <edward.pilatowicz@oracle.com>
|
||||
Ian Campbell <ijc@docker.com>
|
||||
Justin Cormack <justin.cormack@docker.com>
|
||||
Justin Cummins <sul3n3t@gmail.com>
|
||||
Phil Estes <estesp@gmail.com>
|
||||
Stephen J Day <stephen.day@docker.com>
|
||||
Tobias Klauser <tklauser@distanz.ch>
|
||||
Tonis Tiigi <tonistiigi@gmail.com>
|
202
vendor/github.com/containerd/continuity/LICENSE
generated
vendored
Normal file
202
vendor/github.com/containerd/continuity/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
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.
|
||||
|
101
vendor/github.com/containerd/continuity/pathdriver/path_driver.go
generated
vendored
Normal file
101
vendor/github.com/containerd/continuity/pathdriver/path_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright The containerd 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 pathdriver
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// PathDriver provides all of the path manipulation functions in a common
|
||||
// interface. The context should call these and never use the `filepath`
|
||||
// package or any other package to manipulate paths.
|
||||
type PathDriver interface {
|
||||
Join(paths ...string) string
|
||||
IsAbs(path string) bool
|
||||
Rel(base, target string) (string, error)
|
||||
Base(path string) string
|
||||
Dir(path string) string
|
||||
Clean(path string) string
|
||||
Split(path string) (dir, file string)
|
||||
Separator() byte
|
||||
Abs(path string) (string, error)
|
||||
Walk(string, filepath.WalkFunc) error
|
||||
FromSlash(path string) string
|
||||
ToSlash(path string) string
|
||||
Match(pattern, name string) (matched bool, err error)
|
||||
}
|
||||
|
||||
// pathDriver is a simple default implementation calls the filepath package.
|
||||
type pathDriver struct{}
|
||||
|
||||
// LocalPathDriver is the exported pathDriver struct for convenience.
|
||||
var LocalPathDriver PathDriver = &pathDriver{}
|
||||
|
||||
func (*pathDriver) Join(paths ...string) string {
|
||||
return filepath.Join(paths...)
|
||||
}
|
||||
|
||||
func (*pathDriver) IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Rel(base, target string) (string, error) {
|
||||
return filepath.Rel(base, target)
|
||||
}
|
||||
|
||||
func (*pathDriver) Base(path string) string {
|
||||
return filepath.Base(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Dir(path string) string {
|
||||
return filepath.Dir(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Clean(path string) string {
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Split(path string) (dir, file string) {
|
||||
return filepath.Split(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Separator() byte {
|
||||
return filepath.Separator
|
||||
}
|
||||
|
||||
func (*pathDriver) Abs(path string) (string, error) {
|
||||
return filepath.Abs(path)
|
||||
}
|
||||
|
||||
// Note that filepath.Walk calls os.Stat, so if the context wants to
|
||||
// to call Driver.Stat() for Walk, they need to create a new struct that
|
||||
// overrides this method.
|
||||
func (*pathDriver) Walk(root string, walkFn filepath.WalkFunc) error {
|
||||
return filepath.Walk(root, walkFn)
|
||||
}
|
||||
|
||||
func (*pathDriver) FromSlash(path string) string {
|
||||
return filepath.FromSlash(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) ToSlash(path string) string {
|
||||
return filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Match(pattern, name string) (bool, error) {
|
||||
return filepath.Match(pattern, name)
|
||||
}
|
0
vendor/github.com/coreos/clair/LICENSE
generated
vendored
Normal file → Executable file
0
vendor/github.com/coreos/clair/LICENSE
generated
vendored
Normal file → Executable file
0
vendor/github.com/coreos/clair/NOTICE
generated
vendored
Normal file → Executable file
0
vendor/github.com/coreos/clair/NOTICE
generated
vendored
Normal file → Executable file
7
vendor/github.com/coreos/clair/api/v3/clairpb/Dockerfile
generated
vendored
7
vendor/github.com/coreos/clair/api/v3/clairpb/Dockerfile
generated
vendored
|
@ -1,7 +0,0 @@
|
|||
FROM golang:alpine
|
||||
|
||||
RUN apk add --update --no-cache git bash protobuf-dev
|
||||
|
||||
RUN go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
|
||||
RUN go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
|
||||
RUN go get -u github.com/golang/protobuf/protoc-gen-go
|
514
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.go
generated
vendored
514
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.go
generated
vendored
|
@ -9,8 +9,6 @@ It is generated from these files:
|
|||
|
||||
It has these top-level messages:
|
||||
Vulnerability
|
||||
Detector
|
||||
Namespace
|
||||
Feature
|
||||
Layer
|
||||
ClairStatus
|
||||
|
@ -50,37 +48,12 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Detector_DType int32
|
||||
|
||||
const (
|
||||
Detector_DETECTOR_D_TYPE_INVALID Detector_DType = 0
|
||||
Detector_DETECTOR_D_TYPE_NAMESPACE Detector_DType = 1
|
||||
Detector_DETECTOR_D_TYPE_FEATURE Detector_DType = 2
|
||||
)
|
||||
|
||||
var Detector_DType_name = map[int32]string{
|
||||
0: "DETECTOR_D_TYPE_INVALID",
|
||||
1: "DETECTOR_D_TYPE_NAMESPACE",
|
||||
2: "DETECTOR_D_TYPE_FEATURE",
|
||||
}
|
||||
var Detector_DType_value = map[string]int32{
|
||||
"DETECTOR_D_TYPE_INVALID": 0,
|
||||
"DETECTOR_D_TYPE_NAMESPACE": 1,
|
||||
"DETECTOR_D_TYPE_FEATURE": 2,
|
||||
}
|
||||
|
||||
func (x Detector_DType) String() string {
|
||||
return proto.EnumName(Detector_DType_name, int32(x))
|
||||
}
|
||||
func (Detector_DType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }
|
||||
|
||||
type Vulnerability struct {
|
||||
// The name of the vulnerability.
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// The name of the namespace in which the vulnerability was detected.
|
||||
NamespaceName string `protobuf:"bytes,2,opt,name=namespace_name,json=namespaceName" json:"namespace_name,omitempty"`
|
||||
// A description of the vulnerability according to the source for the
|
||||
// namespace.
|
||||
// A description of the vulnerability according to the source for the namespace.
|
||||
Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
|
||||
// A link to the vulnerability according to the source for the namespace.
|
||||
Link string `protobuf:"bytes,4,opt,name=link" json:"link,omitempty"`
|
||||
|
@ -157,91 +130,23 @@ func (m *Vulnerability) GetAffectedVersions() []*Feature {
|
|||
return nil
|
||||
}
|
||||
|
||||
type Detector struct {
|
||||
// The name of the detector.
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// The version of the detector.
|
||||
Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
|
||||
// The type of the detector.
|
||||
Dtype Detector_DType `protobuf:"varint,3,opt,name=dtype,enum=coreos.clair.Detector_DType" json:"dtype,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Detector) Reset() { *m = Detector{} }
|
||||
func (m *Detector) String() string { return proto.CompactTextString(m) }
|
||||
func (*Detector) ProtoMessage() {}
|
||||
func (*Detector) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *Detector) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Detector) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Detector) GetDtype() Detector_DType {
|
||||
if m != nil {
|
||||
return m.Dtype
|
||||
}
|
||||
return Detector_DETECTOR_D_TYPE_INVALID
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
// The name of the namespace.
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// The detector used to detect the namespace. This only exists when present
|
||||
// in an Ancestry Feature.
|
||||
Detector *Detector `protobuf:"bytes,2,opt,name=detector" json:"detector,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Namespace) Reset() { *m = Namespace{} }
|
||||
func (m *Namespace) String() string { return proto.CompactTextString(m) }
|
||||
func (*Namespace) ProtoMessage() {}
|
||||
func (*Namespace) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
func (m *Namespace) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Namespace) GetDetector() *Detector {
|
||||
if m != nil {
|
||||
return m.Detector
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Feature struct {
|
||||
// The name of the feature.
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// The namespace in which the feature is detected.
|
||||
Namespace *Namespace `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
|
||||
// The name of the namespace in which the feature is detected.
|
||||
NamespaceName string `protobuf:"bytes,2,opt,name=namespace_name,json=namespaceName" json:"namespace_name,omitempty"`
|
||||
// The specific version of this feature.
|
||||
Version string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
|
||||
// The format used to parse version numbers for the feature.
|
||||
VersionFormat string `protobuf:"bytes,4,opt,name=version_format,json=versionFormat" json:"version_format,omitempty"`
|
||||
// The detector used to detect this feature. This only exists when present
|
||||
// in an Ancestry.
|
||||
Detector *Detector `protobuf:"bytes,5,opt,name=detector" json:"detector,omitempty"`
|
||||
// The list of vulnerabilities that affect the feature.
|
||||
Vulnerabilities []*Vulnerability `protobuf:"bytes,6,rep,name=vulnerabilities" json:"vulnerabilities,omitempty"`
|
||||
// The feature type indicates if the feature represents a source package or
|
||||
// binary package.
|
||||
FeatureType string `protobuf:"bytes,7,opt,name=feature_type,json=featureType" json:"feature_type,omitempty"`
|
||||
Vulnerabilities []*Vulnerability `protobuf:"bytes,5,rep,name=vulnerabilities" json:"vulnerabilities,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Feature) Reset() { *m = Feature{} }
|
||||
func (m *Feature) String() string { return proto.CompactTextString(m) }
|
||||
func (*Feature) ProtoMessage() {}
|
||||
func (*Feature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
func (*Feature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func (m *Feature) GetName() string {
|
||||
if m != nil {
|
||||
|
@ -250,11 +155,11 @@ func (m *Feature) GetName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetNamespace() *Namespace {
|
||||
func (m *Feature) GetNamespaceName() string {
|
||||
if m != nil {
|
||||
return m.Namespace
|
||||
return m.NamespaceName
|
||||
}
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetVersion() string {
|
||||
|
@ -271,13 +176,6 @@ func (m *Feature) GetVersionFormat() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *Feature) GetDetector() *Detector {
|
||||
if m != nil {
|
||||
return m.Detector
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Feature) GetVulnerabilities() []*Vulnerability {
|
||||
if m != nil {
|
||||
return m.Vulnerabilities
|
||||
|
@ -285,13 +183,6 @@ func (m *Feature) GetVulnerabilities() []*Vulnerability {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Feature) GetFeatureType() string {
|
||||
if m != nil {
|
||||
return m.FeatureType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Layer struct {
|
||||
// The sha256 tarsum for the layer.
|
||||
Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"`
|
||||
|
@ -300,7 +191,7 @@ type Layer struct {
|
|||
func (m *Layer) Reset() { *m = Layer{} }
|
||||
func (m *Layer) String() string { return proto.CompactTextString(m) }
|
||||
func (*Layer) ProtoMessage() {}
|
||||
func (*Layer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
func (*Layer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
func (m *Layer) GetHash() string {
|
||||
if m != nil {
|
||||
|
@ -310,18 +201,27 @@ func (m *Layer) GetHash() string {
|
|||
}
|
||||
|
||||
type ClairStatus struct {
|
||||
// The implemented detectors in this Clair instance
|
||||
Detectors []*Detector `protobuf:"bytes,1,rep,name=detectors" json:"detectors,omitempty"`
|
||||
// The configured list of feature listers used to scan an ancestry.
|
||||
Listers []string `protobuf:"bytes,1,rep,name=listers" json:"listers,omitempty"`
|
||||
// The configured list of namespace detectors used to scan an ancestry.
|
||||
Detectors []string `protobuf:"bytes,2,rep,name=detectors" json:"detectors,omitempty"`
|
||||
// The time at which the updater last ran.
|
||||
LastUpdateTime *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=last_update_time,json=lastUpdateTime" json:"last_update_time,omitempty"`
|
||||
LastUpdateTime *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=last_update_time,json=lastUpdateTime" json:"last_update_time,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ClairStatus) Reset() { *m = ClairStatus{} }
|
||||
func (m *ClairStatus) String() string { return proto.CompactTextString(m) }
|
||||
func (*ClairStatus) ProtoMessage() {}
|
||||
func (*ClairStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
func (*ClairStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
func (m *ClairStatus) GetDetectors() []*Detector {
|
||||
func (m *ClairStatus) GetListers() []string {
|
||||
if m != nil {
|
||||
return m.Listers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ClairStatus) GetDetectors() []string {
|
||||
if m != nil {
|
||||
return m.Detectors
|
||||
}
|
||||
|
@ -343,7 +243,7 @@ type GetAncestryRequest struct {
|
|||
func (m *GetAncestryRequest) Reset() { *m = GetAncestryRequest{} }
|
||||
func (m *GetAncestryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryRequest) ProtoMessage() {}
|
||||
func (*GetAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
func (*GetAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
|
||||
|
||||
func (m *GetAncestryRequest) GetAncestryName() string {
|
||||
if m != nil {
|
||||
|
@ -355,14 +255,14 @@ func (m *GetAncestryRequest) GetAncestryName() string {
|
|||
type GetAncestryResponse struct {
|
||||
// The ancestry requested.
|
||||
Ancestry *GetAncestryResponse_Ancestry `protobuf:"bytes,1,opt,name=ancestry" json:"ancestry,omitempty"`
|
||||
// The status of Clair at the time of the request
|
||||
// The status of Clair at the time of the request.
|
||||
Status *ClairStatus `protobuf:"bytes,2,opt,name=status" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse) Reset() { *m = GetAncestryResponse{} }
|
||||
func (m *GetAncestryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryResponse) ProtoMessage() {}
|
||||
func (*GetAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
func (*GetAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
|
||||
|
||||
func (m *GetAncestryResponse) GetAncestry() *GetAncestryResponse_Ancestry {
|
||||
if m != nil {
|
||||
|
@ -389,7 +289,7 @@ func (m *GetAncestryResponse_AncestryLayer) Reset() { *m = GetAncestryRe
|
|||
func (m *GetAncestryResponse_AncestryLayer) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryResponse_AncestryLayer) ProtoMessage() {}
|
||||
func (*GetAncestryResponse_AncestryLayer) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{7, 0}
|
||||
return fileDescriptor0, []int{5, 0}
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse_AncestryLayer) GetLayer() *Layer {
|
||||
|
@ -409,14 +309,18 @@ func (m *GetAncestryResponse_AncestryLayer) GetDetectedFeatures() []*Feature {
|
|||
type GetAncestryResponse_Ancestry struct {
|
||||
// The name of the desired ancestry.
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
// The configured list of feature listers used to scan this ancestry.
|
||||
ScannedListers []string `protobuf:"bytes,4,rep,name=scanned_listers,json=scannedListers" json:"scanned_listers,omitempty"`
|
||||
// The configured list of namespace detectors used to scan an ancestry.
|
||||
ScannedDetectors []string `protobuf:"bytes,5,rep,name=scanned_detectors,json=scannedDetectors" json:"scanned_detectors,omitempty"`
|
||||
// The list of layers along with detected features in each.
|
||||
Layers []*GetAncestryResponse_AncestryLayer `protobuf:"bytes,3,rep,name=layers" json:"layers,omitempty"`
|
||||
Layers []*GetAncestryResponse_AncestryLayer `protobuf:"bytes,6,rep,name=layers" json:"layers,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse_Ancestry) Reset() { *m = GetAncestryResponse_Ancestry{} }
|
||||
func (m *GetAncestryResponse_Ancestry) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAncestryResponse_Ancestry) ProtoMessage() {}
|
||||
func (*GetAncestryResponse_Ancestry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7, 1} }
|
||||
func (*GetAncestryResponse_Ancestry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5, 1} }
|
||||
|
||||
func (m *GetAncestryResponse_Ancestry) GetName() string {
|
||||
if m != nil {
|
||||
|
@ -425,6 +329,20 @@ func (m *GetAncestryResponse_Ancestry) GetName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse_Ancestry) GetScannedListers() []string {
|
||||
if m != nil {
|
||||
return m.ScannedListers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse_Ancestry) GetScannedDetectors() []string {
|
||||
if m != nil {
|
||||
return m.ScannedDetectors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetAncestryResponse_Ancestry) GetLayers() []*GetAncestryResponse_AncestryLayer {
|
||||
if m != nil {
|
||||
return m.Layers
|
||||
|
@ -446,7 +364,7 @@ type PostAncestryRequest struct {
|
|||
func (m *PostAncestryRequest) Reset() { *m = PostAncestryRequest{} }
|
||||
func (m *PostAncestryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryRequest) ProtoMessage() {}
|
||||
func (*PostAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
func (*PostAncestryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
|
||||
|
||||
func (m *PostAncestryRequest) GetAncestryName() string {
|
||||
if m != nil {
|
||||
|
@ -474,8 +392,7 @@ type PostAncestryRequest_PostLayer struct {
|
|||
Hash string `protobuf:"bytes,1,opt,name=hash" json:"hash,omitempty"`
|
||||
// The location of the layer (URL or filepath).
|
||||
Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
|
||||
// Any HTTP Headers that need to be used if requesting a layer over
|
||||
// HTTP(S).
|
||||
// Any HTTP Headers that need to be used if requesting a layer over HTTP(S).
|
||||
Headers map[string]string `protobuf:"bytes,3,rep,name=headers" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
}
|
||||
|
||||
|
@ -483,7 +400,7 @@ func (m *PostAncestryRequest_PostLayer) Reset() { *m = PostAncestryReque
|
|||
func (m *PostAncestryRequest_PostLayer) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryRequest_PostLayer) ProtoMessage() {}
|
||||
func (*PostAncestryRequest_PostLayer) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{8, 0}
|
||||
return fileDescriptor0, []int{6, 0}
|
||||
}
|
||||
|
||||
func (m *PostAncestryRequest_PostLayer) GetHash() string {
|
||||
|
@ -515,7 +432,7 @@ type PostAncestryResponse struct {
|
|||
func (m *PostAncestryResponse) Reset() { *m = PostAncestryResponse{} }
|
||||
func (m *PostAncestryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*PostAncestryResponse) ProtoMessage() {}
|
||||
func (*PostAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
func (*PostAncestryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
|
||||
func (m *PostAncestryResponse) GetStatus() *ClairStatus {
|
||||
if m != nil {
|
||||
|
@ -540,7 +457,7 @@ type GetNotificationRequest struct {
|
|||
func (m *GetNotificationRequest) Reset() { *m = GetNotificationRequest{} }
|
||||
func (m *GetNotificationRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetNotificationRequest) ProtoMessage() {}
|
||||
func (*GetNotificationRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
|
||||
func (*GetNotificationRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
|
||||
|
||||
func (m *GetNotificationRequest) GetOldVulnerabilityPage() string {
|
||||
if m != nil {
|
||||
|
@ -578,7 +495,7 @@ type GetNotificationResponse struct {
|
|||
func (m *GetNotificationResponse) Reset() { *m = GetNotificationResponse{} }
|
||||
func (m *GetNotificationResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetNotificationResponse) ProtoMessage() {}
|
||||
func (*GetNotificationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
|
||||
func (*GetNotificationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
|
||||
|
||||
func (m *GetNotificationResponse) GetNotification() *GetNotificationResponse_Notification {
|
||||
if m != nil {
|
||||
|
@ -596,11 +513,9 @@ type GetNotificationResponse_Notification struct {
|
|||
Notified string `protobuf:"bytes,3,opt,name=notified" json:"notified,omitempty"`
|
||||
// The time at which a notification has been deleted.
|
||||
Deleted string `protobuf:"bytes,4,opt,name=deleted" json:"deleted,omitempty"`
|
||||
// The previous vulnerability and a paginated view of the ancestries it
|
||||
// affects.
|
||||
// The previous vulnerability and a paginated view of the ancestries it affects.
|
||||
Old *PagedVulnerableAncestries `protobuf:"bytes,5,opt,name=old" json:"old,omitempty"`
|
||||
// The newly updated vulnerability and a paginated view of the
|
||||
// ancestries it affects.
|
||||
// The newly updated vulnerability and a paginated view of the ancestries it affects.
|
||||
New *PagedVulnerableAncestries `protobuf:"bytes,6,opt,name=new" json:"new,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -608,7 +523,7 @@ func (m *GetNotificationResponse_Notification) Reset() { *m = GetNotific
|
|||
func (m *GetNotificationResponse_Notification) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetNotificationResponse_Notification) ProtoMessage() {}
|
||||
func (*GetNotificationResponse_Notification) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{11, 0}
|
||||
return fileDescriptor0, []int{9, 0}
|
||||
}
|
||||
|
||||
func (m *GetNotificationResponse_Notification) GetName() string {
|
||||
|
@ -670,7 +585,7 @@ type PagedVulnerableAncestries struct {
|
|||
func (m *PagedVulnerableAncestries) Reset() { *m = PagedVulnerableAncestries{} }
|
||||
func (m *PagedVulnerableAncestries) String() string { return proto.CompactTextString(m) }
|
||||
func (*PagedVulnerableAncestries) ProtoMessage() {}
|
||||
func (*PagedVulnerableAncestries) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
|
||||
func (*PagedVulnerableAncestries) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
|
||||
|
||||
func (m *PagedVulnerableAncestries) GetCurrentPage() string {
|
||||
if m != nil {
|
||||
|
@ -708,9 +623,8 @@ func (m *PagedVulnerableAncestries) GetAncestries() []*PagedVulnerableAncestries
|
|||
}
|
||||
|
||||
type PagedVulnerableAncestries_IndexedAncestryName struct {
|
||||
// The index is an ever increasing number associated with the particular
|
||||
// ancestry. This is useful if you're processing notifications, and need
|
||||
// to keep track of the progress of paginating the results.
|
||||
// The index is an ever increasing number associated with the particular ancestry.
|
||||
// This is useful if you're processing notifications, and need to keep track of the progress of paginating the results.
|
||||
Index int32 `protobuf:"varint,1,opt,name=index" json:"index,omitempty"`
|
||||
// The name of the ancestry.
|
||||
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
|
||||
|
@ -724,7 +638,7 @@ func (m *PagedVulnerableAncestries_IndexedAncestryName) String() string {
|
|||
}
|
||||
func (*PagedVulnerableAncestries_IndexedAncestryName) ProtoMessage() {}
|
||||
func (*PagedVulnerableAncestries_IndexedAncestryName) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor0, []int{12, 0}
|
||||
return fileDescriptor0, []int{10, 0}
|
||||
}
|
||||
|
||||
func (m *PagedVulnerableAncestries_IndexedAncestryName) GetIndex() int32 {
|
||||
|
@ -749,7 +663,7 @@ type MarkNotificationAsReadRequest struct {
|
|||
func (m *MarkNotificationAsReadRequest) Reset() { *m = MarkNotificationAsReadRequest{} }
|
||||
func (m *MarkNotificationAsReadRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*MarkNotificationAsReadRequest) ProtoMessage() {}
|
||||
func (*MarkNotificationAsReadRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
|
||||
func (*MarkNotificationAsReadRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
|
||||
|
||||
func (m *MarkNotificationAsReadRequest) GetName() string {
|
||||
if m != nil {
|
||||
|
@ -764,7 +678,7 @@ type MarkNotificationAsReadResponse struct {
|
|||
func (m *MarkNotificationAsReadResponse) Reset() { *m = MarkNotificationAsReadResponse{} }
|
||||
func (m *MarkNotificationAsReadResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*MarkNotificationAsReadResponse) ProtoMessage() {}
|
||||
func (*MarkNotificationAsReadResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
func (*MarkNotificationAsReadResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
|
||||
|
||||
type GetStatusRequest struct {
|
||||
}
|
||||
|
@ -772,7 +686,7 @@ type GetStatusRequest struct {
|
|||
func (m *GetStatusRequest) Reset() { *m = GetStatusRequest{} }
|
||||
func (m *GetStatusRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetStatusRequest) ProtoMessage() {}
|
||||
func (*GetStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
|
||||
func (*GetStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
|
||||
|
||||
type GetStatusResponse struct {
|
||||
// The status of the current Clair instance.
|
||||
|
@ -782,7 +696,7 @@ type GetStatusResponse struct {
|
|||
func (m *GetStatusResponse) Reset() { *m = GetStatusResponse{} }
|
||||
func (m *GetStatusResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetStatusResponse) ProtoMessage() {}
|
||||
func (*GetStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
|
||||
func (*GetStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
|
||||
func (m *GetStatusResponse) GetStatus() *ClairStatus {
|
||||
if m != nil {
|
||||
|
@ -793,8 +707,6 @@ func (m *GetStatusResponse) GetStatus() *ClairStatus {
|
|||
|
||||
func init() {
|
||||
proto.RegisterType((*Vulnerability)(nil), "coreos.clair.Vulnerability")
|
||||
proto.RegisterType((*Detector)(nil), "coreos.clair.Detector")
|
||||
proto.RegisterType((*Namespace)(nil), "coreos.clair.Namespace")
|
||||
proto.RegisterType((*Feature)(nil), "coreos.clair.Feature")
|
||||
proto.RegisterType((*Layer)(nil), "coreos.clair.Layer")
|
||||
proto.RegisterType((*ClairStatus)(nil), "coreos.clair.ClairStatus")
|
||||
|
@ -814,7 +726,6 @@ func init() {
|
|||
proto.RegisterType((*MarkNotificationAsReadResponse)(nil), "coreos.clair.MarkNotificationAsReadResponse")
|
||||
proto.RegisterType((*GetStatusRequest)(nil), "coreos.clair.GetStatusRequest")
|
||||
proto.RegisterType((*GetStatusResponse)(nil), "coreos.clair.GetStatusResponse")
|
||||
proto.RegisterEnum("coreos.clair.Detector_DType", Detector_DType_name, Detector_DType_value)
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -926,72 +837,6 @@ var _AncestryService_serviceDesc = grpc.ServiceDesc{
|
|||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
// Client API for StatusService service
|
||||
|
||||
type StatusServiceClient interface {
|
||||
// The RPC used to show the internal state of current Clair instance.
|
||||
GetStatus(ctx context.Context, in *GetStatusRequest, opts ...grpc.CallOption) (*GetStatusResponse, error)
|
||||
}
|
||||
|
||||
type statusServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewStatusServiceClient(cc *grpc.ClientConn) StatusServiceClient {
|
||||
return &statusServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *statusServiceClient) GetStatus(ctx context.Context, in *GetStatusRequest, opts ...grpc.CallOption) (*GetStatusResponse, error) {
|
||||
out := new(GetStatusResponse)
|
||||
err := grpc.Invoke(ctx, "/coreos.clair.StatusService/GetStatus", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for StatusService service
|
||||
|
||||
type StatusServiceServer interface {
|
||||
// The RPC used to show the internal state of current Clair instance.
|
||||
GetStatus(context.Context, *GetStatusRequest) (*GetStatusResponse, error)
|
||||
}
|
||||
|
||||
func RegisterStatusServiceServer(s *grpc.Server, srv StatusServiceServer) {
|
||||
s.RegisterService(&_StatusService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _StatusService_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(StatusServiceServer).GetStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/coreos.clair.StatusService/GetStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(StatusServiceServer).GetStatus(ctx, req.(*GetStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _StatusService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "coreos.clair.StatusService",
|
||||
HandlerType: (*StatusServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetStatus",
|
||||
Handler: _StatusService_GetStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
// Client API for NotificationService service
|
||||
|
||||
type NotificationServiceClient interface {
|
||||
|
@ -1093,93 +938,152 @@ var _NotificationService_serviceDesc = grpc.ServiceDesc{
|
|||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
// Client API for StatusService service
|
||||
|
||||
type StatusServiceClient interface {
|
||||
// The RPC used to show the internal state of current Clair instance.
|
||||
GetStatus(ctx context.Context, in *GetStatusRequest, opts ...grpc.CallOption) (*GetStatusResponse, error)
|
||||
}
|
||||
|
||||
type statusServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewStatusServiceClient(cc *grpc.ClientConn) StatusServiceClient {
|
||||
return &statusServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *statusServiceClient) GetStatus(ctx context.Context, in *GetStatusRequest, opts ...grpc.CallOption) (*GetStatusResponse, error) {
|
||||
out := new(GetStatusResponse)
|
||||
err := grpc.Invoke(ctx, "/coreos.clair.StatusService/GetStatus", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for StatusService service
|
||||
|
||||
type StatusServiceServer interface {
|
||||
// The RPC used to show the internal state of current Clair instance.
|
||||
GetStatus(context.Context, *GetStatusRequest) (*GetStatusResponse, error)
|
||||
}
|
||||
|
||||
func RegisterStatusServiceServer(s *grpc.Server, srv StatusServiceServer) {
|
||||
s.RegisterService(&_StatusService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _StatusService_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(StatusServiceServer).GetStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/coreos.clair.StatusService/GetStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(StatusServiceServer).GetStatus(ctx, req.(*GetStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _StatusService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "coreos.clair.StatusService",
|
||||
HandlerType: (*StatusServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetStatus",
|
||||
Handler: _StatusService_GetStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v3/clairpb/clair.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("api/v3/clairpb/clair.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 1345 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4b, 0x6f, 0xdb, 0xc6,
|
||||
0x16, 0xbe, 0x94, 0x23, 0x4b, 0x3a, 0x92, 0x6c, 0x65, 0xec, 0xd8, 0x32, 0x9d, 0x87, 0xcd, 0x7b,
|
||||
0x83, 0x9b, 0x9b, 0x5b, 0x48, 0xa8, 0x92, 0x02, 0x49, 0xba, 0x28, 0x14, 0x5b, 0x76, 0x0d, 0x24,
|
||||
0xae, 0x41, 0x3b, 0x06, 0xda, 0xa2, 0x60, 0xc7, 0xe2, 0x91, 0x4d, 0x98, 0x22, 0x59, 0x72, 0x64,
|
||||
0x47, 0x08, 0xd2, 0x45, 0x77, 0xdd, 0xb6, 0x8b, 0xfe, 0x86, 0x6e, 0xba, 0xe9, 0x4f, 0xe8, 0xbe,
|
||||
0x8b, 0x76, 0xdb, 0xee, 0xba, 0xe8, 0x1f, 0xe8, 0xa2, 0xbb, 0x62, 0x1e, 0xa4, 0x49, 0x9b, 0x7e,
|
||||
0x24, 0x2b, 0xcd, 0x9c, 0x39, 0xcf, 0x6f, 0xbe, 0x39, 0x87, 0x02, 0x9d, 0x06, 0x4e, 0xfb, 0xe8,
|
||||
0x41, 0xbb, 0xef, 0x52, 0x27, 0x0c, 0xf6, 0xe4, 0x6f, 0x2b, 0x08, 0x7d, 0xe6, 0x93, 0x5a, 0xdf,
|
||||
0x0f, 0xd1, 0x8f, 0x5a, 0x42, 0xa6, 0xdf, 0xd9, 0xf7, 0xfd, 0x7d, 0x17, 0xdb, 0xe2, 0x6c, 0x6f,
|
||||
0x34, 0x68, 0x33, 0x67, 0x88, 0x11, 0xa3, 0xc3, 0x40, 0xaa, 0xeb, 0x37, 0x95, 0x02, 0xf7, 0x48,
|
||||
0x3d, 0xcf, 0x67, 0x94, 0x39, 0xbe, 0x17, 0xc9, 0x53, 0xe3, 0xbb, 0x02, 0xd4, 0x77, 0x47, 0xae,
|
||||
0x87, 0x21, 0xdd, 0x73, 0x5c, 0x87, 0x8d, 0x09, 0x81, 0x6b, 0x1e, 0x1d, 0x62, 0x53, 0x5b, 0xd2,
|
||||
0xee, 0x55, 0x4c, 0xb1, 0x26, 0x77, 0x61, 0x8a, 0xff, 0x46, 0x01, 0xed, 0xa3, 0x25, 0x4e, 0x0b,
|
||||
0xe2, 0xb4, 0x9e, 0x48, 0x37, 0xb9, 0xda, 0x12, 0x54, 0x6d, 0x8c, 0xfa, 0xa1, 0x13, 0xf0, 0x10,
|
||||
0xcd, 0x09, 0xa1, 0x93, 0x16, 0x71, 0xe7, 0xae, 0xe3, 0x1d, 0x36, 0xaf, 0x49, 0xe7, 0x7c, 0x4d,
|
||||
0x74, 0x28, 0x47, 0x78, 0x84, 0xa1, 0xc3, 0xc6, 0xcd, 0xa2, 0x90, 0x27, 0x7b, 0x7e, 0x36, 0x44,
|
||||
0x46, 0x6d, 0xca, 0x68, 0x73, 0x52, 0x9e, 0xc5, 0x7b, 0xb2, 0x00, 0xe5, 0x81, 0xf3, 0x12, 0x6d,
|
||||
0x6b, 0x6f, 0xdc, 0x2c, 0x89, 0xb3, 0x92, 0xd8, 0x3f, 0x1d, 0x93, 0xa7, 0x70, 0x9d, 0x0e, 0x06,
|
||||
0xd8, 0x67, 0x68, 0x5b, 0x47, 0x18, 0x46, 0xbc, 0xe0, 0x66, 0x79, 0x69, 0xe2, 0x5e, 0xb5, 0x73,
|
||||
0xa3, 0x95, 0x86, 0xaf, 0xb5, 0x86, 0x94, 0x8d, 0x42, 0x34, 0x1b, 0xb1, 0xfe, 0xae, 0x52, 0x37,
|
||||
0x7e, 0xd6, 0xa0, 0xbc, 0x8a, 0x0c, 0xfb, 0xcc, 0x0f, 0x73, 0x41, 0x69, 0x42, 0x49, 0xf9, 0x56,
|
||||
0x68, 0xc4, 0x5b, 0xd2, 0x81, 0xa2, 0xcd, 0xc6, 0x01, 0x0a, 0x04, 0xa6, 0x3a, 0x37, 0xb3, 0x21,
|
||||
0x63, 0xa7, 0xad, 0xd5, 0x9d, 0x71, 0x80, 0xa6, 0x54, 0x35, 0x3e, 0x87, 0xa2, 0xd8, 0x93, 0x45,
|
||||
0x98, 0x5f, 0xed, 0xed, 0xf4, 0x56, 0x76, 0x3e, 0x32, 0xad, 0x55, 0x6b, 0xe7, 0xe3, 0xad, 0x9e,
|
||||
0xb5, 0xb1, 0xb9, 0xdb, 0x7d, 0xb6, 0xb1, 0xda, 0xf8, 0x17, 0xb9, 0x05, 0x0b, 0xa7, 0x0f, 0x37,
|
||||
0xbb, 0xcf, 0x7b, 0xdb, 0x5b, 0xdd, 0x95, 0x5e, 0x43, 0xcb, 0xb3, 0x5d, 0xeb, 0x75, 0x77, 0x5e,
|
||||
0x98, 0xbd, 0x46, 0xc1, 0xd8, 0x86, 0xca, 0x66, 0x7c, 0x5d, 0xb9, 0x05, 0x75, 0xa0, 0x6c, 0xab,
|
||||
0xdc, 0x44, 0x45, 0xd5, 0xce, 0x5c, 0x7e, 0xe6, 0x66, 0xa2, 0x67, 0xfc, 0x58, 0x80, 0x92, 0xc2,
|
||||
0x30, 0xd7, 0xe7, 0x7b, 0x50, 0x49, 0x38, 0xa2, 0x9c, 0xce, 0x67, 0x9d, 0x26, 0x39, 0x99, 0x27,
|
||||
0x9a, 0x69, 0x6c, 0x27, 0xb2, 0xd8, 0xde, 0x85, 0x29, 0xb5, 0xb4, 0x06, 0x7e, 0x38, 0xa4, 0x4c,
|
||||
0x71, 0xa9, 0xae, 0xa4, 0x6b, 0x42, 0x98, 0xa9, 0xa5, 0x78, 0xb5, 0x5a, 0x48, 0x0f, 0xa6, 0x8f,
|
||||
0x52, 0x4f, 0xc1, 0xc1, 0xa8, 0x39, 0x29, 0x38, 0xb3, 0x98, 0x35, 0xcd, 0xbc, 0x17, 0xf3, 0xb4,
|
||||
0x0d, 0x59, 0x86, 0xda, 0x40, 0x22, 0x62, 0x09, 0x12, 0x48, 0x6e, 0x56, 0x95, 0x8c, 0xdf, 0xb1,
|
||||
0xb1, 0x08, 0xc5, 0x67, 0x74, 0x8c, 0x82, 0x57, 0x07, 0x34, 0x3a, 0x88, 0x21, 0xe3, 0x6b, 0xe3,
|
||||
0x6b, 0x0d, 0xaa, 0x2b, 0x3c, 0xd0, 0x36, 0xa3, 0x6c, 0x14, 0x91, 0x87, 0x50, 0x89, 0x53, 0x8c,
|
||||
0x9a, 0x9a, 0x48, 0xe8, 0xbc, 0x5a, 0x4e, 0x14, 0xc9, 0x2a, 0x34, 0x5c, 0x1a, 0x31, 0x6b, 0x14,
|
||||
0xd8, 0x94, 0xa1, 0xc5, 0xbb, 0x82, 0xc2, 0x5f, 0x6f, 0xc9, 0x8e, 0xd0, 0x8a, 0x5b, 0x46, 0x6b,
|
||||
0x27, 0x6e, 0x19, 0xe6, 0x14, 0xb7, 0x79, 0x21, 0x4c, 0xb8, 0xd0, 0x78, 0x0c, 0x64, 0x1d, 0x59,
|
||||
0xd7, 0xeb, 0x63, 0xc4, 0xc2, 0xb1, 0x89, 0x5f, 0x8c, 0x30, 0x62, 0xe4, 0xdf, 0x50, 0xa7, 0x4a,
|
||||
0x64, 0xa5, 0x6e, 0xbc, 0x16, 0x0b, 0xf9, 0x95, 0x1a, 0x7f, 0x17, 0x60, 0x26, 0x63, 0x1b, 0x05,
|
||||
0xbe, 0x17, 0x21, 0x59, 0x83, 0x72, 0xac, 0x27, 0xec, 0xaa, 0x9d, 0xfb, 0xd9, 0x6a, 0x72, 0x8c,
|
||||
0x5a, 0x89, 0x20, 0xb1, 0x25, 0xef, 0xc2, 0x64, 0x24, 0x00, 0x52, 0x65, 0x2d, 0x64, 0xbd, 0xa4,
|
||||
0x10, 0x34, 0x95, 0xa2, 0xfe, 0x25, 0xd4, 0x63, 0x47, 0x12, 0xfe, 0xff, 0x41, 0xd1, 0xe5, 0x0b,
|
||||
0x95, 0xc8, 0x4c, 0xd6, 0x85, 0xd0, 0x31, 0xa5, 0x06, 0x6f, 0x29, 0x12, 0x5c, 0xb4, 0x2d, 0x75,
|
||||
0x95, 0x3c, 0xf2, 0x45, 0x2d, 0x25, 0xd6, 0x57, 0x82, 0x48, 0xdf, 0x87, 0x72, 0x1c, 0x3f, 0xf7,
|
||||
0xb1, 0xac, 0xc3, 0xa4, 0x08, 0x16, 0x35, 0x27, 0x84, 0xe3, 0xf6, 0xd5, 0x81, 0x91, 0xb9, 0x2a,
|
||||
0x73, 0xe3, 0xf7, 0x02, 0xcc, 0x6c, 0xf9, 0xd1, 0x5b, 0x5d, 0x1c, 0x99, 0x83, 0x49, 0xf5, 0xb2,
|
||||
0x64, 0x5b, 0x53, 0x3b, 0xb2, 0x72, 0x2a, 0xbb, 0xff, 0x67, 0xb3, 0xcb, 0x89, 0x27, 0x64, 0x99,
|
||||
0xcc, 0xf4, 0x9f, 0x34, 0xa8, 0x24, 0xd2, 0x3c, 0xfa, 0x73, 0x59, 0x40, 0xd9, 0x81, 0x0a, 0x2e,
|
||||
0xd6, 0xc4, 0x84, 0xd2, 0x01, 0x52, 0xfb, 0x24, 0xf6, 0xa3, 0x37, 0x88, 0xdd, 0xfa, 0x50, 0x9a,
|
||||
0xf6, 0x3c, 0x7e, 0x1a, 0x3b, 0xd2, 0x9f, 0x40, 0x2d, 0x7d, 0x40, 0x1a, 0x30, 0x71, 0x88, 0x63,
|
||||
0x95, 0x0a, 0x5f, 0x92, 0x59, 0x28, 0x1e, 0x51, 0x77, 0x14, 0x0f, 0x3b, 0xb9, 0x79, 0x52, 0x78,
|
||||
0xa4, 0x19, 0x1b, 0x30, 0x9b, 0x0d, 0xa9, 0xb8, 0x7d, 0xc2, 0x49, 0xed, 0x8a, 0x9c, 0x34, 0x7e,
|
||||
0xd0, 0x60, 0x6e, 0x1d, 0xd9, 0xa6, 0xcf, 0x9c, 0x81, 0xd3, 0x17, 0xb3, 0x39, 0xbe, 0xad, 0x87,
|
||||
0x30, 0xe7, 0xbb, 0xb6, 0x95, 0xee, 0x2f, 0x63, 0x2b, 0xa0, 0xfb, 0xf1, 0xb5, 0xcd, 0xfa, 0xae,
|
||||
0x9d, 0xe9, 0x45, 0x5b, 0x74, 0x1f, 0xb9, 0x95, 0x87, 0xc7, 0x79, 0x56, 0xb2, 0x8c, 0x59, 0x0f,
|
||||
0x8f, 0xcf, 0x5a, 0xcd, 0x42, 0xd1, 0x75, 0x86, 0x0e, 0x13, 0xed, 0xb6, 0x68, 0xca, 0x4d, 0x42,
|
||||
0xd2, 0x6b, 0x27, 0x24, 0x35, 0x7e, 0x2b, 0xc0, 0xfc, 0x99, 0x84, 0x55, 0xfd, 0xbb, 0x50, 0xf3,
|
||||
0x52, 0x72, 0x85, 0x42, 0xe7, 0x0c, 0x8d, 0xf3, 0x8c, 0x5b, 0x19, 0x61, 0xc6, 0x8f, 0xfe, 0xa7,
|
||||
0x06, 0xb5, 0xf4, 0xf1, 0x79, 0xf3, 0xb8, 0x1f, 0x22, 0x65, 0x68, 0xc7, 0xf3, 0x58, 0x6d, 0xf9,
|
||||
0x57, 0x84, 0x74, 0x87, 0xb6, 0x1a, 0x27, 0xc9, 0x9e, 0x5b, 0xd9, 0xe8, 0x22, 0xb7, 0x92, 0x55,
|
||||
0xc6, 0x5b, 0xf2, 0x18, 0x26, 0x7c, 0xd7, 0x56, 0xd3, 0xe3, 0xbf, 0xa7, 0x08, 0x47, 0xf7, 0x31,
|
||||
0xc1, 0xde, 0x45, 0x45, 0x04, 0x07, 0x23, 0x93, 0xdb, 0x70, 0x53, 0x0f, 0x8f, 0xc5, 0x17, 0xcb,
|
||||
0x9b, 0x98, 0x7a, 0x78, 0x6c, 0xfc, 0x52, 0x80, 0x85, 0x73, 0x55, 0xf8, 0x6c, 0xe9, 0x8f, 0xc2,
|
||||
0x10, 0x3d, 0x96, 0x26, 0x42, 0x55, 0xc9, 0xc4, 0x4d, 0x2e, 0x42, 0xc5, 0xc3, 0x97, 0x2c, 0x7d,
|
||||
0xe5, 0x65, 0x2e, 0xb8, 0xe0, 0x9a, 0xbb, 0x50, 0xcf, 0xd0, 0x45, 0x20, 0x71, 0xc9, 0xd8, 0xcb,
|
||||
0x5a, 0x90, 0x4f, 0x01, 0x68, 0x92, 0x66, 0xb3, 0x28, 0x1e, 0xe9, 0xfb, 0x57, 0x2c, 0xbc, 0xb5,
|
||||
0xe1, 0xd9, 0xf8, 0x12, 0xed, 0x6e, 0xaa, 0x0b, 0x99, 0x29, 0x77, 0xfa, 0x07, 0x30, 0x93, 0xa3,
|
||||
0xc2, 0x8b, 0x71, 0xb8, 0x58, 0xa0, 0x50, 0x34, 0xe5, 0x26, 0xa1, 0x46, 0x21, 0xc5, 0xd9, 0x07,
|
||||
0x70, 0xeb, 0x39, 0x0d, 0x0f, 0xd3, 0x14, 0xea, 0x46, 0x26, 0x52, 0x3b, 0x7e, 0x6a, 0x39, 0x7c,
|
||||
0x32, 0x96, 0xe0, 0xf6, 0x79, 0x46, 0x92, 0xb1, 0x06, 0x81, 0xc6, 0x3a, 0x32, 0xf5, 0xa0, 0xa5,
|
||||
0x27, 0x63, 0x0d, 0xae, 0xa7, 0x64, 0x6f, 0xdd, 0x17, 0x3a, 0x7f, 0x69, 0x30, 0x1d, 0x57, 0xbb,
|
||||
0x8d, 0xe1, 0x91, 0xd3, 0x47, 0x32, 0x82, 0x6a, 0x6a, 0x06, 0x90, 0xa5, 0x0b, 0xc6, 0x83, 0x48,
|
||||
0x46, 0x5f, 0xbe, 0x74, 0x80, 0x18, 0xcb, 0x5f, 0xfd, 0xfa, 0xc7, 0xb7, 0x85, 0x45, 0xb2, 0xd0,
|
||||
0x8e, 0x87, 0x40, 0xfb, 0x55, 0x66, 0x46, 0xbc, 0x26, 0x87, 0x50, 0x4b, 0x77, 0x3b, 0xb2, 0x7c,
|
||||
0x69, 0xf3, 0xd5, 0x8d, 0x8b, 0x54, 0x54, 0xe4, 0x59, 0x11, 0x79, 0xca, 0xa8, 0x24, 0x91, 0x9f,
|
||||
0x68, 0xf7, 0x3b, 0x1e, 0xd4, 0x25, 0x12, 0x71, 0xd1, 0x9f, 0x41, 0x25, 0x01, 0x94, 0xdc, 0x3e,
|
||||
0x53, 0x50, 0x06, 0x7d, 0xfd, 0xce, 0xb9, 0xe7, 0x2a, 0xe8, 0xb4, 0x08, 0x5a, 0x21, 0xa5, 0xb6,
|
||||
0xc2, 0xf9, 0xfb, 0x02, 0xcc, 0xa4, 0xaf, 0x38, 0x0e, 0xfb, 0x1a, 0xa6, 0x4f, 0x35, 0x2a, 0xf2,
|
||||
0x9f, 0x4b, 0xfa, 0x98, 0x4c, 0xe1, 0xee, 0x95, 0xba, 0x9d, 0x71, 0x4b, 0x24, 0x32, 0x4f, 0x6e,
|
||||
0xb4, 0xd3, 0x9d, 0x2e, 0x6a, 0xbf, 0x92, 0x98, 0x7f, 0xa3, 0xc1, 0x5c, 0x3e, 0xfb, 0xc8, 0xa9,
|
||||
0xb9, 0x7b, 0x21, 0xb1, 0xf5, 0x77, 0xae, 0xa6, 0x9c, 0x4d, 0xea, 0x7e, 0x7e, 0x52, 0x4f, 0x6f,
|
||||
0xc3, 0x4c, 0xdf, 0x1f, 0x66, 0x3d, 0x06, 0x7b, 0x9f, 0x94, 0xd4, 0xbf, 0xd4, 0xbd, 0x49, 0xf1,
|
||||
0x45, 0xf9, 0xe0, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x4b, 0xee, 0xfe, 0xbe, 0x0e, 0x00,
|
||||
0x00,
|
||||
// 1237 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0x4b, 0x6f, 0x1b, 0xd5,
|
||||
0x17, 0xd7, 0xd8, 0x71, 0x1c, 0x1f, 0xdb, 0x49, 0x7a, 0x93, 0xa6, 0x93, 0x49, 0x1f, 0xc9, 0xfc,
|
||||
0xff, 0x55, 0x4b, 0x8b, 0x6c, 0xe1, 0xb2, 0x68, 0xcb, 0x02, 0xa5, 0x8f, 0x84, 0x4a, 0xa5, 0xaa,
|
||||
0xa6, 0xd0, 0x05, 0x08, 0x59, 0xd7, 0x33, 0xc7, 0xc9, 0x28, 0xe3, 0x19, 0x33, 0xf7, 0xda, 0x89,
|
||||
0x55, 0x95, 0x05, 0x5b, 0x76, 0xb0, 0xe0, 0x33, 0xb0, 0xe1, 0x1b, 0xb0, 0x62, 0xcb, 0x02, 0xc1,
|
||||
0x16, 0x76, 0x2c, 0xf8, 0x02, 0xec, 0xd1, 0x7d, 0x4d, 0x66, 0x12, 0xe7, 0xd1, 0xb2, 0xf2, 0x9c,
|
||||
0xf7, 0xeb, 0x77, 0xcf, 0x49, 0xc0, 0xa1, 0xc3, 0xb0, 0x3d, 0xbe, 0xd3, 0xf6, 0x23, 0x1a, 0xa6,
|
||||
0xc3, 0x9e, 0xfa, 0x6d, 0x0d, 0xd3, 0x84, 0x27, 0xa4, 0xe1, 0x27, 0x29, 0x26, 0xac, 0x25, 0x79,
|
||||
0xce, 0xb5, 0x9d, 0x24, 0xd9, 0x89, 0xb0, 0x2d, 0x65, 0xbd, 0x51, 0xbf, 0xcd, 0xc3, 0x01, 0x32,
|
||||
0x4e, 0x07, 0x43, 0xa5, 0xee, 0x5c, 0xd6, 0x0a, 0xc2, 0x23, 0x8d, 0xe3, 0x84, 0x53, 0x1e, 0x26,
|
||||
0x31, 0x53, 0x52, 0xf7, 0xfb, 0x12, 0x34, 0x5f, 0x8e, 0xa2, 0x18, 0x53, 0xda, 0x0b, 0xa3, 0x90,
|
||||
0x4f, 0x08, 0x81, 0x99, 0x98, 0x0e, 0xd0, 0xb6, 0xd6, 0xad, 0x9b, 0x35, 0x4f, 0x7e, 0x93, 0xeb,
|
||||
0x30, 0x2f, 0x7e, 0xd9, 0x90, 0xfa, 0xd8, 0x95, 0xd2, 0x92, 0x94, 0x36, 0x33, 0xee, 0x33, 0xa1,
|
||||
0xb6, 0x0e, 0xf5, 0x00, 0x99, 0x9f, 0x86, 0x43, 0x11, 0xc2, 0x2e, 0x4b, 0x9d, 0x3c, 0x4b, 0x38,
|
||||
0x8f, 0xc2, 0x78, 0xcf, 0x9e, 0x51, 0xce, 0xc5, 0x37, 0x71, 0x60, 0x8e, 0xe1, 0x18, 0xd3, 0x90,
|
||||
0x4f, 0xec, 0x8a, 0xe4, 0x67, 0xb4, 0x90, 0x0d, 0x90, 0xd3, 0x80, 0x72, 0x6a, 0xcf, 0x2a, 0x99,
|
||||
0xa1, 0xc9, 0x2a, 0xcc, 0xf5, 0xc3, 0x03, 0x0c, 0xba, 0xbd, 0x89, 0x5d, 0x95, 0xb2, 0xaa, 0xa4,
|
||||
0x1f, 0x4c, 0xc8, 0x03, 0xb8, 0x40, 0xfb, 0x7d, 0xf4, 0x39, 0x06, 0xdd, 0x31, 0xa6, 0x4c, 0x14,
|
||||
0x6c, 0xcf, 0xad, 0x97, 0x6f, 0xd6, 0x3b, 0x17, 0x5b, 0xf9, 0xf6, 0xb5, 0xb6, 0x90, 0xf2, 0x51,
|
||||
0x8a, 0xde, 0xa2, 0xd1, 0x7f, 0xa9, 0xd5, 0xdd, 0x5f, 0x2c, 0xa8, 0x6a, 0xe9, 0x7f, 0xe9, 0x89,
|
||||
0x0d, 0x55, 0x9d, 0x81, 0xee, 0x87, 0x21, 0x85, 0x03, 0xfd, 0xd9, 0xed, 0x27, 0xe9, 0x80, 0x72,
|
||||
0xdd, 0x95, 0xa6, 0xe6, 0x6e, 0x49, 0x26, 0x79, 0x0c, 0x0b, 0xe3, 0xdc, 0x80, 0x42, 0x64, 0x76,
|
||||
0x45, 0x56, 0xb2, 0x56, 0xac, 0xa4, 0x30, 0x45, 0xef, 0xa8, 0x8d, 0xbb, 0x06, 0x95, 0xa7, 0x74,
|
||||
0x82, 0xa9, 0xa8, 0x65, 0x97, 0xb2, 0x5d, 0x53, 0x8b, 0xf8, 0x76, 0xbf, 0xb1, 0xa0, 0xfe, 0x50,
|
||||
0x78, 0x79, 0xc1, 0x29, 0x1f, 0x31, 0x91, 0x74, 0x14, 0x32, 0x8e, 0x29, 0xb3, 0xad, 0xf5, 0xb2,
|
||||
0x48, 0x5a, 0x93, 0xe4, 0x32, 0xd4, 0x02, 0xe4, 0xe8, 0xf3, 0x24, 0x65, 0x76, 0x49, 0xca, 0x0e,
|
||||
0x19, 0xe4, 0x11, 0x2c, 0x46, 0x94, 0xf1, 0xee, 0x68, 0x18, 0x50, 0x8e, 0x5d, 0x01, 0x45, 0x59,
|
||||
0x75, 0xbd, 0xe3, 0xb4, 0x14, 0x0c, 0x5b, 0x06, 0xa7, 0xad, 0x4f, 0x0c, 0x4e, 0xbd, 0x79, 0x61,
|
||||
0xf3, 0xa9, 0x34, 0x11, 0x4c, 0xf7, 0x1e, 0x90, 0x6d, 0xe4, 0x9b, 0xb1, 0x8f, 0x8c, 0xa7, 0x13,
|
||||
0x0f, 0xbf, 0x1c, 0x21, 0xe3, 0xe4, 0x7f, 0xd0, 0xa4, 0x9a, 0xd5, 0xcd, 0x0d, 0xa3, 0x61, 0x98,
|
||||
0xa2, 0xdb, 0xee, 0xaf, 0x65, 0x58, 0x2a, 0xd8, 0xb2, 0x61, 0x12, 0x33, 0x24, 0x5b, 0x30, 0x67,
|
||||
0xf4, 0xa4, 0x5d, 0xbd, 0x73, 0xab, 0xd8, 0xbd, 0x29, 0x46, 0xad, 0x8c, 0x91, 0xd9, 0x92, 0xf7,
|
||||
0x60, 0x96, 0xc9, 0x16, 0xc9, 0x61, 0xd7, 0x3b, 0xab, 0x45, 0x2f, 0xb9, 0x1e, 0x7a, 0x5a, 0xd1,
|
||||
0xf9, 0x0a, 0x9a, 0xc6, 0x91, 0x1a, 0xc0, 0x3b, 0x50, 0x89, 0xc4, 0x87, 0x4e, 0x64, 0xa9, 0xe8,
|
||||
0x42, 0xea, 0x78, 0x4a, 0x43, 0xe0, 0x58, 0x35, 0x17, 0x83, 0x6e, 0x5f, 0x61, 0x51, 0x75, 0xfd,
|
||||
0x64, 0x1c, 0x1b, 0x7d, 0xcd, 0x60, 0xce, 0x4f, 0x16, 0xcc, 0x99, 0x04, 0xa6, 0x02, 0xf9, 0x06,
|
||||
0x2c, 0x30, 0x9f, 0xc6, 0x31, 0x06, 0x5d, 0x33, 0xf4, 0x19, 0x39, 0xd8, 0x79, 0xcd, 0x7e, 0xaa,
|
||||
0x67, 0x7f, 0x1b, 0x2e, 0x18, 0xc5, 0x43, 0x0c, 0x54, 0xa4, 0xea, 0xa2, 0x16, 0x3c, 0xca, 0xa0,
|
||||
0xb0, 0x0d, 0xb3, 0xb2, 0x06, 0x66, 0xcf, 0xca, 0x7c, 0xdb, 0xe7, 0xef, 0xb7, 0x6a, 0x81, 0x36,
|
||||
0x77, 0xff, 0x2c, 0xc1, 0xd2, 0xf3, 0x84, 0xbd, 0x15, 0x1e, 0xc8, 0x0a, 0xcc, 0xea, 0xb7, 0xa5,
|
||||
0x1e, 0xa7, 0xa6, 0xc8, 0xc3, 0x2c, 0xbb, 0xb2, 0xcc, 0xee, 0x76, 0x31, 0xbb, 0x29, 0xf1, 0x24,
|
||||
0xaf, 0x90, 0x99, 0xf3, 0xb3, 0x05, 0xb5, 0x8c, 0x3b, 0xed, 0x5d, 0x09, 0xde, 0x90, 0xf2, 0x5d,
|
||||
0x1d, 0x5c, 0x7e, 0x13, 0x0f, 0xaa, 0xbb, 0x48, 0x83, 0xc3, 0xd8, 0x77, 0xdf, 0x20, 0x76, 0xeb,
|
||||
0x23, 0x65, 0xfa, 0x38, 0x16, 0x52, 0xe3, 0xc8, 0xb9, 0x0f, 0x8d, 0xbc, 0x80, 0x2c, 0x42, 0x79,
|
||||
0x0f, 0x27, 0x3a, 0x15, 0xf1, 0x49, 0x96, 0xa1, 0x32, 0xa6, 0xd1, 0xc8, 0x2c, 0x29, 0x45, 0xdc,
|
||||
0x2f, 0xdd, 0xb5, 0xdc, 0x27, 0xb0, 0x5c, 0x0c, 0xa9, 0x9f, 0xcc, 0x21, 0xd4, 0xad, 0x73, 0x42,
|
||||
0xdd, 0xfd, 0xd1, 0x82, 0x95, 0x6d, 0xe4, 0xcf, 0x12, 0x1e, 0xf6, 0x43, 0x5f, 0xde, 0x19, 0x33,
|
||||
0xad, 0xf7, 0x61, 0x25, 0x89, 0x82, 0x6e, 0x7e, 0x2b, 0x4d, 0xba, 0x43, 0xba, 0x63, 0xc6, 0xb6,
|
||||
0x9c, 0x44, 0x41, 0x61, 0x83, 0x3d, 0xa7, 0x3b, 0x28, 0xac, 0x62, 0xdc, 0x9f, 0x66, 0xa5, 0xca,
|
||||
0x58, 0x8e, 0x71, 0xff, 0xb8, 0xd5, 0x32, 0x54, 0xa2, 0x70, 0x10, 0x72, 0xb9, 0x7a, 0x2a, 0x9e,
|
||||
0x22, 0x32, 0xe8, 0xcf, 0x1c, 0x42, 0xdf, 0xfd, 0xa3, 0x04, 0x97, 0x8e, 0x25, 0xac, 0xeb, 0x7f,
|
||||
0x09, 0x8d, 0x38, 0xc7, 0xd7, 0x5d, 0xe8, 0x1c, 0x83, 0xf1, 0x34, 0xe3, 0x56, 0x81, 0x59, 0xf0,
|
||||
0xe3, 0xfc, 0x6d, 0x41, 0x23, 0x2f, 0x9e, 0xfa, 0x26, 0x6d, 0xa8, 0xfa, 0x29, 0x52, 0x8e, 0x81,
|
||||
0xae, 0xd4, 0x90, 0xe2, 0x22, 0x2a, 0x77, 0x18, 0xe8, 0x83, 0x92, 0xd1, 0xc2, 0x2a, 0xc0, 0x08,
|
||||
0x85, 0x95, 0xaa, 0xd2, 0x90, 0xe4, 0x1e, 0x94, 0x93, 0x28, 0x90, 0xe7, 0xb5, 0xde, 0xb9, 0x71,
|
||||
0x04, 0x70, 0x74, 0x07, 0xb3, 0xde, 0x47, 0xa8, 0x81, 0x10, 0x22, 0xf3, 0x84, 0x8d, 0x30, 0x8d,
|
||||
0x71, 0x5f, 0x5e, 0xdf, 0x37, 0x31, 0x8d, 0x71, 0xdf, 0xfd, 0xad, 0x04, 0xab, 0x27, 0xaa, 0x90,
|
||||
0x0d, 0x68, 0xf8, 0xa3, 0x34, 0xc5, 0x98, 0xe7, 0x81, 0x50, 0xd7, 0x3c, 0x39, 0xc9, 0x35, 0xa8,
|
||||
0xc5, 0x78, 0xc0, 0xf3, 0x23, 0x9f, 0x13, 0x8c, 0x53, 0xc6, 0xbc, 0x09, 0xcd, 0x02, 0x5c, 0x64,
|
||||
0x27, 0xce, 0x38, 0x96, 0x45, 0x0b, 0xf2, 0x39, 0x00, 0xcd, 0xd2, 0xd4, 0xc7, 0xf6, 0x83, 0x73,
|
||||
0x16, 0xde, 0x7a, 0x12, 0x07, 0x78, 0x80, 0xc1, 0x66, 0x6e, 0x0b, 0x79, 0x39, 0x77, 0xce, 0x87,
|
||||
0xb0, 0x34, 0x45, 0x45, 0x14, 0x13, 0x0a, 0xb6, 0xec, 0x42, 0xc5, 0x53, 0x44, 0x06, 0x8d, 0x52,
|
||||
0x0e, 0xb3, 0x77, 0xe0, 0xca, 0xc7, 0x34, 0xdd, 0xcb, 0x43, 0x68, 0x93, 0x79, 0x48, 0x03, 0xf3,
|
||||
0xd4, 0xa6, 0xe0, 0xc9, 0x5d, 0x87, 0xab, 0x27, 0x19, 0x29, 0xc4, 0xba, 0x04, 0x16, 0xb7, 0x91,
|
||||
0xeb, 0x07, 0xad, 0x3c, 0xb9, 0x5b, 0x70, 0x21, 0xc7, 0x7b, 0xeb, 0xbd, 0xd0, 0xf9, 0xc7, 0x82,
|
||||
0x05, 0x53, 0xed, 0x0b, 0x4c, 0xc7, 0xa1, 0x8f, 0x64, 0x04, 0xf5, 0xdc, 0x0d, 0x20, 0xeb, 0xa7,
|
||||
0x9c, 0x07, 0x99, 0x8c, 0xb3, 0x71, 0xe6, 0x01, 0x71, 0x37, 0xbe, 0xfe, 0xfd, 0xaf, 0xef, 0x4a,
|
||||
0x6b, 0x64, 0xb5, 0x6d, 0x8e, 0x40, 0xfb, 0x55, 0xe1, 0x46, 0xbc, 0x26, 0x7b, 0xd0, 0xc8, 0x6f,
|
||||
0x3b, 0xb2, 0x71, 0xe6, 0xf2, 0x75, 0xdc, 0xd3, 0x54, 0x74, 0xe4, 0x65, 0x19, 0x79, 0xde, 0xad,
|
||||
0x65, 0x91, 0xef, 0x5b, 0xb7, 0x3a, 0x3f, 0x94, 0x60, 0x29, 0xdf, 0x72, 0x53, 0xfb, 0x6b, 0x58,
|
||||
0x38, 0xb2, 0x38, 0xc8, 0xff, 0xcf, 0xd8, 0x2b, 0x2a, 0x95, 0xeb, 0xe7, 0xda, 0x3e, 0xee, 0x15,
|
||||
0x99, 0xcd, 0x25, 0x72, 0xb1, 0x9d, 0xdf, 0x3c, 0xac, 0xfd, 0x4a, 0xf5, 0xe0, 0x5b, 0x0b, 0x56,
|
||||
0xa6, 0xa3, 0x81, 0x1c, 0xb9, 0x83, 0xa7, 0x02, 0xcd, 0x79, 0xf7, 0x7c, 0xca, 0xc5, 0xa4, 0x6e,
|
||||
0x4d, 0x4f, 0xaa, 0x13, 0x43, 0x53, 0xa1, 0xc6, 0x34, 0xe9, 0x0b, 0xa8, 0x65, 0xe0, 0x23, 0x57,
|
||||
0x8f, 0x15, 0x5e, 0x40, 0xaa, 0x73, 0xed, 0x44, 0xb9, 0x8e, 0xbe, 0x20, 0xa3, 0xd7, 0x48, 0xb5,
|
||||
0xad, 0x30, 0xf9, 0xe0, 0x2a, 0x2c, 0xf9, 0xc9, 0xa0, 0x68, 0x36, 0xec, 0x7d, 0x56, 0xd5, 0xff,
|
||||
0x71, 0xf5, 0x66, 0xe5, 0x1f, 0xaa, 0x77, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xd2, 0x74,
|
||||
0xfa, 0x8a, 0x0d, 0x00, 0x00,
|
||||
}
|
||||
|
|
174
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.gw.go
generated
vendored
174
vendor/github.com/coreos/clair/api/v3/clairpb/clair.pb.gw.go
generated
vendored
|
@ -70,15 +70,6 @@ func request_AncestryService_PostAncestry_0(ctx context.Context, marshaler runti
|
|||
|
||||
}
|
||||
|
||||
func request_StatusService_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, client StatusServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetStatusRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_NotificationService_GetNotification_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
@ -141,6 +132,15 @@ func request_NotificationService_MarkNotificationAsRead_0(ctx context.Context, m
|
|||
|
||||
}
|
||||
|
||||
func request_StatusService_GetStatus_0(ctx context.Context, marshaler runtime.Marshaler, client StatusServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetStatusRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterAncestryServiceHandlerFromEndpoint is same as RegisterAncestryServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterAncestryServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
|
@ -252,84 +252,6 @@ var (
|
|||
forward_AncestryService_PostAncestry_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
// RegisterStatusServiceHandlerFromEndpoint is same as RegisterStatusServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterStatusServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterStatusServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterStatusServiceHandler registers the http handlers for service StatusService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterStatusServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterStatusServiceHandlerClient(ctx, mux, NewStatusServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterStatusServiceHandler registers the http handlers for service StatusService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over the given implementation of "StatusServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "StatusServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "StatusServiceClient" to call the correct interceptors.
|
||||
func RegisterStatusServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client StatusServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_StatusService_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_StatusService_GetStatus_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_StatusService_GetStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_StatusService_GetStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"status"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_StatusService_GetStatus_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
// RegisterNotificationServiceHandlerFromEndpoint is same as RegisterNotificationServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterNotificationServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
|
@ -440,3 +362,81 @@ var (
|
|||
|
||||
forward_NotificationService_MarkNotificationAsRead_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
// RegisterStatusServiceHandlerFromEndpoint is same as RegisterStatusServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterStatusServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterStatusServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterStatusServiceHandler registers the http handlers for service StatusService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterStatusServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterStatusServiceHandlerClient(ctx, mux, NewStatusServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterStatusServiceHandler registers the http handlers for service StatusService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over the given implementation of "StatusServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "StatusServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "StatusServiceClient" to call the correct interceptors.
|
||||
func RegisterStatusServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client StatusServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_StatusService_GetStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_StatusService_GetStatus_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_StatusService_GetStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_StatusService_GetStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"status"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_StatusService_GetStatus_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
|
260
vendor/github.com/coreos/clair/api/v3/clairpb/clair.proto
generated
vendored
260
vendor/github.com/coreos/clair/api/v3/clairpb/clair.proto
generated
vendored
|
@ -1,260 +0,0 @@
|
|||
// Copyright 2018 clair 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.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
|
||||
package coreos.clair;
|
||||
|
||||
option go_package = "clairpb";
|
||||
option java_package = "com.coreos.clair.pb";
|
||||
|
||||
service AncestryService {
|
||||
// The RPC used to read the results of scanning for a particular ancestry.
|
||||
rpc GetAncestry(GetAncestryRequest) returns (GetAncestryResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/ancestry/{ancestry_name}"
|
||||
};
|
||||
}
|
||||
// The RPC used to create a new scan of an ancestry.
|
||||
rpc PostAncestry(PostAncestryRequest) returns (PostAncestryResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/ancestry"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
service StatusService {
|
||||
// The RPC used to show the internal state of current Clair instance.
|
||||
rpc GetStatus(GetStatusRequest) returns (GetStatusResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/status"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
service NotificationService {
|
||||
// The RPC used to get a particularly Notification.
|
||||
rpc GetNotification(GetNotificationRequest)
|
||||
returns (GetNotificationResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/notifications/{name}"
|
||||
};
|
||||
}
|
||||
// The RPC used to mark a Notification as read after it has been processed.
|
||||
rpc MarkNotificationAsRead(MarkNotificationAsReadRequest)
|
||||
returns (MarkNotificationAsReadResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/notifications/{name}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message Vulnerability {
|
||||
// The name of the vulnerability.
|
||||
string name = 1;
|
||||
// The name of the namespace in which the vulnerability was detected.
|
||||
string namespace_name = 2;
|
||||
// A description of the vulnerability according to the source for the
|
||||
// namespace.
|
||||
string description = 3;
|
||||
// A link to the vulnerability according to the source for the namespace.
|
||||
string link = 4;
|
||||
// How dangerous the vulnerability is.
|
||||
string severity = 5;
|
||||
// Namespace agnostic metadata about the vulnerability.
|
||||
string metadata = 6;
|
||||
// The feature that fixes this vulnerability.
|
||||
// This field only exists when a vulnerability is a part of a Feature.
|
||||
string fixed_by = 7;
|
||||
// The Features that are affected by the vulnerability.
|
||||
// This field only exists when a vulnerability is a part of a Notification.
|
||||
repeated Feature affected_versions = 8;
|
||||
}
|
||||
|
||||
message Detector {
|
||||
enum DType {
|
||||
DETECTOR_D_TYPE_INVALID = 0;
|
||||
DETECTOR_D_TYPE_NAMESPACE = 1;
|
||||
DETECTOR_D_TYPE_FEATURE = 2;
|
||||
}
|
||||
// The name of the detector.
|
||||
string name = 1;
|
||||
// The version of the detector.
|
||||
string version = 2;
|
||||
// The type of the detector.
|
||||
DType dtype = 3;
|
||||
}
|
||||
|
||||
message Namespace {
|
||||
// The name of the namespace.
|
||||
string name = 1;
|
||||
// The detector used to detect the namespace. This only exists when present
|
||||
// in an Ancestry Feature.
|
||||
Detector detector = 2;
|
||||
}
|
||||
|
||||
message Feature {
|
||||
// The name of the feature.
|
||||
string name = 1;
|
||||
// The namespace in which the feature is detected.
|
||||
Namespace namespace = 2;
|
||||
// The specific version of this feature.
|
||||
string version = 3;
|
||||
// The format used to parse version numbers for the feature.
|
||||
string version_format = 4;
|
||||
// The detector used to detect this feature. This only exists when present
|
||||
// in an Ancestry.
|
||||
Detector detector = 5;
|
||||
// The list of vulnerabilities that affect the feature.
|
||||
repeated Vulnerability vulnerabilities = 6;
|
||||
// The feature type indicates if the feature represents a source package or
|
||||
// binary package.
|
||||
string feature_type = 7;
|
||||
}
|
||||
|
||||
message Layer {
|
||||
// The sha256 tarsum for the layer.
|
||||
string hash = 1;
|
||||
}
|
||||
|
||||
message ClairStatus {
|
||||
// The implemented detectors in this Clair instance
|
||||
repeated Detector detectors = 1;
|
||||
// The time at which the updater last ran.
|
||||
google.protobuf.Timestamp last_update_time = 2;
|
||||
}
|
||||
|
||||
message GetAncestryRequest {
|
||||
// The name of the desired ancestry.
|
||||
string ancestry_name = 1;
|
||||
}
|
||||
|
||||
message GetAncestryResponse {
|
||||
message AncestryLayer {
|
||||
// The layer's information.
|
||||
Layer layer = 1;
|
||||
// The features detected in this layer.
|
||||
repeated Feature detected_features = 2;
|
||||
}
|
||||
message Ancestry {
|
||||
// The name of the desired ancestry.
|
||||
string name = 1;
|
||||
// The list of layers along with detected features in each.
|
||||
repeated AncestryLayer layers = 3;
|
||||
}
|
||||
// The ancestry requested.
|
||||
Ancestry ancestry = 1;
|
||||
// The status of Clair at the time of the request
|
||||
ClairStatus status = 2;
|
||||
}
|
||||
|
||||
message PostAncestryRequest {
|
||||
message PostLayer {
|
||||
// The hash of the layer.
|
||||
string hash = 1;
|
||||
// The location of the layer (URL or file path).
|
||||
string path = 2;
|
||||
// Any HTTP Headers that need to be used if requesting a layer over
|
||||
// HTTP(S).
|
||||
map<string, string> headers = 3;
|
||||
}
|
||||
// The name of the ancestry being scanned.
|
||||
// If scanning OCI images, this should be the hash of the manifest.
|
||||
string ancestry_name = 1;
|
||||
// The format of the image being uploaded.
|
||||
string format = 2;
|
||||
// The layers to be scanned for this Ancestry, ordered in the way that i th
|
||||
// layer is the parent of i + 1 th layer.
|
||||
repeated PostLayer layers = 3;
|
||||
}
|
||||
|
||||
message PostAncestryResponse {
|
||||
// The status of Clair at the time of the request.
|
||||
ClairStatus status = 1;
|
||||
}
|
||||
|
||||
message GetNotificationRequest {
|
||||
// The current page of previous vulnerabilities for the ancestry.
|
||||
// This will be empty when it is the first page.
|
||||
string old_vulnerability_page = 1;
|
||||
// The current page of vulnerabilities for the ancestry.
|
||||
// This will be empty when it is the first page.
|
||||
string new_vulnerability_page = 2;
|
||||
// The requested maximum number of results per page.
|
||||
int32 limit = 3;
|
||||
// The name of the notification being requested.
|
||||
string name = 4;
|
||||
}
|
||||
|
||||
message GetNotificationResponse {
|
||||
message Notification {
|
||||
// The name of the requested notification.
|
||||
string name = 1;
|
||||
// The time at which the notification was created.
|
||||
string created = 2;
|
||||
// The time at which the notification was last sent out.
|
||||
string notified = 3;
|
||||
// The time at which a notification has been deleted.
|
||||
string deleted = 4;
|
||||
// The previous vulnerability and a paginated view of the ancestries it
|
||||
// affects.
|
||||
PagedVulnerableAncestries old = 5;
|
||||
// The newly updated vulnerability and a paginated view of the
|
||||
// ancestries it affects.
|
||||
PagedVulnerableAncestries new = 6;
|
||||
}
|
||||
// The notification as requested.
|
||||
Notification notification = 1;
|
||||
}
|
||||
|
||||
message PagedVulnerableAncestries {
|
||||
message IndexedAncestryName {
|
||||
// The index is an ever increasing number associated with the particular
|
||||
// ancestry. This is useful if you're processing notifications, and need
|
||||
// to keep track of the progress of paginating the results.
|
||||
int32 index = 1;
|
||||
// The name of the ancestry.
|
||||
string name = 2;
|
||||
}
|
||||
// The identifier for the current page.
|
||||
string current_page = 1;
|
||||
// The token used to request the next page.
|
||||
// This will be empty when there are no more pages.
|
||||
string next_page = 2;
|
||||
// The requested maximum number of results per page.
|
||||
int32 limit = 3;
|
||||
// The vulnerability that affects a given set of ancestries.
|
||||
Vulnerability vulnerability = 4;
|
||||
// The ancestries affected by a vulnerability.
|
||||
repeated IndexedAncestryName ancestries = 5;
|
||||
}
|
||||
|
||||
message MarkNotificationAsReadRequest {
|
||||
// The name of the Notification that has been processed.
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message MarkNotificationAsReadResponse {}
|
||||
|
||||
message GetStatusRequest {}
|
||||
|
||||
message GetStatusResponse {
|
||||
// The status of the current Clair instance.
|
||||
ClairStatus status = 1;
|
||||
}
|
488
vendor/github.com/coreos/clair/api/v3/clairpb/clair.swagger.json
generated
vendored
488
vendor/github.com/coreos/clair/api/v3/clairpb/clair.swagger.json
generated
vendored
|
@ -1,488 +0,0 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "api/v3/clairpb/clair.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/ancestry": {
|
||||
"post": {
|
||||
"summary": "The RPC used to create a new scan of an ancestry.",
|
||||
"operationId": "PostAncestry",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairPostAncestryResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairPostAncestryRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AncestryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/ancestry/{ancestry_name}": {
|
||||
"get": {
|
||||
"summary": "The RPC used to read the results of scanning for a particular ancestry.",
|
||||
"operationId": "GetAncestry",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairGetAncestryResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "ancestry_name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AncestryService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/notifications/{name}": {
|
||||
"get": {
|
||||
"summary": "The RPC used to get a particularly Notification.",
|
||||
"operationId": "GetNotification",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairGetNotificationResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "old_vulnerability_page",
|
||||
"description": "The current page of previous vulnerabilities for the ancestry.\nThis will be empty when it is the first page.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "new_vulnerability_page",
|
||||
"description": "The current page of vulnerabilities for the ancestry.\nThis will be empty when it is the first page.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"description": "The requested maximum number of results per page.",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"NotificationService"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"summary": "The RPC used to mark a Notification as read after it has been processed.",
|
||||
"operationId": "MarkNotificationAsRead",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairMarkNotificationAsReadResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"NotificationService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/status": {
|
||||
"get": {
|
||||
"summary": "The RPC used to show the internal state of current Clair instance.",
|
||||
"operationId": "GetStatus",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/clairGetStatusResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"StatusService"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"DetectorDType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DETECTOR_D_TYPE_INVALID",
|
||||
"DETECTOR_D_TYPE_NAMESPACE",
|
||||
"DETECTOR_D_TYPE_FEATURE"
|
||||
],
|
||||
"default": "DETECTOR_D_TYPE_INVALID"
|
||||
},
|
||||
"GetAncestryResponseAncestry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the desired ancestry."
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/GetAncestryResponseAncestryLayer"
|
||||
},
|
||||
"description": "The list of layers along with detected features in each."
|
||||
}
|
||||
}
|
||||
},
|
||||
"GetAncestryResponseAncestryLayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layer": {
|
||||
"$ref": "#/definitions/clairLayer",
|
||||
"description": "The layer's information."
|
||||
},
|
||||
"detected_features": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairFeature"
|
||||
},
|
||||
"description": "The features detected in this layer."
|
||||
}
|
||||
}
|
||||
},
|
||||
"GetNotificationResponseNotification": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the requested notification."
|
||||
},
|
||||
"created": {
|
||||
"type": "string",
|
||||
"description": "The time at which the notification was created."
|
||||
},
|
||||
"notified": {
|
||||
"type": "string",
|
||||
"description": "The time at which the notification was last sent out."
|
||||
},
|
||||
"deleted": {
|
||||
"type": "string",
|
||||
"description": "The time at which a notification has been deleted."
|
||||
},
|
||||
"old": {
|
||||
"$ref": "#/definitions/clairPagedVulnerableAncestries",
|
||||
"description": "The previous vulnerability and a paginated view of the ancestries it\naffects."
|
||||
},
|
||||
"new": {
|
||||
"$ref": "#/definitions/clairPagedVulnerableAncestries",
|
||||
"description": "The newly updated vulnerability and a paginated view of the\nancestries it affects."
|
||||
}
|
||||
}
|
||||
},
|
||||
"PagedVulnerableAncestriesIndexedAncestryName": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"index": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The index is an ever increasing number associated with the particular\nancestry. This is useful if you're processing notifications, and need\nto keep track of the progress of paginating the results."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the ancestry."
|
||||
}
|
||||
}
|
||||
},
|
||||
"PostAncestryRequestPostLayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hash": {
|
||||
"type": "string",
|
||||
"description": "The hash of the layer."
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The location of the layer (URL or file path)."
|
||||
},
|
||||
"headers": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Any HTTP Headers that need to be used if requesting a layer over\nHTTP(S)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairClairStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detectors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairDetector"
|
||||
},
|
||||
"title": "The implemented detectors in this Clair instance"
|
||||
},
|
||||
"last_update_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The time at which the updater last ran."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairDetector": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the detector."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the detector."
|
||||
},
|
||||
"dtype": {
|
||||
"$ref": "#/definitions/DetectorDType",
|
||||
"description": "The type of the detector."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairFeature": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the feature."
|
||||
},
|
||||
"namespace": {
|
||||
"$ref": "#/definitions/clairNamespace",
|
||||
"description": "The namespace in which the feature is detected."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The specific version of this feature."
|
||||
},
|
||||
"version_format": {
|
||||
"type": "string",
|
||||
"description": "The format used to parse version numbers for the feature."
|
||||
},
|
||||
"detector": {
|
||||
"$ref": "#/definitions/clairDetector",
|
||||
"description": "The detector used to detect this feature. This only exists when present\nin an Ancestry."
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairVulnerability"
|
||||
},
|
||||
"description": "The list of vulnerabilities that affect the feature."
|
||||
},
|
||||
"feature_type": {
|
||||
"type": "string",
|
||||
"description": "The feature type indicates if the feature represents a source package or\nbinary package."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairGetAncestryResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ancestry": {
|
||||
"$ref": "#/definitions/GetAncestryResponseAncestry",
|
||||
"description": "The ancestry requested."
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/clairClairStatus",
|
||||
"title": "The status of Clair at the time of the request"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairGetNotificationResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"notification": {
|
||||
"$ref": "#/definitions/GetNotificationResponseNotification",
|
||||
"description": "The notification as requested."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairGetStatusResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/clairClairStatus",
|
||||
"description": "The status of the current Clair instance."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairLayer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hash": {
|
||||
"type": "string",
|
||||
"description": "The sha256 tarsum for the layer."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairMarkNotificationAsReadResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"clairNamespace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the namespace."
|
||||
},
|
||||
"detector": {
|
||||
"$ref": "#/definitions/clairDetector",
|
||||
"description": "The detector used to detect the namespace. This only exists when present\nin an Ancestry Feature."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairPagedVulnerableAncestries": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"current_page": {
|
||||
"type": "string",
|
||||
"description": "The identifier for the current page."
|
||||
},
|
||||
"next_page": {
|
||||
"type": "string",
|
||||
"description": "The token used to request the next page.\nThis will be empty when there are no more pages."
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "The requested maximum number of results per page."
|
||||
},
|
||||
"vulnerability": {
|
||||
"$ref": "#/definitions/clairVulnerability",
|
||||
"description": "The vulnerability that affects a given set of ancestries."
|
||||
},
|
||||
"ancestries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PagedVulnerableAncestriesIndexedAncestryName"
|
||||
},
|
||||
"description": "The ancestries affected by a vulnerability."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairPostAncestryRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ancestry_name": {
|
||||
"type": "string",
|
||||
"description": "The name of the ancestry being scanned.\nIf scanning OCI images, this should be the hash of the manifest."
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "The format of the image being uploaded."
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PostAncestryRequestPostLayer"
|
||||
},
|
||||
"description": "The layers to be scanned for this Ancestry, ordered in the way that i th\nlayer is the parent of i + 1 th layer."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairPostAncestryResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/clairClairStatus",
|
||||
"description": "The status of Clair at the time of the request."
|
||||
}
|
||||
}
|
||||
},
|
||||
"clairVulnerability": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability."
|
||||
},
|
||||
"namespace_name": {
|
||||
"type": "string",
|
||||
"description": "The name of the namespace in which the vulnerability was detected."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of the vulnerability according to the source for the\nnamespace."
|
||||
},
|
||||
"link": {
|
||||
"type": "string",
|
||||
"description": "A link to the vulnerability according to the source for the namespace."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How dangerous the vulnerability is."
|
||||
},
|
||||
"metadata": {
|
||||
"type": "string",
|
||||
"description": "Namespace agnostic metadata about the vulnerability."
|
||||
},
|
||||
"fixed_by": {
|
||||
"type": "string",
|
||||
"description": "The feature that fixes this vulnerability.\nThis field only exists when a vulnerability is a part of a Feature."
|
||||
},
|
||||
"affected_versions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/clairFeature"
|
||||
},
|
||||
"description": "The Features that are affected by the vulnerability.\nThis field only exists when a vulnerability is a part of a Notification."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
vendor/github.com/coreos/clair/api/v3/clairpb/convert.go
generated
vendored
46
vendor/github.com/coreos/clair/api/v3/clairpb/convert.go
generated
vendored
|
@ -22,13 +22,6 @@ import (
|
|||
"github.com/coreos/clair/ext/versionfmt"
|
||||
)
|
||||
|
||||
// DatabaseDetectorTypeMapping maps the database detector type to the integer
|
||||
// enum proto.
|
||||
var DatabaseDetectorTypeMapping = map[database.DetectorType]Detector_DType{
|
||||
database.NamespaceDetectorType: Detector_DType(1),
|
||||
database.FeatureDetectorType: Detector_DType(2),
|
||||
}
|
||||
|
||||
// PagedVulnerableAncestriesFromDatabaseModel converts database
|
||||
// PagedVulnerableAncestries to api PagedVulnerableAncestries and assigns
|
||||
// indexes to ancestries.
|
||||
|
@ -99,7 +92,6 @@ func NotificationFromDatabaseModel(dbNotification database.VulnerabilityNotifica
|
|||
return ¬i, nil
|
||||
}
|
||||
|
||||
// VulnerabilityFromDatabaseModel converts database Vulnerability to api Vulnerability.
|
||||
func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability) (*Vulnerability, error) {
|
||||
metaString := ""
|
||||
if dbVuln.Metadata != nil {
|
||||
|
@ -120,7 +112,6 @@ func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability) (*Vulnerabili
|
|||
}, nil
|
||||
}
|
||||
|
||||
// VulnerabilityWithFixedInFromDatabaseModel converts database VulnerabilityWithFixedIn to api Vulnerability.
|
||||
func VulnerabilityWithFixedInFromDatabaseModel(dbVuln database.VulnerabilityWithFixedIn) (*Vulnerability, error) {
|
||||
vuln, err := VulnerabilityFromDatabaseModel(dbVuln.Vulnerability)
|
||||
if err != nil {
|
||||
|
@ -131,8 +122,14 @@ func VulnerabilityWithFixedInFromDatabaseModel(dbVuln database.VulnerabilityWith
|
|||
return vuln, nil
|
||||
}
|
||||
|
||||
// LayerFromDatabaseModel converts database layer to api layer.
|
||||
func LayerFromDatabaseModel(dbLayer database.LayerMetadata) *Layer {
|
||||
layer := Layer{Hash: dbLayer.Hash}
|
||||
return &layer
|
||||
}
|
||||
|
||||
// NamespacedFeatureFromDatabaseModel converts database namespacedFeature to api Feature.
|
||||
func NamespacedFeatureFromDatabaseModel(feature database.AncestryFeature) *Feature {
|
||||
func NamespacedFeatureFromDatabaseModel(feature database.NamespacedFeature) *Feature {
|
||||
version := feature.Feature.Version
|
||||
if version == versionfmt.MaxVersion {
|
||||
version = "None"
|
||||
|
@ -140,35 +137,8 @@ func NamespacedFeatureFromDatabaseModel(feature database.AncestryFeature) *Featu
|
|||
|
||||
return &Feature{
|
||||
Name: feature.Feature.Name,
|
||||
Namespace: &Namespace{
|
||||
Name: feature.Namespace.Name,
|
||||
Detector: DetectorFromDatabaseModel(feature.NamespaceBy),
|
||||
},
|
||||
NamespaceName: feature.Namespace.Name,
|
||||
VersionFormat: feature.Namespace.VersionFormat,
|
||||
Version: version,
|
||||
Detector: DetectorFromDatabaseModel(feature.FeatureBy),
|
||||
FeatureType: string(feature.Type),
|
||||
}
|
||||
}
|
||||
|
||||
// DetectorFromDatabaseModel converts database detector to api detector.
|
||||
func DetectorFromDatabaseModel(detector database.Detector) *Detector {
|
||||
if !detector.Valid() {
|
||||
return nil
|
||||
}
|
||||
return &Detector{
|
||||
Name: detector.Name,
|
||||
Version: detector.Version,
|
||||
Dtype: DatabaseDetectorTypeMapping[detector.DType],
|
||||
}
|
||||
}
|
||||
|
||||
// DetectorsFromDatabaseModel converts database detectors to api detectors.
|
||||
func DetectorsFromDatabaseModel(dbDetectors []database.Detector) []*Detector {
|
||||
detectors := make([]*Detector, 0, len(dbDetectors))
|
||||
for _, d := range dbDetectors {
|
||||
detectors = append(detectors, DetectorFromDatabaseModel(d))
|
||||
}
|
||||
|
||||
return detectors
|
||||
}
|
||||
|
|
28
vendor/github.com/coreos/clair/api/v3/clairpb/generate-protobuf.sh
generated
vendored
28
vendor/github.com/coreos/clair/api/v3/clairpb/generate-protobuf.sh
generated
vendored
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2018 clair 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
DOCKER_REPO_ROOT="$GOPATH/src/github.com/coreos/clair"
|
||||
IMAGE=${IMAGE:-"quay.io/coreos/clair-gen-proto"}
|
||||
|
||||
docker run --rm -it \
|
||||
-v "$DOCKER_REPO_ROOT":"$DOCKER_REPO_ROOT" \
|
||||
-w "$DOCKER_REPO_ROOT" \
|
||||
"$IMAGE" \
|
||||
"./api/v3/clairpb/run_in_docker.sh"
|
3
vendor/github.com/coreos/clair/api/v3/clairpb/prototool.yaml
generated
vendored
3
vendor/github.com/coreos/clair/api/v3/clairpb/prototool.yaml
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
protoc_version: 3.5.1
|
||||
protoc_includes:
|
||||
- ../../../vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis
|
29
vendor/github.com/coreos/clair/api/v3/clairpb/run_in_docker.sh
generated
vendored
29
vendor/github.com/coreos/clair/api/v3/clairpb/run_in_docker.sh
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2018 clair 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.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
protoc -I/usr/include -I. \
|
||||
-I"${GOPATH}/src" \
|
||||
-I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" \
|
||||
--go_out=plugins=grpc:. \
|
||||
--grpc-gateway_out=logtostderr=true:. \
|
||||
--swagger_out=logtostderr=true:. \
|
||||
./api/v3/clairpb/clair.proto
|
||||
|
||||
go generate .
|
96
vendor/github.com/coreos/clair/database/ancestry.go
generated
vendored
96
vendor/github.com/coreos/clair/database/ancestry.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
// Ancestry is a manifest that keeps all layers in an image in order.
|
||||
type Ancestry struct {
|
||||
// Name is a globally unique value for a set of layers. This is often the
|
||||
// sha256 digest of an OCI/Docker manifest.
|
||||
Name string `json:"name"`
|
||||
// By contains the processors that are used when computing the
|
||||
// content of this ancestry.
|
||||
By []Detector `json:"by"`
|
||||
// Layers should be ordered and i_th layer is the parent of i+1_th layer in
|
||||
// the slice.
|
||||
Layers []AncestryLayer `json:"layers"`
|
||||
}
|
||||
|
||||
// Valid checks if the ancestry is compliant to spec.
|
||||
func (a *Ancestry) Valid() bool {
|
||||
if a == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if a.Name == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, d := range a.By {
|
||||
if !d.Valid() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for _, l := range a.Layers {
|
||||
if !l.Valid() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AncestryLayer is a layer with all detected namespaced features.
|
||||
type AncestryLayer struct {
|
||||
// Hash is the sha-256 tarsum on the layer's blob content.
|
||||
Hash string `json:"hash"`
|
||||
// Features are the features introduced by this layer when it was
|
||||
// processed.
|
||||
Features []AncestryFeature `json:"features"`
|
||||
}
|
||||
|
||||
// Valid checks if the Ancestry Layer is compliant to the spec.
|
||||
func (l *AncestryLayer) Valid() bool {
|
||||
if l == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if l.Hash == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GetFeatures returns the Ancestry's features.
|
||||
func (l *AncestryLayer) GetFeatures() []NamespacedFeature {
|
||||
nsf := make([]NamespacedFeature, 0, len(l.Features))
|
||||
for _, f := range l.Features {
|
||||
nsf = append(nsf, f.NamespacedFeature)
|
||||
}
|
||||
|
||||
return nsf
|
||||
}
|
||||
|
||||
// AncestryFeature is a namespaced feature with the detectors used to
|
||||
// find this feature.
|
||||
type AncestryFeature struct {
|
||||
NamespacedFeature `json:"namespacedFeature"`
|
||||
|
||||
// FeatureBy is the detector that detected the feature.
|
||||
FeatureBy Detector `json:"featureBy"`
|
||||
// NamespaceBy is the detector that detected the namespace.
|
||||
NamespaceBy Detector `json:"namespaceBy"`
|
||||
}
|
57
vendor/github.com/coreos/clair/database/database.go
generated
vendored
57
vendor/github.com/coreos/clair/database/database.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019 clair authors
|
||||
// Copyright 2017 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -17,6 +17,7 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -26,20 +27,12 @@ import (
|
|||
var (
|
||||
// ErrBackendException is an error that occurs when the database backend
|
||||
// does not work properly (ie. unreachable).
|
||||
ErrBackendException = NewStorageError("an error occurred when querying the backend")
|
||||
ErrBackendException = errors.New("database: an error occurred when querying the backend")
|
||||
|
||||
// ErrInconsistent is an error that occurs when a database consistency check
|
||||
// fails (i.e. when an entity which is supposed to be unique is detected
|
||||
// twice)
|
||||
ErrInconsistent = NewStorageError("inconsistent database")
|
||||
|
||||
// ErrInvalidParameters is an error that occurs when the parameters are not valid.
|
||||
ErrInvalidParameters = NewStorageError("parameters are not valid")
|
||||
|
||||
// ErrMissingEntities is an error that occurs when an associated immutable
|
||||
// entity doesn't exist in the database. This error can indicate a wrong
|
||||
// implementation or corrupted database.
|
||||
ErrMissingEntities = NewStorageError("associated immutable entities are missing in the database")
|
||||
ErrInconsistent = errors.New("database: inconsistent database")
|
||||
)
|
||||
|
||||
// RegistrableComponentConfig is a configuration block that can be used to
|
||||
|
@ -106,9 +99,6 @@ type Session interface {
|
|||
// namespaced features. If the ancestry is not found, return false.
|
||||
FindAncestry(name string) (ancestry Ancestry, found bool, err error)
|
||||
|
||||
// PersistDetector inserts a slice of detectors if not in the database.
|
||||
PersistDetectors(detectors []Detector) error
|
||||
|
||||
// PersistFeatures inserts a set of features if not in the database.
|
||||
PersistFeatures(features []Feature) error
|
||||
|
||||
|
@ -130,10 +120,12 @@ type Session interface {
|
|||
// PersistNamespaces inserts a set of namespaces if not in the database.
|
||||
PersistNamespaces([]Namespace) error
|
||||
|
||||
// PersistLayer appends a layer's content in the database.
|
||||
// PersistLayer persists a layer's content in the database. The given
|
||||
// namespaces and features can be partial content of this layer.
|
||||
//
|
||||
// If any feature, namespace, or detector is not in the database, it returns not found error.
|
||||
PersistLayer(hash string, features []LayerFeature, namespaces []LayerNamespace, detectedBy []Detector) error
|
||||
// The layer, namespaces and features are expected to be already existing
|
||||
// in the database.
|
||||
PersistLayer(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error
|
||||
|
||||
// FindLayer returns a layer with all detected features and
|
||||
// namespaces.
|
||||
|
@ -165,8 +157,8 @@ type Session interface {
|
|||
// affected ancestries affected by old or new vulnerability.
|
||||
//
|
||||
// Because the number of affected ancestries maybe large, they are paginated
|
||||
// and their pages are specified by the pagination token, which should be
|
||||
// considered first page when it's empty.
|
||||
// and their pages are specified by the paination token, which, if empty, are
|
||||
// always considered first page.
|
||||
FindVulnerabilityNotification(name string, limit int, oldVulnerabilityPage pagination.Token, newVulnerabilityPage pagination.Token) (noti VulnerabilityNotificationWithVulnerable, found bool, err error)
|
||||
|
||||
// MarkNotificationAsRead marks a Notification as notified now, assuming
|
||||
|
@ -182,22 +174,23 @@ type Session interface {
|
|||
// FindKeyValue retrieves a value from the given key.
|
||||
FindKeyValue(key string) (value string, found bool, err error)
|
||||
|
||||
// AcquireLock acquires a brand new lock in the database with a given name
|
||||
// for the given duration.
|
||||
// Lock creates or renew a Lock in the database with the given name, owner
|
||||
// and duration.
|
||||
//
|
||||
// A lock can only have one owner.
|
||||
// This method should NOT block until a lock is acquired.
|
||||
AcquireLock(name, owner string, duration time.Duration) (acquired bool, expiration time.Time, err error)
|
||||
// After the specified duration, the Lock expires by itself if it hasn't been
|
||||
// unlocked, and thus, let other users create a Lock with the same name.
|
||||
// However, the owner can renew its Lock by setting renew to true.
|
||||
// Lock should not block, it should instead returns whether the Lock has been
|
||||
// successfully acquired/renewed. If it's the case, the expiration time of
|
||||
// that Lock is returned as well.
|
||||
Lock(name string, owner string, duration time.Duration, renew bool) (success bool, expiration time.Time, err error)
|
||||
|
||||
// ExtendLock extends an existing lock such that the lock will expire at the
|
||||
// current time plus the provided duration.
|
||||
//
|
||||
// This method should return immediately with an error if the lock does not
|
||||
// exist.
|
||||
ExtendLock(name, owner string, duration time.Duration) (extended bool, expiration time.Time, err error)
|
||||
// Unlock releases an existing Lock.
|
||||
Unlock(name, owner string) error
|
||||
|
||||
// ReleaseLock releases an existing lock.
|
||||
ReleaseLock(name, owner string) error
|
||||
// FindLock returns the owner of a Lock specified by the name, and its
|
||||
// expiration time if it exists.
|
||||
FindLock(name string) (owner string, expiration time.Time, found bool, err error)
|
||||
}
|
||||
|
||||
// Datastore represents a persistent data store
|
||||
|
|
538
vendor/github.com/coreos/clair/database/dbutil.go
generated
vendored
538
vendor/github.com/coreos/clair/database/dbutil.go
generated
vendored
|
@ -1,538 +0,0 @@
|
|||
// Copyright 2018 clair 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 database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/coreos/clair/pkg/commonerr"
|
||||
"github.com/coreos/clair/pkg/pagination"
|
||||
"github.com/deckarep/golang-set"
|
||||
)
|
||||
|
||||
// DeduplicateNamespaces deduplicates a list of namespaces.
|
||||
func DeduplicateNamespaces(namespaces ...Namespace) []Namespace {
|
||||
nsSet := mapset.NewSet()
|
||||
for _, ns := range namespaces {
|
||||
nsSet.Add(ns)
|
||||
}
|
||||
|
||||
uniqueNamespaces := make([]Namespace, 0, nsSet.Cardinality())
|
||||
for ns := range nsSet.Iter() {
|
||||
uniqueNamespaces = append(uniqueNamespaces, ns.(Namespace))
|
||||
}
|
||||
|
||||
return uniqueNamespaces
|
||||
}
|
||||
|
||||
// DeduplicateFeatures deduplicates a list of list of features.
|
||||
func DeduplicateFeatures(features ...Feature) []Feature {
|
||||
fSet := mapset.NewSet()
|
||||
for _, f := range features {
|
||||
fSet.Add(f)
|
||||
}
|
||||
|
||||
return ConvertFeatureSetToFeatures(fSet)
|
||||
}
|
||||
|
||||
// ConvertFeatureSetToFeatures converts a feature set to an array of features
|
||||
func ConvertFeatureSetToFeatures(features mapset.Set) []Feature {
|
||||
uniqueFeatures := make([]Feature, 0, features.Cardinality())
|
||||
for f := range features.Iter() {
|
||||
uniqueFeatures = append(uniqueFeatures, f.(Feature))
|
||||
}
|
||||
|
||||
return uniqueFeatures
|
||||
}
|
||||
|
||||
func ConvertFeatureSetToLayerFeatures(features mapset.Set) []LayerFeature {
|
||||
uniqueLayerFeatures := make([]LayerFeature, 0, features.Cardinality())
|
||||
for f := range features.Iter() {
|
||||
feature := f.(Feature)
|
||||
layerFeature := LayerFeature{
|
||||
Feature: feature,
|
||||
}
|
||||
uniqueLayerFeatures = append(uniqueLayerFeatures, layerFeature)
|
||||
}
|
||||
|
||||
return uniqueLayerFeatures
|
||||
}
|
||||
|
||||
// FindKeyValueAndRollback wraps session FindKeyValue function with begin and
|
||||
// roll back.
|
||||
func FindKeyValueAndRollback(datastore Datastore, key string) (value string, ok bool, err error) {
|
||||
var tx Session
|
||||
tx, err = datastore.Begin()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
value, ok, err = tx.FindKeyValue(key)
|
||||
return
|
||||
}
|
||||
|
||||
// PersistPartialLayerAndCommit wraps session PersistLayer function with begin and
|
||||
// commit.
|
||||
func PersistPartialLayerAndCommit(datastore Datastore, layer *Layer) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistLayer(layer.Hash, layer.Features, layer.Namespaces, layer.By); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// PersistFeaturesAndCommit wraps session PersistFeaturesAndCommit function with begin and commit.
|
||||
func PersistFeaturesAndCommit(datastore Datastore, features []Feature) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistFeatures(features); err != nil {
|
||||
serialized, _ := json.Marshal(features)
|
||||
log.WithError(err).WithField("feature", string(serialized)).Error("failed to store features")
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// PersistNamespacesAndCommit wraps session PersistNamespaces function with
|
||||
// begin and commit.
|
||||
func PersistNamespacesAndCommit(datastore Datastore, namespaces []Namespace) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.PersistNamespaces(namespaces); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// FindAncestryAndRollback wraps session FindAncestry function with begin and
|
||||
// rollback.
|
||||
func FindAncestryAndRollback(datastore Datastore, name string) (Ancestry, bool, error) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return Ancestry{}, false, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
return tx.FindAncestry(name)
|
||||
}
|
||||
|
||||
// FindLayerAndRollback wraps session FindLayer function with begin and rollback.
|
||||
func FindLayerAndRollback(datastore Datastore, hash string) (layer *Layer, ok bool, err error) {
|
||||
var tx Session
|
||||
if tx, err = datastore.Begin(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
// TODO(sidac): In order to make the session interface more idiomatic, we'll
|
||||
// return the pointer value in the future.
|
||||
var dereferencedLayer Layer
|
||||
dereferencedLayer, ok, err = tx.FindLayer(hash)
|
||||
layer = &dereferencedLayer
|
||||
return
|
||||
}
|
||||
|
||||
// DeduplicateNamespacedFeatures returns a copy of all unique features in the
|
||||
// input.
|
||||
func DeduplicateNamespacedFeatures(features []NamespacedFeature) []NamespacedFeature {
|
||||
nsSet := mapset.NewSet()
|
||||
for _, ns := range features {
|
||||
nsSet.Add(ns)
|
||||
}
|
||||
|
||||
uniqueFeatures := make([]NamespacedFeature, 0, nsSet.Cardinality())
|
||||
for ns := range nsSet.Iter() {
|
||||
uniqueFeatures = append(uniqueFeatures, ns.(NamespacedFeature))
|
||||
}
|
||||
|
||||
return uniqueFeatures
|
||||
}
|
||||
|
||||
// GetAncestryFeatures returns a list of unique namespaced features in the
|
||||
// ancestry.
|
||||
func GetAncestryFeatures(ancestry Ancestry) []NamespacedFeature {
|
||||
features := []NamespacedFeature{}
|
||||
for _, layer := range ancestry.Layers {
|
||||
features = append(features, layer.GetFeatures()...)
|
||||
}
|
||||
|
||||
return DeduplicateNamespacedFeatures(features)
|
||||
}
|
||||
|
||||
// UpsertAncestryAndCommit wraps session UpsertAncestry function with begin and commit.
|
||||
func UpsertAncestryAndCommit(datastore Datastore, ancestry *Ancestry) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = tx.UpsertAncestry(*ancestry); err != nil {
|
||||
log.WithError(err).Error("failed to upsert the ancestry")
|
||||
serialized, _ := json.Marshal(ancestry)
|
||||
log.Debug(string(serialized))
|
||||
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PersistNamespacedFeaturesAndCommit wraps session PersistNamespacedFeatures function
|
||||
// with begin and commit.
|
||||
func PersistNamespacedFeaturesAndCommit(datastore Datastore, features []NamespacedFeature) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.PersistNamespacedFeatures(features); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CacheRelatedVulnerabilityAndCommit wraps session CacheAffectedNamespacedFeatures
|
||||
// function with begin and commit.
|
||||
func CacheRelatedVulnerabilityAndCommit(datastore Datastore, features []NamespacedFeature) error {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.CacheAffectedNamespacedFeatures(features); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// IntersectDetectors returns the detectors in both d1 and d2.
|
||||
func IntersectDetectors(d1 []Detector, d2 []Detector) []Detector {
|
||||
d1Set := mapset.NewSet()
|
||||
for _, d := range d1 {
|
||||
d1Set.Add(d)
|
||||
}
|
||||
|
||||
d2Set := mapset.NewSet()
|
||||
for _, d := range d2 {
|
||||
d2Set.Add(d)
|
||||
}
|
||||
|
||||
inter := d1Set.Intersect(d2Set)
|
||||
detectors := make([]Detector, 0, inter.Cardinality())
|
||||
for d := range inter.Iter() {
|
||||
detectors = append(detectors, d.(Detector))
|
||||
}
|
||||
|
||||
return detectors
|
||||
}
|
||||
|
||||
// DiffDetectors returns the detectors belongs to d1 but not d2
|
||||
func DiffDetectors(d1 []Detector, d2 []Detector) []Detector {
|
||||
d1Set := mapset.NewSet()
|
||||
for _, d := range d1 {
|
||||
d1Set.Add(d)
|
||||
}
|
||||
|
||||
d2Set := mapset.NewSet()
|
||||
for _, d := range d2 {
|
||||
d2Set.Add(d)
|
||||
}
|
||||
|
||||
diff := d1Set.Difference(d2Set)
|
||||
detectors := make([]Detector, 0, diff.Cardinality())
|
||||
for d := range diff.Iter() {
|
||||
detectors = append(detectors, d.(Detector))
|
||||
}
|
||||
|
||||
return detectors
|
||||
}
|
||||
|
||||
// MergeLayers merges all content in new layer to l, where the content is
|
||||
// updated.
|
||||
func MergeLayers(l *Layer, new *Layer) *Layer {
|
||||
featureSet := mapset.NewSet()
|
||||
namespaceSet := mapset.NewSet()
|
||||
bySet := mapset.NewSet()
|
||||
|
||||
for _, f := range l.Features {
|
||||
featureSet.Add(f)
|
||||
}
|
||||
|
||||
for _, ns := range l.Namespaces {
|
||||
namespaceSet.Add(ns)
|
||||
}
|
||||
|
||||
for _, d := range l.By {
|
||||
bySet.Add(d)
|
||||
}
|
||||
|
||||
for _, feature := range new.Features {
|
||||
if !featureSet.Contains(feature) {
|
||||
l.Features = append(l.Features, feature)
|
||||
featureSet.Add(feature)
|
||||
}
|
||||
}
|
||||
|
||||
for _, namespace := range new.Namespaces {
|
||||
if !namespaceSet.Contains(namespace) {
|
||||
l.Namespaces = append(l.Namespaces, namespace)
|
||||
namespaceSet.Add(namespace)
|
||||
}
|
||||
}
|
||||
|
||||
for _, detector := range new.By {
|
||||
if !bySet.Contains(detector) {
|
||||
l.By = append(l.By, detector)
|
||||
bySet.Add(detector)
|
||||
}
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// AcquireLock acquires a named global lock for a duration.
|
||||
func AcquireLock(datastore Datastore, name, owner string, duration time.Duration) (acquired bool, expiration time.Time) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
locked, t, err := tx.AcquireLock(name, owner, duration)
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
|
||||
if locked {
|
||||
if err := tx.Commit(); err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
}
|
||||
|
||||
return locked, t
|
||||
}
|
||||
|
||||
// ExtendLock extends the duration of an existing global lock for the given
|
||||
// duration.
|
||||
func ExtendLock(ds Datastore, name, whoami string, desiredLockDuration time.Duration) (bool, time.Time) {
|
||||
tx, err := ds.Begin()
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
locked, expiration, err := tx.ExtendLock(name, whoami, desiredLockDuration)
|
||||
if err != nil {
|
||||
return false, time.Time{}
|
||||
}
|
||||
|
||||
if locked {
|
||||
if err := tx.Commit(); err == nil {
|
||||
return locked, expiration
|
||||
}
|
||||
}
|
||||
|
||||
return false, time.Time{}
|
||||
}
|
||||
|
||||
// ReleaseLock releases a named global lock.
|
||||
func ReleaseLock(datastore Datastore, name, owner string) {
|
||||
tx, err := datastore.Begin()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.ReleaseLock(name, owner); err != nil {
|
||||
return
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// PersistDetectorsAndCommit stores the detectors in the data store.
|
||||
func PersistDetectorsAndCommit(store Datastore, detectors []Detector) error {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
if err := tx.PersistDetectors(detectors); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkNotificationAsReadAndCommit marks a notification as read.
|
||||
func MarkNotificationAsReadAndCommit(store Datastore, name string) (bool, error) {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
err = tx.DeleteNotification(name)
|
||||
if err == commonerr.ErrNotFound {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// FindAffectedNamespacedFeaturesAndRollback finds the vulnerabilities on each
|
||||
// feature.
|
||||
func FindAffectedNamespacedFeaturesAndRollback(store Datastore, features []NamespacedFeature) ([]NullableAffectedNamespacedFeature, error) {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
nullableFeatures, err := tx.FindAffectedNamespacedFeatures(features)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nullableFeatures, nil
|
||||
}
|
||||
|
||||
// FindVulnerabilityNotificationAndRollback finds the vulnerability notification
|
||||
// and rollback.
|
||||
func FindVulnerabilityNotificationAndRollback(store Datastore, name string, limit int, oldVulnerabilityPage pagination.Token, newVulnerabilityPage pagination.Token) (VulnerabilityNotificationWithVulnerable, bool, error) {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return VulnerabilityNotificationWithVulnerable{}, false, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
return tx.FindVulnerabilityNotification(name, limit, oldVulnerabilityPage, newVulnerabilityPage)
|
||||
}
|
||||
|
||||
// FindNewNotification finds notifications either never notified or notified
|
||||
// before the given time.
|
||||
func FindNewNotification(store Datastore, notifiedBefore time.Time) (NotificationHook, bool, error) {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return NotificationHook{}, false, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
return tx.FindNewNotification(notifiedBefore)
|
||||
}
|
||||
|
||||
// UpdateKeyValueAndCommit stores the key value to storage.
|
||||
func UpdateKeyValueAndCommit(store Datastore, key, value string) error {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
if err = tx.UpdateKeyValue(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// InsertVulnerabilityNotificationsAndCommit inserts the notifications into db
|
||||
// and commit.
|
||||
func InsertVulnerabilityNotificationsAndCommit(store Datastore, notifications []VulnerabilityNotification) error {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.InsertVulnerabilityNotifications(notifications); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// FindVulnerabilitiesAndRollback finds the vulnerabilities based on given ids.
|
||||
func FindVulnerabilitiesAndRollback(store Datastore, ids []VulnerabilityID) ([]NullableVulnerability, error) {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
return tx.FindVulnerabilities(ids)
|
||||
}
|
||||
|
||||
func UpdateVulnerabilitiesAndCommit(store Datastore, toRemove []VulnerabilityID, toAdd []VulnerabilityWithAffected) error {
|
||||
tx, err := store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.DeleteVulnerabilities(toRemove); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.InsertVulnerabilities(toAdd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
144
vendor/github.com/coreos/clair/database/detector.go
generated
vendored
144
vendor/github.com/coreos/clair/database/detector.go
generated
vendored
|
@ -1,144 +0,0 @@
|
|||
// Copyright 2018 clair 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 database
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// NamespaceDetectorType is a type of detector that extracts the namespaces.
|
||||
NamespaceDetectorType DetectorType = "namespace"
|
||||
// FeatureDetectorType is a type of detector that extracts the features.
|
||||
FeatureDetectorType DetectorType = "feature"
|
||||
)
|
||||
|
||||
// DetectorTypes contains all detector types.
|
||||
var (
|
||||
DetectorTypes = []DetectorType{
|
||||
NamespaceDetectorType,
|
||||
FeatureDetectorType,
|
||||
}
|
||||
// ErrFailedToParseDetectorType is the error returned when a detector type could
|
||||
// not be parsed from a string.
|
||||
ErrFailedToParseDetectorType = errors.New("failed to parse DetectorType from input")
|
||||
// ErrInvalidDetector is the error returned when a detector from database has
|
||||
// invalid name or version or type.
|
||||
ErrInvalidDetector = errors.New("the detector has invalid metadata")
|
||||
)
|
||||
|
||||
// DetectorType is the type of a detector.
|
||||
type DetectorType string
|
||||
|
||||
// Value implements the database/sql/driver.Valuer interface.
|
||||
func (s DetectorType) Value() (driver.Value, error) {
|
||||
return string(s), nil
|
||||
}
|
||||
|
||||
// Scan implements the database/sql.Scanner interface.
|
||||
func (s *DetectorType) Scan(value interface{}) error {
|
||||
val, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New("could not scan a Severity from a non-string input")
|
||||
}
|
||||
|
||||
var err error
|
||||
*s, err = NewDetectorType(string(val))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewDetectorType attempts to parse a string into a standard DetectorType
|
||||
// value.
|
||||
func NewDetectorType(s string) (DetectorType, error) {
|
||||
for _, ss := range DetectorTypes {
|
||||
if strings.EqualFold(s, string(ss)) {
|
||||
return ss, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", ErrFailedToParseDetectorType
|
||||
}
|
||||
|
||||
// Valid checks if a detector type is defined.
|
||||
func (s DetectorType) Valid() bool {
|
||||
for _, t := range DetectorTypes {
|
||||
if s == t {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Detector is an versioned Clair extension.
|
||||
type Detector struct {
|
||||
// Name of an extension should be non-empty and uniquely identifies the
|
||||
// extension.
|
||||
Name string `json:"name"`
|
||||
// Version of an extension should be non-empty.
|
||||
Version string `json:"version"`
|
||||
// DType is the type of the extension and should be one of the types in
|
||||
// DetectorTypes.
|
||||
DType DetectorType `json:"dtype"`
|
||||
}
|
||||
|
||||
// Valid checks if all fields in the detector satisfies the spec.
|
||||
func (d Detector) Valid() bool {
|
||||
if d.Name == "" || d.Version == "" || !d.DType.Valid() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// String returns a unique string representation of the detector.
|
||||
func (d Detector) String() string {
|
||||
return fmt.Sprintf("%s:%s", d.Name, d.Version)
|
||||
}
|
||||
|
||||
// NewNamespaceDetector returns a new namespace detector.
|
||||
func NewNamespaceDetector(name, version string) Detector {
|
||||
return Detector{
|
||||
Name: name,
|
||||
Version: version,
|
||||
DType: NamespaceDetectorType,
|
||||
}
|
||||
}
|
||||
|
||||
// NewFeatureDetector returns a new feature detector.
|
||||
func NewFeatureDetector(name, version string) Detector {
|
||||
return Detector{
|
||||
Name: name,
|
||||
Version: version,
|
||||
DType: FeatureDetectorType,
|
||||
}
|
||||
}
|
||||
|
||||
// SerializeDetectors returns the string representation of given detectors.
|
||||
func SerializeDetectors(detectors []Detector) []string {
|
||||
strDetectors := []string{}
|
||||
for _, d := range detectors {
|
||||
strDetectors = append(strDetectors, d.String())
|
||||
}
|
||||
|
||||
return strDetectors
|
||||
}
|
35
vendor/github.com/coreos/clair/database/error.go
generated
vendored
35
vendor/github.com/coreos/clair/database/error.go
generated
vendored
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
// StorageError is database error
|
||||
type StorageError struct {
|
||||
reason string
|
||||
original error
|
||||
}
|
||||
|
||||
func (e *StorageError) Error() string {
|
||||
return e.reason
|
||||
}
|
||||
|
||||
// NewStorageErrorWithInternalError creates a new database error
|
||||
func NewStorageErrorWithInternalError(reason string, originalError error) *StorageError {
|
||||
return &StorageError{reason, originalError}
|
||||
}
|
||||
|
||||
// NewStorageError creates a new database error
|
||||
func NewStorageError(reason string) *StorageError {
|
||||
return &StorageError{reason, nil}
|
||||
}
|
96
vendor/github.com/coreos/clair/database/feature.go
generated
vendored
96
vendor/github.com/coreos/clair/database/feature.go
generated
vendored
|
@ -1,96 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
// Feature represents a package detected in a layer but the namespace is not
|
||||
// determined.
|
||||
//
|
||||
// e.g. Name: Libssl1.0, Version: 1.0, VersionFormat: dpkg, Type: binary
|
||||
// dpkg is the version format of the installer package manager, which in this
|
||||
// case could be dpkg or apk.
|
||||
type Feature struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
VersionFormat string `json:"versionFormat"`
|
||||
Type FeatureType `json:"type"`
|
||||
}
|
||||
|
||||
// NamespacedFeature is a feature with determined namespace and can be affected
|
||||
// by vulnerabilities.
|
||||
//
|
||||
// e.g. OpenSSL 1.0 dpkg Debian:7.
|
||||
type NamespacedFeature struct {
|
||||
Feature `json:"feature"`
|
||||
|
||||
Namespace Namespace `json:"namespace"`
|
||||
}
|
||||
|
||||
// AffectedNamespacedFeature is a namespaced feature affected by the
|
||||
// vulnerabilities with fixed-in versions for this feature.
|
||||
type AffectedNamespacedFeature struct {
|
||||
NamespacedFeature
|
||||
|
||||
AffectedBy []VulnerabilityWithFixedIn
|
||||
}
|
||||
|
||||
// VulnerabilityWithFixedIn is used for AffectedNamespacedFeature to retrieve
|
||||
// the affecting vulnerabilities and the fixed-in versions for the feature.
|
||||
type VulnerabilityWithFixedIn struct {
|
||||
Vulnerability
|
||||
|
||||
FixedInVersion string
|
||||
}
|
||||
|
||||
// AffectedFeature is used to determine whether a namespaced feature is affected
|
||||
// by a Vulnerability. Namespace and Feature Name is unique. Affected Feature is
|
||||
// bound to vulnerability.
|
||||
type AffectedFeature struct {
|
||||
// FeatureType determines which type of package it affects.
|
||||
FeatureType FeatureType
|
||||
Namespace Namespace
|
||||
FeatureName string
|
||||
// FixedInVersion is known next feature version that's not affected by the
|
||||
// vulnerability. Empty FixedInVersion means the unaffected version is
|
||||
// unknown.
|
||||
FixedInVersion string
|
||||
// AffectedVersion contains the version range to determine whether or not a
|
||||
// feature is affected.
|
||||
AffectedVersion string
|
||||
}
|
||||
|
||||
// NullableAffectedNamespacedFeature is an affectednamespacedfeature with
|
||||
// whether it's found in datastore.
|
||||
type NullableAffectedNamespacedFeature struct {
|
||||
AffectedNamespacedFeature
|
||||
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func NewFeature(name string, version string, versionFormat string, featureType FeatureType) *Feature {
|
||||
return &Feature{name, version, versionFormat, featureType}
|
||||
}
|
||||
|
||||
func NewBinaryPackage(name string, version string, versionFormat string) *Feature {
|
||||
return &Feature{name, version, versionFormat, BinaryPackage}
|
||||
}
|
||||
|
||||
func NewSourcePackage(name string, version string, versionFormat string) *Feature {
|
||||
return &Feature{name, version, versionFormat, SourcePackage}
|
||||
}
|
||||
|
||||
func NewNamespacedFeature(namespace *Namespace, feature *Feature) *NamespacedFeature {
|
||||
// TODO: namespaced feature should use pointer values
|
||||
return &NamespacedFeature{*feature, *namespace}
|
||||
}
|
52
vendor/github.com/coreos/clair/database/feature_type.go
generated
vendored
52
vendor/github.com/coreos/clair/database/feature_type.go
generated
vendored
|
@ -1,52 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FeatureType indicates the type of feature that a vulnerability
|
||||
// affects.
|
||||
type FeatureType string
|
||||
|
||||
const (
|
||||
SourcePackage FeatureType = "source"
|
||||
BinaryPackage FeatureType = "binary"
|
||||
)
|
||||
|
||||
var featureTypes = []FeatureType{
|
||||
SourcePackage,
|
||||
BinaryPackage,
|
||||
}
|
||||
|
||||
// Scan implements the database/sql.Scanner interface.
|
||||
func (t *FeatureType) Scan(value interface{}) error {
|
||||
val := value.(string)
|
||||
for _, ft := range featureTypes {
|
||||
if string(ft) == val {
|
||||
*t = ft
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("invalid feature type received from database: '%s'", val))
|
||||
}
|
||||
|
||||
// Value implements the database/sql/driver.Valuer interface.
|
||||
func (t *FeatureType) Value() (driver.Value, error) {
|
||||
return string(*t), nil
|
||||
}
|
65
vendor/github.com/coreos/clair/database/layer.go
generated
vendored
65
vendor/github.com/coreos/clair/database/layer.go
generated
vendored
|
@ -1,65 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
// Layer is a layer with all the detected features and namespaces.
|
||||
type Layer struct {
|
||||
// Hash is the sha-256 tarsum on the layer's blob content.
|
||||
Hash string `json:"hash"`
|
||||
// By contains a list of detectors scanned this Layer.
|
||||
By []Detector `json:"by"`
|
||||
Namespaces []LayerNamespace `json:"namespaces"`
|
||||
Features []LayerFeature `json:"features"`
|
||||
}
|
||||
|
||||
func (l *Layer) GetFeatures() []Feature {
|
||||
features := make([]Feature, 0, len(l.Features))
|
||||
for _, f := range l.Features {
|
||||
features = append(features, f.Feature)
|
||||
}
|
||||
|
||||
return features
|
||||
}
|
||||
|
||||
func (l *Layer) GetNamespaces() []Namespace {
|
||||
namespaces := make([]Namespace, 0, len(l.Namespaces)+len(l.Features))
|
||||
for _, ns := range l.Namespaces {
|
||||
namespaces = append(namespaces, ns.Namespace)
|
||||
}
|
||||
for _, f := range l.Features {
|
||||
if f.PotentialNamespace.Valid() {
|
||||
namespaces = append(namespaces, f.PotentialNamespace)
|
||||
}
|
||||
}
|
||||
|
||||
return namespaces
|
||||
}
|
||||
|
||||
// LayerNamespace is a namespace with detection information.
|
||||
type LayerNamespace struct {
|
||||
Namespace `json:"namespace"`
|
||||
|
||||
// By is the detector found the namespace.
|
||||
By Detector `json:"by"`
|
||||
}
|
||||
|
||||
// LayerFeature is a feature with detection information.
|
||||
type LayerFeature struct {
|
||||
Feature `json:"feature"`
|
||||
|
||||
// By is the detector found the feature.
|
||||
By Detector `json:"by"`
|
||||
PotentialNamespace Namespace `json:"potentialNamespace"`
|
||||
}
|
41
vendor/github.com/coreos/clair/database/metadata.go
generated
vendored
41
vendor/github.com/coreos/clair/database/metadata.go
generated
vendored
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2019 clair 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 database
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// MetadataMap is for storing the metadata returned by vulnerability database.
|
||||
type MetadataMap map[string]interface{}
|
||||
|
||||
func (mm *MetadataMap) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// github.com/lib/pq decodes TEXT/VARCHAR fields into strings.
|
||||
val, ok := value.(string)
|
||||
if !ok {
|
||||
panic("got type other than []byte from database")
|
||||
}
|
||||
return json.Unmarshal([]byte(val), mm)
|
||||
}
|
||||
|
||||
func (mm *MetadataMap) Value() (driver.Value, error) {
|
||||
json, err := json.Marshal(*mm)
|
||||
return string(json), err
|
||||
}
|
38
vendor/github.com/coreos/clair/database/mock.go
generated
vendored
38
vendor/github.com/coreos/clair/database/mock.go
generated
vendored
|
@ -30,10 +30,9 @@ type MockSession struct {
|
|||
FctFindAffectedNamespacedFeatures func(features []NamespacedFeature) ([]NullableAffectedNamespacedFeature, error)
|
||||
FctPersistNamespaces func([]Namespace) error
|
||||
FctPersistFeatures func([]Feature) error
|
||||
FctPersistDetectors func(detectors []Detector) error
|
||||
FctPersistNamespacedFeatures func([]NamespacedFeature) error
|
||||
FctCacheAffectedNamespacedFeatures func([]NamespacedFeature) error
|
||||
FctPersistLayer func(hash string, features []LayerFeature, namespaces []LayerNamespace, by []Detector) error
|
||||
FctPersistLayer func(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error
|
||||
FctFindLayer func(name string) (Layer, bool, error)
|
||||
FctInsertVulnerabilities func([]VulnerabilityWithAffected) error
|
||||
FctFindVulnerabilities func([]VulnerabilityID) ([]NullableVulnerability, error)
|
||||
|
@ -46,9 +45,9 @@ type MockSession struct {
|
|||
FctDeleteNotification func(name string) error
|
||||
FctUpdateKeyValue func(key, value string) error
|
||||
FctFindKeyValue func(key string) (string, bool, error)
|
||||
FctAcquireLock func(name, owner string, duration time.Duration) (bool, time.Time, error)
|
||||
FctExtendLock func(name, owner string, duration time.Duration) (bool, time.Time, error)
|
||||
FctReleaseLock func(name, owner string) error
|
||||
FctLock func(name string, owner string, duration time.Duration, renew bool) (bool, time.Time, error)
|
||||
FctUnlock func(name, owner string) error
|
||||
FctFindLock func(name string) (string, time.Time, bool, error)
|
||||
}
|
||||
|
||||
func (ms *MockSession) Commit() error {
|
||||
|
@ -86,13 +85,6 @@ func (ms *MockSession) FindAffectedNamespacedFeatures(features []NamespacedFeatu
|
|||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistDetectors(detectors []Detector) error {
|
||||
if ms.FctPersistDetectors != nil {
|
||||
return ms.FctPersistDetectors(detectors)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistNamespaces(namespaces []Namespace) error {
|
||||
if ms.FctPersistNamespaces != nil {
|
||||
return ms.FctPersistNamespaces(namespaces)
|
||||
|
@ -121,9 +113,9 @@ func (ms *MockSession) CacheAffectedNamespacedFeatures(namespacedFeatures []Name
|
|||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) PersistLayer(hash string, features []LayerFeature, namespaces []LayerNamespace, detectors []Detector) error {
|
||||
func (ms *MockSession) PersistLayer(hash string, namespaces []Namespace, features []Feature, processedBy Processors) error {
|
||||
if ms.FctPersistLayer != nil {
|
||||
return ms.FctPersistLayer(hash, features, namespaces, detectors)
|
||||
return ms.FctPersistLayer(hash, namespaces, features, processedBy)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
@ -206,23 +198,23 @@ func (ms *MockSession) FindKeyValue(key string) (string, bool, error) {
|
|||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) AcquireLock(name, owner string, duration time.Duration) (bool, time.Time, error) {
|
||||
if ms.FctAcquireLock != nil {
|
||||
return ms.FctAcquireLock(name, owner, duration)
|
||||
func (ms *MockSession) Lock(name string, owner string, duration time.Duration, renew bool) (bool, time.Time, error) {
|
||||
if ms.FctLock != nil {
|
||||
return ms.FctLock(name, owner, duration, renew)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) ExtendLock(name, owner string, duration time.Duration) (bool, time.Time, error) {
|
||||
if ms.FctExtendLock != nil {
|
||||
return ms.FctExtendLock(name, owner, duration)
|
||||
func (ms *MockSession) Unlock(name, owner string) error {
|
||||
if ms.FctUnlock != nil {
|
||||
return ms.FctUnlock(name, owner)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
||||
func (ms *MockSession) ReleaseLock(name, owner string) error {
|
||||
if ms.FctReleaseLock != nil {
|
||||
return ms.FctReleaseLock(name, owner)
|
||||
func (ms *MockSession) FindLock(name string) (string, time.Time, bool, error) {
|
||||
if ms.FctFindLock != nil {
|
||||
return ms.FctFindLock(name)
|
||||
}
|
||||
panic("required mock function not implemented")
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue