mirror of
https://github.com/crazy-max/diun.git
synced 2025-12-21 13:23:09 +01:00
Add CLI to interact with Diun through gRPC (#382)
Add simple CLI to interact with Diun through gRPC Create image and notif proto services Compile and validate protos through a dedicated Dockerfile and bake target Implement proto definitions Move server as `serve` command New commands `image` and `notif` Refactor command line usage doc Better CLI error handling Tools build constraint to manage tools deps through go modules Add upgrade notes Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -25,6 +25,21 @@ env:
|
||||
GHCR_SLUG: ghcr.io/crazy-max/diun
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Validate
|
||||
uses: docker/bake-action@v1
|
||||
with:
|
||||
targets: validate
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -49,7 +64,9 @@ jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ test ]
|
||||
needs:
|
||||
- validate
|
||||
- test
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
|
||||
28
.github/workflows/validate.yml
vendored
28
.github/workflows/validate.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: validate
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
tags:
|
||||
- 'v*'
|
||||
- 'dockerfile/*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Validate
|
||||
uses: docker/bake-action@v1
|
||||
with:
|
||||
targets: validate
|
||||
@@ -18,7 +18,7 @@ RUN --mount=type=bind,target=/src,rw \
|
||||
--dist "/out" \
|
||||
--hooks="go mod tidy" \
|
||||
--hooks="go mod download" \
|
||||
--main="./cmd/main.go" \
|
||||
--main="./cmd" \
|
||||
--ldflags="-s -w -X 'main.version={{.Version}}'" \
|
||||
--files="CHANGELOG.md" \
|
||||
--files="LICENSE" \
|
||||
@@ -44,3 +44,4 @@ ENV PROFILER_PATH="/profiler" \
|
||||
|
||||
VOLUME [ "/data" ]
|
||||
ENTRYPOINT [ "diun" ]
|
||||
CMD [ "serve" ]
|
||||
|
||||
34
cmd/cli.go
Normal file
34
cmd/cli.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// CliHandler is a cli interface
|
||||
type CliHandler interface {
|
||||
BeforeApply() error
|
||||
}
|
||||
|
||||
// CliGlobals holds globals cli attributes
|
||||
type CliGlobals struct {
|
||||
CliHandler `kong:"-"`
|
||||
|
||||
conn *grpc.ClientConn `kong:"-"`
|
||||
imageSvc pb.ImageServiceClient `kong:"-"`
|
||||
notifSvc pb.NotifServiceClient `kong:"-"`
|
||||
|
||||
GRPCAuthority string `kong:"name='grpc-authority',default='127.0.0.1:42286',help='Link to Diun gRPC API.'"`
|
||||
}
|
||||
|
||||
// BeforeApply is a hook that run cli cmd are executed.
|
||||
func (s *CliGlobals) BeforeApply() (err error) {
|
||||
s.conn, err = grpc.Dial(s.GRPCAuthority, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.imageSvc = pb.NewImageServiceClient(s.conn)
|
||||
s.notifSvc = pb.NewNotifServiceClient(s.conn)
|
||||
return
|
||||
}
|
||||
131
cmd/image.go
Normal file
131
cmd/image.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"github.com/tidwall/pretty"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
// ImageCmd holds image command
|
||||
type ImageCmd struct {
|
||||
List ImageListCmd `kong:"cmd,default='1',help='List images in database.'"`
|
||||
Inspect ImageInspectCmd `kong:"cmd,help='Display information of an image in database.'"`
|
||||
Remove ImageRemoveCmd `kong:"cmd,help='Remove an image manifest from database.'"`
|
||||
//Prune ImagePruneCmd `kong:"cmd,help='Remove unused manifests from the database.'"`
|
||||
}
|
||||
|
||||
// ImageListCmd holds image list command
|
||||
type ImageListCmd struct {
|
||||
CliGlobals
|
||||
Raw bool `kong:"name='raw',default='false',help='JSON output.'"`
|
||||
}
|
||||
|
||||
func (s *ImageListCmd) Run(ctx *Context) error {
|
||||
defer s.conn.Close()
|
||||
|
||||
il, err := s.imageSvc.ImageList(context.Background(), &pb.ImageListRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.Slice(il.Images, func(i, j int) bool {
|
||||
return strings.Map(unicode.ToUpper, il.Images[i].Name) < strings.Map(unicode.ToUpper, il.Images[j].Name)
|
||||
})
|
||||
|
||||
if s.Raw {
|
||||
b, _ := protojson.Marshal(il)
|
||||
fmt.Println(string(pretty.Pretty(b)))
|
||||
return nil
|
||||
}
|
||||
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(os.Stdout)
|
||||
t.AppendHeader(table.Row{"Name", "Manifests Count", "Latest Tag", "Latest Created", "Latest Digest"})
|
||||
for _, image := range il.Images {
|
||||
t.AppendRow(table.Row{image.Name, image.ManifestsCount, image.Latest.Tag, image.Latest.Created.AsTime().Format(time.RFC3339), image.Latest.Digest})
|
||||
}
|
||||
t.AppendFooter(table.Row{"Total", len(il.Images)})
|
||||
t.Render()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ImageInspectCmd holds image inspect command
|
||||
type ImageInspectCmd struct {
|
||||
CliGlobals
|
||||
Image string `kong:"name='image',required,help='Image to inspect.'"`
|
||||
Raw bool `kong:"name='raw',default='false',help='JSON output.'"`
|
||||
}
|
||||
|
||||
func (s *ImageInspectCmd) Run(ctx *Context) error {
|
||||
defer s.conn.Close()
|
||||
|
||||
ii, err := s.imageSvc.ImageInspect(context.Background(), &pb.ImageInspectRequest{
|
||||
Name: s.Image,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.Slice(ii.Image.Manifests, func(i, j int) bool {
|
||||
return ii.Image.Manifests[i].Created.AsTime().After(ii.Image.Manifests[j].Created.AsTime())
|
||||
})
|
||||
|
||||
if s.Raw {
|
||||
b, _ := protojson.Marshal(ii)
|
||||
fmt.Println(string(pretty.Pretty(b)))
|
||||
return nil
|
||||
}
|
||||
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(os.Stdout)
|
||||
t.AppendHeader(table.Row{"Tag", "Created", "Digest"})
|
||||
for _, image := range ii.Image.Manifests {
|
||||
t.AppendRow(table.Row{image.Tag, image.Created.AsTime().Format(time.RFC3339), image.Digest})
|
||||
}
|
||||
t.AppendFooter(table.Row{"Total", len(ii.Image.Manifests)})
|
||||
t.Render()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ImageRemoveCmd holds image remove command
|
||||
type ImageRemoveCmd struct {
|
||||
CliGlobals
|
||||
Image string `kong:"name='image',required,help='Image to remove.'"`
|
||||
All bool `kong:"name='all',default='false',help='Remove all manifests from the database.'"`
|
||||
}
|
||||
|
||||
func (s *ImageRemoveCmd) Run(ctx *Context) error {
|
||||
defer s.conn.Close()
|
||||
|
||||
removed, err := s.imageSvc.ImageRemove(context.Background(), &pb.ImageRemoveRequest{
|
||||
Name: s.Image,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(os.Stdout)
|
||||
t.AppendHeader(table.Row{"Tag", "Created", "Digest", "Size"})
|
||||
var totalSize int64
|
||||
for _, image := range removed.Manifests {
|
||||
t.AppendRow(table.Row{image.Tag, image.Created.AsTime().Format(time.RFC3339), image.Digest, units.HumanSize(float64(image.Size))})
|
||||
totalSize += image.Size
|
||||
}
|
||||
t.AppendFooter(table.Row{"Total", fmt.Sprintf("%d (%s)", len(removed.Manifests), units.HumanSize(float64(totalSize)))})
|
||||
t.Render()
|
||||
|
||||
return nil
|
||||
}
|
||||
104
cmd/main.go
104
cmd/main.go
@@ -3,48 +3,48 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
_ "time/tzdata"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/crazy-max/diun/v4/internal/app"
|
||||
"github.com/crazy-max/diun/v4/internal/config"
|
||||
"github.com/crazy-max/diun/v4/internal/logging"
|
||||
"github.com/crazy-max/diun/v4/internal/model"
|
||||
"github.com/pkg/profile"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
diun *app.Diun
|
||||
cli model.Cli
|
||||
version = "dev"
|
||||
meta = model.Meta{
|
||||
cli struct {
|
||||
Version kong.VersionFlag
|
||||
Serve ServeCmd `kong:"cmd,help='Starts Diun server.'"`
|
||||
Image ImageCmd `kong:"cmd,help='Manage image manifests.'"`
|
||||
Notif NotifCmd `kong:"cmd,help='Manage notifications.'"`
|
||||
}
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Meta model.Meta
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
meta := model.Meta{
|
||||
ID: "diun",
|
||||
Name: "Diun",
|
||||
Desc: "Docker image update notifier",
|
||||
URL: "https://github.com/crazy-max/diun",
|
||||
Logo: "https://raw.githubusercontent.com/crazy-max/diun/master/.res/diun.png",
|
||||
Author: "CrazyMax",
|
||||
Version: version,
|
||||
}
|
||||
)
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
meta.Version = version
|
||||
meta.UserAgent = fmt.Sprintf("%s/%s go/%s %s", meta.ID, meta.Version, runtime.Version()[2:], strings.Title(runtime.GOOS))
|
||||
if meta.Hostname, err = os.Hostname(); err != nil {
|
||||
log.Fatal().Err(err).Msg("Cannot resolve hostname")
|
||||
}
|
||||
|
||||
// Parse command line
|
||||
_ = kong.Parse(&cli,
|
||||
ctx := kong.Parse(&cli,
|
||||
kong.Name(meta.ID),
|
||||
kong.Description(fmt.Sprintf("%s. More info: %s", meta.Desc, meta.URL)),
|
||||
kong.UsageOnError(),
|
||||
@@ -56,69 +56,5 @@ func main() {
|
||||
Summary: true,
|
||||
}))
|
||||
|
||||
// Init
|
||||
logging.Configure(&cli)
|
||||
log.Info().Str("version", version).Msgf("Starting %s", meta.Name)
|
||||
|
||||
// Handle os signals
|
||||
channel := make(chan os.Signal)
|
||||
signal.Notify(channel, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
sig := <-channel
|
||||
diun.Close()
|
||||
log.Warn().Msgf("Caught signal %v", sig)
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// Load configuration
|
||||
cfg, err := config.Load(cli)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Cannot load configuration")
|
||||
}
|
||||
log.Debug().Msg(cfg.String())
|
||||
|
||||
// Profiler
|
||||
if len(cli.Profiler) > 0 && len(cli.ProfilerPath) > 0 {
|
||||
profilerPath := path.Clean(cli.ProfilerPath)
|
||||
if err = os.MkdirAll(profilerPath, os.ModePerm); err != nil {
|
||||
log.Fatal().Err(err).Msg("Cannot create profiler folder")
|
||||
}
|
||||
profilePath := profile.ProfilePath(profilerPath)
|
||||
switch cli.Profiler {
|
||||
case "cpu":
|
||||
defer profile.Start(profile.CPUProfile, profilePath).Stop()
|
||||
case "mem":
|
||||
defer profile.Start(profile.MemProfile, profilePath).Stop()
|
||||
case "alloc":
|
||||
defer profile.Start(profile.MemProfileAllocs, profilePath).Stop()
|
||||
case "heap":
|
||||
defer profile.Start(profile.MemProfileHeap, profilePath).Stop()
|
||||
case "routines":
|
||||
defer profile.Start(profile.GoroutineProfile, profilePath).Stop()
|
||||
case "mutex":
|
||||
defer profile.Start(profile.MutexProfile, profilePath).Stop()
|
||||
case "threads":
|
||||
defer profile.Start(profile.ThreadcreationProfile, profilePath).Stop()
|
||||
case "block":
|
||||
defer profile.Start(profile.BlockProfile, profilePath).Stop()
|
||||
default:
|
||||
log.Fatal().Msgf("Unknown profiler: %s", cli.Profiler)
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
if diun, err = app.New(meta, cli, cfg); err != nil {
|
||||
log.Fatal().Err(err).Msgf("Cannot initialize %s", meta.Name)
|
||||
}
|
||||
|
||||
// Test notif
|
||||
if cli.TestNotif {
|
||||
diun.TestNotif()
|
||||
return
|
||||
}
|
||||
|
||||
// Start
|
||||
if err = diun.Start(); err != nil {
|
||||
log.Fatal().Err(err).Msgf("Cannot start %s", meta.Name)
|
||||
}
|
||||
ctx.FatalIfErrorf(ctx.Run(&Context{Meta: meta}))
|
||||
}
|
||||
|
||||
30
cmd/notif.go
Normal file
30
cmd/notif.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
)
|
||||
|
||||
// NotifCmd holds notif command
|
||||
type NotifCmd struct {
|
||||
Test NotifTestCmd `kong:"cmd,help='Test notification settings.'"`
|
||||
}
|
||||
|
||||
// NotifTestCmd holds notif test command
|
||||
type NotifTestCmd struct {
|
||||
CliGlobals
|
||||
}
|
||||
|
||||
func (s *NotifTestCmd) Run(ctx *Context) error {
|
||||
defer s.conn.Close()
|
||||
|
||||
nt, err := s.notifSvc.NotifTest(context.Background(), &pb.NotifTestRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(nt.Message)
|
||||
return nil
|
||||
}
|
||||
99
cmd/serve.go
Normal file
99
cmd/serve.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/crazy-max/diun/v4/internal/app"
|
||||
"github.com/crazy-max/diun/v4/internal/config"
|
||||
"github.com/crazy-max/diun/v4/internal/logging"
|
||||
"github.com/pkg/profile"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// ServeCmd holds serve command args and flags
|
||||
type ServeCmd struct {
|
||||
Cfgfile string `kong:"name='config',env='CONFIG',help='Diun configuration file.'"`
|
||||
ProfilerPath string `kong:"name='profiler-path',env='PROFILER_PATH',help='Base path where profiling files are written.'"`
|
||||
Profiler string `kong:"name='profiler',env='PROFILER',help='Profiler to use.'"`
|
||||
LogLevel string `kong:"name='log-level',env='LOG_LEVEL',default='info',help='Set log level.'"`
|
||||
LogJSON bool `kong:"name='log-json',env='LOG_JSON',default='false',help='Enable JSON logging output.'"`
|
||||
LogCaller bool `kong:"name='log-caller',env='LOG_CALLER',default='false',help='Add file:line of the caller to log output.'"`
|
||||
LogNoColor bool `kong:"name='log-nocolor',env='LOG_NOCOLOR',default='false',help='Disables the colorized output.'"`
|
||||
GRPCAuthority string `kong:"name='grpc-authority',env='GRPC_AUTHORITY',default=':42286',help='Address used to expose the gRPC server.'"`
|
||||
}
|
||||
|
||||
func (s *ServeCmd) Run(ctx *Context) error {
|
||||
var diun *app.Diun
|
||||
|
||||
// Logging
|
||||
logging.Configure(logging.Options{
|
||||
LogLevel: s.LogLevel,
|
||||
LogJSON: s.LogJSON,
|
||||
LogCaller: s.LogCaller,
|
||||
LogNoColor: s.LogNoColor,
|
||||
})
|
||||
log.Info().Str("version", version).Msgf("Starting %s", ctx.Meta.Name)
|
||||
|
||||
// Handle os signals
|
||||
channel := make(chan os.Signal)
|
||||
signal.Notify(channel, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
sig := <-channel
|
||||
diun.Close()
|
||||
log.Warn().Msgf("Caught signal %v", sig)
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// Load configuration
|
||||
cfg, err := config.Load(s.Cfgfile)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Cannot load configuration")
|
||||
}
|
||||
log.Debug().Msg(cfg.String())
|
||||
|
||||
// Profiler
|
||||
if len(s.Profiler) > 0 && len(s.ProfilerPath) > 0 {
|
||||
profilerPath := path.Clean(s.ProfilerPath)
|
||||
if err = os.MkdirAll(profilerPath, os.ModePerm); err != nil {
|
||||
log.Fatal().Err(err).Msg("Cannot create profiler folder")
|
||||
}
|
||||
profilePath := profile.ProfilePath(profilerPath)
|
||||
switch s.Profiler {
|
||||
case "cpu":
|
||||
defer profile.Start(profile.CPUProfile, profilePath).Stop()
|
||||
case "mem":
|
||||
defer profile.Start(profile.MemProfile, profilePath).Stop()
|
||||
case "alloc":
|
||||
defer profile.Start(profile.MemProfileAllocs, profilePath).Stop()
|
||||
case "heap":
|
||||
defer profile.Start(profile.MemProfileHeap, profilePath).Stop()
|
||||
case "routines":
|
||||
defer profile.Start(profile.GoroutineProfile, profilePath).Stop()
|
||||
case "mutex":
|
||||
defer profile.Start(profile.MutexProfile, profilePath).Stop()
|
||||
case "threads":
|
||||
defer profile.Start(profile.ThreadcreationProfile, profilePath).Stop()
|
||||
case "block":
|
||||
defer profile.Start(profile.BlockProfile, profilePath).Stop()
|
||||
default:
|
||||
log.Fatal().Msgf("Unknown profiler: %s", s.Profiler)
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
diun, err = app.New(ctx.Meta, cfg, s.GRPCAuthority)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Cannot initialize %s", ctx.Meta.Name)
|
||||
}
|
||||
|
||||
// Start
|
||||
err = diun.Start()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Cannot start %s", ctx.Meta.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -9,6 +9,17 @@ target "go-version" {
|
||||
}
|
||||
}
|
||||
|
||||
// protoc version
|
||||
variable "PROTOC_VERSION" {
|
||||
default = "3.17.0"
|
||||
}
|
||||
|
||||
target "protoc-version" {
|
||||
args = {
|
||||
PROTOC_VERSION = PROTOC_VERSION
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub reference as defined in GitHub Actions (eg. refs/head/master))
|
||||
variable "GITHUB_REF" {
|
||||
default = ""
|
||||
@@ -30,7 +41,7 @@ group "default" {
|
||||
}
|
||||
|
||||
group "validate" {
|
||||
targets = ["lint", "vendor-validate"]
|
||||
targets = ["lint", "vendor-validate", "gen-validate"]
|
||||
}
|
||||
|
||||
target "lint" {
|
||||
@@ -52,6 +63,19 @@ target "vendor-update" {
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "gen-validate" {
|
||||
inherits = ["go-version", "protoc-version"]
|
||||
dockerfile = "./hack/gen.Dockerfile"
|
||||
target = "validate"
|
||||
}
|
||||
|
||||
target "gen-update" {
|
||||
inherits = ["go-version", "protoc-version"]
|
||||
dockerfile = "./hack/gen.Dockerfile"
|
||||
target = "update"
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "test" {
|
||||
inherits = ["go-version"]
|
||||
dockerfile = "./hack/test.Dockerfile"
|
||||
|
||||
@@ -22,7 +22,7 @@ At startup, Diun searches for a file named `diun.yml` (or `diun.yaml`) in:
|
||||
* `$HOME/.config/`
|
||||
* `.` _(the working directory)_
|
||||
|
||||
You can override this using the [`--config` flag or `CONFIG` env var](../usage/cli.md).
|
||||
You can override this using the [`--config` flag or `CONFIG` env var with `serve` command](../usage/command-line.md#serve).
|
||||
|
||||
??? example "diun.yml"
|
||||
```yaml
|
||||
|
||||
@@ -20,13 +20,11 @@ regopts:
|
||||
passwordFile: /run/secrets/password
|
||||
```
|
||||
|
||||
`myregistry` will be used as a `name` selector (default) if referenced by its [name](#name).
|
||||
|
||||
`docker.io` will be used as an `image` selector. If an image is on DockerHub (`docker.io` domain), this registry options will
|
||||
be selected if not referenced as a `regopt` name.
|
||||
|
||||
`docker.io/crazymax` will be used as an `image` selector. If an image is on DockerHub and in `crazymax` namespace, this registry options will
|
||||
be selected if not referenced as a `regopt` name.
|
||||
* `myregistry` will be used as a `name` selector (default) if referenced by its [name](#name).
|
||||
* `docker.io` will be used as an `image` selector. If an image is on DockerHub (`docker.io` domain), this registry
|
||||
options will be selected if not referenced as a `regopt` name.
|
||||
* `docker.io/crazymax` will be used as an `image` selector. If an image is on DockerHub and in `crazymax` namespace,
|
||||
this registry options will be selected if not referenced as a `regopt` name.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Send notification at the very first analysis of an image. (default `false`)
|
||||
### `compareDigest`
|
||||
|
||||
Compare the digest of an image with the registry before downloading the image manifest. It is strongly
|
||||
recommended to leave this value at `true`, especially with [Docker Hub which imposes a rate-limit](../faq.md#docker-hub-rate-limits)
|
||||
recommended leaving this value at `true`, especially with [Docker Hub which imposes a rate-limit](../faq.md#docker-hub-rate-limits)
|
||||
on image pull. (default `true`)
|
||||
|
||||
!!! example "Config file"
|
||||
@@ -74,7 +74,7 @@ on image pull. (default `true`)
|
||||
|
||||
### `healthchecks`
|
||||
|
||||
Healthchecks allows to monitor Diun watcher by sending start and success notification
|
||||
Healthchecks allows monitoring Diun watcher by sending start and success notification
|
||||
events to [healthchecks.io](https://healthchecks.io/).
|
||||
|
||||
!!! tip
|
||||
|
||||
@@ -14,16 +14,16 @@ watch:
|
||||
|
||||
## Test notifications
|
||||
|
||||
Through the [command line](usage/cli.md) with:
|
||||
Through the [command line](usage/command-line.md#notif-test) with:
|
||||
|
||||
```shell
|
||||
diun --config ./diun.yml --test-notif
|
||||
diun notif test
|
||||
```
|
||||
|
||||
Or within a container:
|
||||
|
||||
```shell
|
||||
docker-compose exec diun diun --test-notif
|
||||
docker-compose exec diun diun notif test
|
||||
```
|
||||
|
||||
## field docker|swarm uses unsupported type: invalid
|
||||
@@ -127,7 +127,8 @@ Or you can tweak the [`schedule` setting](config/watch.md#schedule) with somethi
|
||||
|
||||
## Profiling
|
||||
|
||||
Diun provides a simple way to manage runtime/pprof profiling through [`--profiler-path` and `--profiler` flags](usage/cli.md#options):
|
||||
Diun provides a simple way to manage runtime/pprof profiling through the
|
||||
[`--profiler-path` and `--profiler` flags with `serve` command](usage/command-line.md#serve):
|
||||
|
||||
```yaml
|
||||
version: "3.5"
|
||||
|
||||
@@ -25,8 +25,8 @@ And extract diun:
|
||||
wget -qO- {{ config.repo_url }}releases/download/v{{ git.tag | trim('v') }}/diun_{{ git.tag | trim('v') }}_linux_x86_64.tar.gz | tar -zxvf - diun
|
||||
```
|
||||
|
||||
After getting the binary, it can be tested with [`./diun --help`](../usage/cli.md) command and moved to a permanent
|
||||
location.
|
||||
After getting the binary, it can be tested with [`./diun --help`](../usage/command-line.md#global-options) command
|
||||
and moved to a permanent location.
|
||||
|
||||
## Server configuration
|
||||
|
||||
|
||||
@@ -233,7 +233,8 @@ Following the transposition of the configuration into environment variables, the
|
||||
is no longer loaded by default in the official Docker image.
|
||||
|
||||
If you want to load a configuration file through the Docker image you will have to declare the
|
||||
[`CONFIG` environment variable](../usage/cli.md#environment-variables) pointing to the assigned configuration file:
|
||||
[`CONFIG` environment variable with `serve` command](../usage/command-line.md#serve) pointing to the assigned
|
||||
configuration file:
|
||||
|
||||
!!! tip
|
||||
This is no longer required since version 4.2.0. Now configuration file can be loaded from
|
||||
|
||||
15
docs/migration/v4.0-to-v4.17.md
Normal file
15
docs/migration/v4.0-to-v4.17.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Diun v4.0 to v4.17
|
||||
|
||||
## New CLI
|
||||
|
||||
CLI has changed since 4.17 and includes [`serve` command](../usage/command-line.md#serve) to start Diun:
|
||||
|
||||
!!! example "v4.0"
|
||||
```shell
|
||||
diun --config diun.yml
|
||||
```
|
||||
|
||||
!!! example "v4.17"
|
||||
```shell
|
||||
diun serve --config diun.yml
|
||||
```
|
||||
@@ -1,44 +0,0 @@
|
||||
# Command Line
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
diun [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```
|
||||
$ diun --help
|
||||
Usage: diun
|
||||
|
||||
Docker image update notifier. More info: https://github.com/crazy-max/diun
|
||||
|
||||
Flags:
|
||||
-h, --help Show context-sensitive help.
|
||||
--version
|
||||
--config=STRING Diun configuration file ($CONFIG).
|
||||
--profiler-path=STRING Base path where profiling files are written
|
||||
($PROFILER_PATH).
|
||||
--profiler=STRING Profiler to use ($PROFILER).
|
||||
--log-level="info" Set log level ($LOG_LEVEL).
|
||||
--log-json Enable JSON logging output ($LOG_JSON).
|
||||
--log-caller Add file:line of the caller to log output
|
||||
($LOG_CALLER).
|
||||
--log-nocolor Disables the colorized output ($LOG_NOCOLOR).
|
||||
--test-notif Test notification settings.
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
|
||||
Following environment variables can be used in place:
|
||||
|
||||
| Name | Default | Description |
|
||||
|--------------------|---------------|---------------|
|
||||
| `CONFIG` | | Diun configuration file |
|
||||
| `PROFILER_PATH` | | Base path where profiling files are written |
|
||||
| `PROFILER` | | [Profiler](../faq.md#profiling) to use |
|
||||
| `LOG_LEVEL` | `info` | Log level output |
|
||||
| `LOG_JSON` | `false` | Enable JSON logging output |
|
||||
| `LOG_CALLER` | `false` | Enable to add `file:line` of the caller |
|
||||
| `LOG_NOCOLOR` | `false` | Disables the colorized output |
|
||||
124
docs/usage/command-line.md
Normal file
124
docs/usage/command-line.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Command Line
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
diun [global options] command [command or global options] [arguments...]
|
||||
```
|
||||
|
||||
## Global options
|
||||
|
||||
All global options can be placed at the command level.
|
||||
|
||||
* `--help`, `-h`: Show context-sensitive help.
|
||||
* `--version`: Show version and exit.
|
||||
|
||||
## Commands
|
||||
|
||||
### `serve`
|
||||
|
||||
Starts Diun server.
|
||||
|
||||
* `--config <path>`: Diun configuration file
|
||||
* `--profiler-path <path>`: Base path where profiling files are written
|
||||
* `--profiler <string>`: Profiler to use
|
||||
* `--log-level <string>`: Set log level (default `info`)
|
||||
* `--log-json`: Enable JSON logging output
|
||||
* `--log-caller`: Add `file:line` of the caller to log output
|
||||
* `--log-nocolor`: Disables the colorized output
|
||||
* `--grpc-authority <string>`: Address used to expose the gRPC server (default `:42286`)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
diun serve --config diun.yml --log-level debug
|
||||
```
|
||||
|
||||
Following environment variables can also be used in place:
|
||||
|
||||
| Name | Default | Description |
|
||||
|--------------------|---------------|---------------|
|
||||
| `CONFIG` | | Diun configuration file |
|
||||
| `PROFILER_PATH` | | Base path where profiling files are written |
|
||||
| `PROFILER` | | [Profiler](../faq.md#profiling) to use |
|
||||
| `LOG_LEVEL` | `info` | Log level output |
|
||||
| `LOG_JSON` | `false` | Enable JSON logging output |
|
||||
| `LOG_CALLER` | `false` | Enable to add `file:line` of the caller |
|
||||
| `LOG_NOCOLOR` | `false` | Disables the colorized output |
|
||||
| `GRPC_AUTHORITY` | `:42286` | Address used to expose the gRPC server |
|
||||
|
||||
### `image list`
|
||||
|
||||
!!! note
|
||||
Diun needs to be started through [`serve`](#serve) command to be able to use this command.
|
||||
|
||||
List images in database.
|
||||
|
||||
* `--raw`: JSON output
|
||||
* `--grpc-authority <string>`: Link to Diun gRPC API (default `127.0.0.1:42286`)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
diun image list
|
||||
```
|
||||
```shell
|
||||
diun image list --raw
|
||||
```
|
||||
|
||||
### `image inspect`
|
||||
|
||||
!!! note
|
||||
Diun needs to be started through [`serve`](#serve) command to be able to use this command.
|
||||
|
||||
Display information of an image in database.
|
||||
|
||||
* `--image`: Image to inspect (**required**)
|
||||
* `--raw`: JSON output
|
||||
* `--grpc-authority <string>`: Link to Diun gRPC API (default `127.0.0.1:42286`)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
diun image inspect alpine
|
||||
```
|
||||
```shell
|
||||
diun image inspect drone/drone --raw
|
||||
```
|
||||
|
||||
### `image remove`
|
||||
|
||||
!!! note
|
||||
Diun needs to be started through [`serve`](#serve) command to be able to use this command.
|
||||
|
||||
Remove an image manifest from database.
|
||||
|
||||
* `--image`: Image to remove (**required**)
|
||||
* `--grpc-authority <string>`: Link to Diun gRPC API (default `127.0.0.1:42286`)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
diun image remove alpine:latest
|
||||
```
|
||||
```shell
|
||||
diun image inspect drone/drone
|
||||
```
|
||||
|
||||
!!! warning
|
||||
All manifest for an image will be removed if no tag is specified
|
||||
|
||||
### `notif test`
|
||||
|
||||
!!! note
|
||||
Diun needs to be started through [`serve`](#serve) command to be able to use this command.
|
||||
|
||||
Test notification settings.
|
||||
|
||||
* `--grpc-authority <string>`: Link to Diun gRPC API (default `127.0.0.1:42286`)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
diun notif test
|
||||
```
|
||||
8
go.mod
8
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/crazy-max/diun/v4
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/alecthomas/kong v0.2.16
|
||||
@@ -11,6 +11,7 @@ require (
|
||||
github.com/crazy-max/gonfig v0.4.0
|
||||
github.com/docker/docker v20.10.6+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.3
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||
github.com/go-playground/validator/v10 v10.5.0
|
||||
@@ -18,6 +19,7 @@ require (
|
||||
github.com/gregdel/pushover v0.0.0-20201104094836-ddbe0c1d3a38
|
||||
github.com/hako/durafmt v0.0.0-20190612201238-650ed9f29a84
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/jedib0t/go-pretty/v6 v6.2.1
|
||||
github.com/matcornic/hermes/v2 v2.1.0
|
||||
github.com/matrix-org/gomatrix v0.0.0-20200501121722-e5578b12c752
|
||||
github.com/microcosm-cc/bluemonday v1.0.9
|
||||
@@ -35,7 +37,11 @@ require (
|
||||
github.com/streadway/amqp v0.0.0-20200108173154-1c71cc93ed71
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/tidwall/pretty v1.1.0
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
google.golang.org/grpc v1.37.0
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
|
||||
google.golang.org/protobuf v1.26.0
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
||||
30
go.sum
30
go.sum
@@ -298,8 +298,9 @@ github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58 h1:hHWif/4GirK3P5uvCyyj941XSVIQDzuJhbEguCICdPE=
|
||||
@@ -458,8 +459,9 @@ github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d h1:QyzYnTnPE15SQyUeqU6qLbWxMkwyAyu+vGksa0b7j00=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
@@ -478,6 +480,8 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc=
|
||||
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -616,8 +620,9 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@@ -667,8 +672,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE=
|
||||
github.com/google/go-containerregistry v0.1.2 h1:YjFNKqxzWUVZND8d4ItF9wuYlE75WQfECE7yKX/Nu3o=
|
||||
github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4=
|
||||
@@ -856,6 +862,8 @@ github.com/jarcoal/httpmock v1.0.5 h1:cHtVEcTxRSX4J0je7mWPfc9BpDpqzXSJ5HbymZmyHc
|
||||
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0 h1:xqgexXAGQgY3HAjNPSaCqn5Aahbo5TKsmhp8VRfr1iQ=
|
||||
github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
github.com/jedib0t/go-pretty/v6 v6.2.1 h1:O/3XdNfyWSyVLLIt1EeDhfP8AhNMjtBSh0MuZ4frg6U=
|
||||
github.com/jedib0t/go-pretty/v6 v6.2.1/go.mod h1:+nE9fyyHGil+PuISTCrp7avEdo6bqoMwqZnuiK2r2a0=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1 h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk=
|
||||
@@ -977,6 +985,7 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
@@ -1152,6 +1161,7 @@ github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
|
||||
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
@@ -1348,6 +1358,8 @@ github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6
|
||||
github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
|
||||
github.com/tetafro/godot v0.4.2 h1:Dib7un+rYJFUi8vN0Bk6EHheKy6fv6ZzFURHw75g6m8=
|
||||
github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
|
||||
github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8=
|
||||
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8=
|
||||
github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
@@ -1611,6 +1623,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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=
|
||||
@@ -1868,8 +1881,11 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1879,8 +1895,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
|
||||
40
hack/gen.Dockerfile
Normal file
40
hack/gen.Dockerfile
Normal file
@@ -0,0 +1,40 @@
|
||||
# syntax=docker/dockerfile:1.2
|
||||
ARG GO_VERSION
|
||||
ARG PROTOC_VERSION
|
||||
ARG GLIBC_VERSION=2.33-r0
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS base
|
||||
ARG GLIBC_VERSION
|
||||
RUN apk add --no-cache curl file git unzip \
|
||||
&& curl -sSL "https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub" -o "/etc/apk/keys/sgerrand.rsa.pub" \
|
||||
&& curl -sSL "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk" -o "glibc.apk" \
|
||||
&& apk add glibc.apk \
|
||||
&& rm /etc/apk/keys/sgerrand.rsa.pub glibc.apk
|
||||
ARG PROTOC_VERSION
|
||||
RUN curl -sSL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip" -o "protoc.zip" \
|
||||
&& unzip "protoc.zip" -d "/usr/local" \
|
||||
&& protoc --version \
|
||||
&& rm "protoc.zip"
|
||||
WORKDIR /src
|
||||
|
||||
FROM base AS gomod
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod tidy && go mod download && go install -v $(sed -n -e 's|^\s*_\s*"\(.*\)".*$|\1| p' tools.go)
|
||||
|
||||
FROM gomod AS generate
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go generate ./... && mkdir /out && cp -Rf pb /out
|
||||
|
||||
FROM scratch AS update
|
||||
COPY --from=generate /out /
|
||||
|
||||
FROM generate AS validate
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
git add -A && cp -rf /out/* .; \
|
||||
if [ -n "$(git status --porcelain)" ]; then \
|
||||
echo >&2 'ERROR: Generate result differs. Please update with "docker buildx bake gen-update"'; \
|
||||
git status --porcelain; \
|
||||
exit 1; \
|
||||
fi
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/crazy-max/diun/v4/internal/config"
|
||||
"github.com/crazy-max/diun/v4/internal/db"
|
||||
"github.com/crazy-max/diun/v4/internal/grpc"
|
||||
"github.com/crazy-max/diun/v4/internal/logging"
|
||||
"github.com/crazy-max/diun/v4/internal/model"
|
||||
"github.com/crazy-max/diun/v4/internal/notif"
|
||||
@@ -16,7 +17,6 @@ import (
|
||||
filePrd "github.com/crazy-max/diun/v4/internal/provider/file"
|
||||
kubernetesPrd "github.com/crazy-max/diun/v4/internal/provider/kubernetes"
|
||||
swarmPrd "github.com/crazy-max/diun/v4/internal/provider/swarm"
|
||||
"github.com/crazy-max/diun/v4/pkg/registry"
|
||||
"github.com/crazy-max/gohealthchecks"
|
||||
"github.com/hako/durafmt"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
@@ -29,10 +29,13 @@ import (
|
||||
type Diun struct {
|
||||
meta model.Meta
|
||||
cfg *config.Config
|
||||
cron *cron.Cron
|
||||
|
||||
db *db.Client
|
||||
grpc *grpc.Client
|
||||
hc *gohealthchecks.Client
|
||||
notif *notif.Client
|
||||
|
||||
cron *cron.Cron
|
||||
jobID cron.EntryID
|
||||
locker uint32
|
||||
pool *ants.PoolWithFunc
|
||||
@@ -40,7 +43,7 @@ type Diun struct {
|
||||
}
|
||||
|
||||
// New creates new diun instance
|
||||
func New(meta model.Meta, cli model.Cli, cfg *config.Config) (*Diun, error) {
|
||||
func New(meta model.Meta, cfg *config.Config, grpcAuthority string) (*Diun, error) {
|
||||
var err error
|
||||
|
||||
diun := &Diun{
|
||||
@@ -56,11 +59,14 @@ func New(meta model.Meta, cli model.Cli, cfg *config.Config) (*Diun, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !cli.TestNotif {
|
||||
diun.db, err = db.New(*cfg.Db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
diun.grpc, err = grpc.New(grpcAuthority, diun.db, diun.notif)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Watch.Healthchecks != nil {
|
||||
@@ -89,6 +95,13 @@ func (di *Diun) Start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start GRPC server
|
||||
go func() {
|
||||
if err := di.grpc.Start(); err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to start GRPC server")
|
||||
}
|
||||
}()
|
||||
|
||||
// Run on startup
|
||||
di.Run()
|
||||
|
||||
@@ -157,7 +170,7 @@ func (di *Diun) Run() {
|
||||
di.createJob(job)
|
||||
}
|
||||
|
||||
// Dokcerfile provider
|
||||
// Dockerfile provider
|
||||
for _, job := range dockerfilePrd.New(di.cfg.Providers.Dockerfile).ListJob() {
|
||||
di.createJob(job)
|
||||
}
|
||||
@@ -178,51 +191,8 @@ func (di *Diun) Close() {
|
||||
if di.cron != nil {
|
||||
di.cron.Stop()
|
||||
}
|
||||
di.grpc.Stop()
|
||||
if err := di.db.Close(); err != nil {
|
||||
log.Warn().Err(err).Msg("Cannot close database")
|
||||
}
|
||||
}
|
||||
|
||||
// TestNotif test the notification settings
|
||||
func (di *Diun) TestNotif() {
|
||||
createdAt, _ := time.Parse("2006-01-02T15:04:05Z", "2020-03-26T12:23:56Z")
|
||||
image, _ := registry.ParseImage(registry.ParseImageOptions{
|
||||
Name: "diun/testnotif:latest",
|
||||
})
|
||||
image.HubLink = ""
|
||||
|
||||
log.Info().Msg("Testing notification settings...")
|
||||
di.notif.Send(model.NotifEntry{
|
||||
Status: "new",
|
||||
Provider: "file",
|
||||
Image: image,
|
||||
Manifest: registry.Manifest{
|
||||
Name: "diun/testnotif",
|
||||
Tag: "latest",
|
||||
MIMEType: "application/vnd.docker.distribution.manifest.list.v2+json",
|
||||
Digest: "sha256:216e3ae7de4ca8b553eb11ef7abda00651e79e537e85c46108284e5e91673e01",
|
||||
Created: &createdAt,
|
||||
DockerVersion: "",
|
||||
Labels: map[string]string{
|
||||
"maintainer": "CrazyMax",
|
||||
"org.label-schema.build-date": "2020-03-26T12:23:56Z",
|
||||
"org.label-schema.description": "Docker image update notifier",
|
||||
"org.label-schema.name": "Diun",
|
||||
"org.label-schema.schema-version": "1.0",
|
||||
"org.label-schema.url": "https://github.com/crazy-max/diun",
|
||||
"org.label-schema.vcs-ref": "e13f097c",
|
||||
"org.label-schema.vcs-url": "https://github.com/crazy-max/diun",
|
||||
"org.label-schema.vendor": "CrazyMax",
|
||||
"org.label-schema.version": "x.x.x",
|
||||
},
|
||||
Layers: []string{
|
||||
"sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819",
|
||||
"sha256:166c6f165b73185ede72415d780538a55c0c8e854bd177925bc007193e5b0d1b",
|
||||
"sha256:e05682efa9cc9d6239b2b9252fe0dc1e58d6e1585679733bb94a6549d49e9b10",
|
||||
"sha256:c6a5bfed445b3ed7e85523cd73c6532ac9f9b72bb588ca728fd5b33987ca6538",
|
||||
"sha256:df2140efb8abeb727ef0b27ff158b7010a7941eb1cfdade505f510a6e1eaf016",
|
||||
},
|
||||
Platform: "linux/amd64",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ type Config struct {
|
||||
}
|
||||
|
||||
// Load returns Config struct
|
||||
func Load(cli model.Cli) (*Config, error) {
|
||||
func Load(config string) (*Config, error) {
|
||||
cfg := Config{
|
||||
Db: (&model.Db{}).GetDefaults(),
|
||||
Watch: (&model.Watch{}).GetDefaults(),
|
||||
}
|
||||
|
||||
fileLoader := gonfig.NewFileLoader(gonfig.FileLoaderConfig{
|
||||
Filename: cli.Cfgfile,
|
||||
Filename: config,
|
||||
Finder: gonfig.Finder{
|
||||
BasePaths: []string{"/etc/diun/diun", "$XDG_CONFIG_HOME/diun", "$HOME/.config/diun", "./diun"},
|
||||
Extensions: []string{"yaml", "yml"},
|
||||
@@ -54,14 +54,14 @@ func Load(cli model.Cli) (*Config, error) {
|
||||
log.Info().Msgf("Configuration loaded from %d environment variable(s)", len(envLoader.GetVars()))
|
||||
}
|
||||
|
||||
if err := cfg.validate(cli); err != nil {
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func (cfg *Config) validate(cli model.Cli) error {
|
||||
func (cfg *Config) validate() error {
|
||||
if len(cfg.Db.Path) > 0 {
|
||||
if err := os.MkdirAll(path.Dir(cfg.Db.Path), os.ModePerm); err != nil {
|
||||
return errors.Wrap(err, "Cannot create database destination folder")
|
||||
@@ -72,11 +72,7 @@ func (cfg *Config) validate(cli model.Cli) error {
|
||||
return errors.New("Healthchecks UUID is required")
|
||||
}
|
||||
|
||||
if cfg.Notif == nil && cli.TestNotif {
|
||||
return errors.New("At least one notifier is required")
|
||||
}
|
||||
|
||||
if cfg.Providers == nil && !cli.TestNotif {
|
||||
if cfg.Providers == nil {
|
||||
return errors.New("At least one provider is required")
|
||||
}
|
||||
|
||||
|
||||
@@ -18,55 +18,33 @@ import (
|
||||
func TestLoadFile(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
cli model.Cli
|
||||
cfg string
|
||||
wantData *config.Config
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Failed on non-existing file",
|
||||
cli: model.Cli{
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Fail on wrong file format",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.invalid.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.invalid.yml",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Fail on no UUID for Healthchecks",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.err.hc.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Fail on no notifier if test notif",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.err.notif.yml",
|
||||
TestNotif: true,
|
||||
},
|
||||
cfg: "./fixtures/config.err.hc.yml",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Fail on no provider",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.err.provider.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.err.provider.yml",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Success",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.test.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.test.yml",
|
||||
wantData: &config.Config{
|
||||
Db: &model.Db{
|
||||
Path: "diun.db",
|
||||
@@ -218,7 +196,7 @@ func TestLoadFile(t *testing.T) {
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg, err := config.Load(tt.cli)
|
||||
cfg, err := config.Load(tt.cfg)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -237,7 +215,7 @@ func TestLoadEnv(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
cli model.Cli
|
||||
cfg string
|
||||
environ []string
|
||||
expected interface{}
|
||||
wantErr bool
|
||||
@@ -365,7 +343,7 @@ func TestLoadEnv(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err := config.Load(tt.cli)
|
||||
cfg, err := config.Load(tt.cfg)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -382,17 +360,14 @@ func TestLoadMixed(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
cli model.Cli
|
||||
cfg string
|
||||
environ []string
|
||||
expected interface{}
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
desc: "env vars and invalid file",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.invalid.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.invalid.yml",
|
||||
environ: []string{
|
||||
"DIUN_PROVIDERS_DOCKER=true",
|
||||
},
|
||||
@@ -401,10 +376,7 @@ func TestLoadMixed(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "docker provider (file) and notif mails (envs)",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.docker.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.docker.yml",
|
||||
environ: []string{
|
||||
"DIUN_NOTIF_MAIL_HOST=127.0.0.1",
|
||||
"DIUN_NOTIF_MAIL_PORT=25",
|
||||
@@ -441,10 +413,7 @@ func TestLoadMixed(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "file provider and notif webhook env override",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.file.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.file.yml",
|
||||
environ: []string{
|
||||
"DIUN_NOTIF_WEBHOOK_ENDPOINT=http://webhook.foo.com/sd54qad89azd5a",
|
||||
"DIUN_NOTIF_WEBHOOK_HEADERS_AUTHORIZATION=Token78910",
|
||||
@@ -488,7 +457,7 @@ func TestLoadMixed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err := config.Load(tt.cli)
|
||||
cfg, err := config.Load(tt.cfg)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -503,19 +472,16 @@ func TestLoadMixed(t *testing.T) {
|
||||
func TestValidation(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
cli model.Cli
|
||||
cfg string
|
||||
}{
|
||||
{
|
||||
name: "Success",
|
||||
cli: model.Cli{
|
||||
Cfgfile: "./fixtures/config.validate.yml",
|
||||
TestNotif: false,
|
||||
},
|
||||
cfg: "./fixtures/config.validate.yml",
|
||||
},
|
||||
}
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg, err := config.Load(tt.cli)
|
||||
cfg, err := config.Load(tt.cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
dec, err := env.Encode("DIUN_", cfg)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
providers:
|
||||
docker: {}
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/crazy-max/diun/v4/pkg/registry"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
@@ -25,6 +26,25 @@ func (c *Client) First(image registry.Image) (bool, error) {
|
||||
return !found, err
|
||||
}
|
||||
|
||||
// ListManifest return a list of Docker images manifests
|
||||
func (c *Client) ListManifest() ([]registry.Manifest, error) {
|
||||
var manifests []registry.Manifest
|
||||
|
||||
err := c.View(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket([]byte(bucketManifest)).Cursor()
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var manifest registry.Manifest
|
||||
if err := json.Unmarshal(v, &manifest); err != nil {
|
||||
return err
|
||||
}
|
||||
manifests = append(manifests, manifest)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return manifests, err
|
||||
}
|
||||
|
||||
// GetManifest returns Docker image manifest
|
||||
func (c *Client) GetManifest(image registry.Image) (registry.Manifest, error) {
|
||||
var manifest registry.Manifest
|
||||
@@ -43,11 +63,37 @@ func (c *Client) GetManifest(image registry.Image) (registry.Manifest, error) {
|
||||
// PutManifest add Docker image manifest in db
|
||||
func (c *Client) PutManifest(image registry.Image, manifest registry.Manifest) error {
|
||||
entryBytes, _ := json.Marshal(manifest)
|
||||
|
||||
err := c.Update(func(tx *bolt.Tx) error {
|
||||
return c.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(bucketManifest))
|
||||
return b.Put([]byte(image.String()), entryBytes)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteManifest deletes a Docker image manifest
|
||||
func (c *Client) DeleteManifest(manifest registry.Manifest) error {
|
||||
return c.Update(func(tx *bolt.Tx) error {
|
||||
return tx.Bucket([]byte(bucketManifest)).Delete([]byte(fmt.Sprintf("%s:%s", manifest.Name, manifest.Tag)))
|
||||
})
|
||||
}
|
||||
|
||||
// ListImage return a list of Docker images with their linked manifests
|
||||
func (c *Client) ListImage() (map[string][]registry.Manifest, error) {
|
||||
images := make(map[string][]registry.Manifest)
|
||||
|
||||
err := c.View(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket([]byte(bucketManifest)).Cursor()
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
var manifest registry.Manifest
|
||||
if err := json.Unmarshal(v, &manifest); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := images[manifest.Name]; !ok {
|
||||
images[manifest.Name] = []registry.Manifest{}
|
||||
}
|
||||
images[manifest.Name] = append(images[manifest.Name], manifest)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return images, err
|
||||
}
|
||||
|
||||
@@ -29,11 +29,8 @@ func (c *Client) ReadMetadata() error {
|
||||
// WriteMetadata writes db metadata
|
||||
func (c *Client) WriteMetadata(metadata Metadata) error {
|
||||
entryBytes, _ := json.Marshal(metadata)
|
||||
|
||||
err := c.Update(func(tx *bolt.Tx) error {
|
||||
return c.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(bucketMetadata))
|
||||
return b.Put([]byte(metadataKey), entryBytes)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -75,9 +75,5 @@ func (c *Client) migration2() error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
58
internal/grpc/client.go
Normal file
58
internal/grpc/client.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/crazy-max/diun/v4/internal/db"
|
||||
grpclogger "github.com/crazy-max/diun/v4/internal/grpc/logger"
|
||||
"github.com/crazy-max/diun/v4/internal/notif"
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Client represents an active grpc object
|
||||
type Client struct {
|
||||
server *grpc.Server
|
||||
authority string
|
||||
db *db.Client
|
||||
notif *notif.Client
|
||||
pb.UnimplementedImageServiceServer
|
||||
pb.UnimplementedNotifServiceServer
|
||||
}
|
||||
|
||||
// New creates a new grpc instance
|
||||
func New(authority string, db *db.Client, notif *notif.Client) (*Client, error) {
|
||||
grpclogger.SetGrpcLogger(log.Level(zerolog.ErrorLevel))
|
||||
|
||||
c := &Client{
|
||||
authority: authority,
|
||||
db: db,
|
||||
notif: notif,
|
||||
}
|
||||
|
||||
c.server = grpc.NewServer()
|
||||
pb.RegisterImageServiceServer(c.server, c)
|
||||
pb.RegisterNotifServiceServer(c.server, c)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Start runs the grpc server
|
||||
func (c *Client) Start() error {
|
||||
var err error
|
||||
|
||||
lis, err := net.Listen("tcp", c.authority)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Cannot create gRPC listener")
|
||||
}
|
||||
|
||||
return c.server.Serve(lis)
|
||||
}
|
||||
|
||||
// Stop stops the grpc server
|
||||
func (c *Client) Stop() {
|
||||
c.server.GracefulStop()
|
||||
}
|
||||
123
internal/grpc/image.go
Normal file
123
internal/grpc/image.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
func (c *Client) ImageList(ctx context.Context, request *pb.ImageListRequest) (*pb.ImageListResponse, error) {
|
||||
images, err := c.db.ListImage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ilr []*pb.ImageListResponse_Image
|
||||
for name, manifests := range images {
|
||||
latest := &manifests[0]
|
||||
for _, manifest := range manifests {
|
||||
if manifest.Created.After(*latest.Created) {
|
||||
latest = &manifest
|
||||
}
|
||||
}
|
||||
ilr = append(ilr, &pb.ImageListResponse_Image{
|
||||
Name: name,
|
||||
ManifestsCount: int64(len(manifests)),
|
||||
Latest: &pb.Manifest{
|
||||
Tag: latest.Tag,
|
||||
MimeType: latest.MIMEType,
|
||||
Digest: latest.Digest.String(),
|
||||
Created: timestamppb.New(*latest.Created),
|
||||
Labels: latest.Labels,
|
||||
Platform: latest.Platform,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ImageListResponse{
|
||||
Images: ilr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) ImageInspect(ctx context.Context, request *pb.ImageInspectRequest) (*pb.ImageInspectResponse, error) {
|
||||
ref, err := reference.ParseNormalizedNamed(request.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
images, err := c.db.ListImage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := images[ref.Name()]; !ok {
|
||||
return nil, fmt.Errorf("%s not found in database", ref.Name())
|
||||
}
|
||||
|
||||
iir := &pb.ImageInspectResponse_Image{
|
||||
Name: ref.Name(),
|
||||
Manifests: []*pb.Manifest{},
|
||||
}
|
||||
for _, manifest := range images[ref.Name()] {
|
||||
iir.Manifests = append(iir.Manifests, &pb.Manifest{
|
||||
Tag: manifest.Tag,
|
||||
MimeType: manifest.MIMEType,
|
||||
Digest: manifest.Digest.String(),
|
||||
Created: timestamppb.New(*manifest.Created),
|
||||
Labels: manifest.Labels,
|
||||
Platform: manifest.Platform,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ImageInspectResponse{
|
||||
Image: iir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) ImageRemove(ctx context.Context, request *pb.ImageRemoveRequest) (*pb.ImageRemoveResponse, error) {
|
||||
ref, err := reference.ParseNormalizedNamed(request.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
images, err := c.db.ListImage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := images[ref.Name()]; !ok {
|
||||
return nil, fmt.Errorf("%s not found in database", ref.Name())
|
||||
}
|
||||
|
||||
var tag string
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
|
||||
var removed []*pb.Manifest
|
||||
for _, manifest := range images[ref.Name()] {
|
||||
if len(tag) == 0 || manifest.Tag == tag {
|
||||
if err = c.db.DeleteManifest(manifest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, _ := json.Marshal(manifest)
|
||||
removed = append(removed, &pb.Manifest{
|
||||
Tag: manifest.Tag,
|
||||
MimeType: manifest.MIMEType,
|
||||
Digest: manifest.Digest.String(),
|
||||
Created: timestamppb.New(*manifest.Created),
|
||||
Labels: manifest.Labels,
|
||||
Platform: manifest.Platform,
|
||||
Size: int64(len(b)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.ImageRemoveResponse{
|
||||
Manifests: removed,
|
||||
}, nil
|
||||
}
|
||||
94
internal/grpc/logger/logger.go
Normal file
94
internal/grpc/logger/logger.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
func SetGrpcLogger(logger zerolog.Logger) {
|
||||
grpclog.SetLoggerV2(wrap(logger))
|
||||
}
|
||||
|
||||
func wrap(l zerolog.Logger) *bridge {
|
||||
return &bridge{l}
|
||||
}
|
||||
|
||||
type bridge struct {
|
||||
zerolog.Logger
|
||||
}
|
||||
|
||||
func (b *bridge) Info(args ...interface{}) {
|
||||
b.Logger.Info().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Infoln(args ...interface{}) {
|
||||
b.Logger.Info().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Infof(format string, args ...interface{}) {
|
||||
b.Logger.Info().Msgf(format, args...)
|
||||
}
|
||||
|
||||
func (b *bridge) Warning(args ...interface{}) {
|
||||
b.Logger.Warn().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Warningln(args ...interface{}) {
|
||||
b.Logger.Warn().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Warningf(format string, args ...interface{}) {
|
||||
b.Logger.Warn().Msgf(format, args...)
|
||||
}
|
||||
|
||||
func (b *bridge) Error(args ...interface{}) {
|
||||
b.Logger.Error().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Errorln(args ...interface{}) {
|
||||
b.Logger.Error().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Errorf(format string, args ...interface{}) {
|
||||
b.Logger.Error().Msgf(format, args...)
|
||||
}
|
||||
|
||||
func (b *bridge) Fatal(args ...interface{}) {
|
||||
b.Logger.Fatal().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Fatalln(args ...interface{}) {
|
||||
b.Logger.Fatal().Msg(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
func (b *bridge) Fatalf(format string, args ...interface{}) {
|
||||
b.Logger.Fatal().Msgf(format, args...)
|
||||
}
|
||||
|
||||
func (b *bridge) V(verbosity int) bool {
|
||||
// verbosity values:
|
||||
// 0 = info
|
||||
// 1 = warning
|
||||
// 2 = error
|
||||
// 3 = fatal
|
||||
switch b.GetLevel() {
|
||||
case zerolog.PanicLevel:
|
||||
return verbosity > 3
|
||||
case zerolog.FatalLevel:
|
||||
return verbosity == 3
|
||||
case zerolog.ErrorLevel:
|
||||
return verbosity == 2
|
||||
case zerolog.WarnLevel:
|
||||
return verbosity == 1
|
||||
case zerolog.InfoLevel:
|
||||
return verbosity == 0
|
||||
case zerolog.DebugLevel:
|
||||
return true
|
||||
case zerolog.TraceLevel:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
72
internal/grpc/notif.go
Normal file
72
internal/grpc/notif.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/crazy-max/diun/v4/internal/model"
|
||||
"github.com/crazy-max/diun/v4/pb"
|
||||
"github.com/crazy-max/diun/v4/pkg/registry"
|
||||
)
|
||||
|
||||
func (c *Client) NotifTest(ctx context.Context, request *pb.NotifTestRequest) (*pb.NotifTestResponse, error) {
|
||||
createdAt, _ := time.Parse("2006-01-02T15:04:05Z", "2020-03-26T12:23:56Z")
|
||||
image, _ := registry.ParseImage(registry.ParseImageOptions{
|
||||
Name: "diun/testnotif:latest",
|
||||
})
|
||||
image.HubLink = ""
|
||||
|
||||
entry := model.NotifEntry{
|
||||
Status: "new",
|
||||
Provider: "file",
|
||||
Image: image,
|
||||
Manifest: registry.Manifest{
|
||||
Name: "diun/testnotif",
|
||||
Tag: "latest",
|
||||
MIMEType: "application/vnd.docker.distribution.manifest.list.v2+json",
|
||||
Digest: "sha256:216e3ae7de4ca8b553eb11ef7abda00651e79e537e85c46108284e5e91673e01",
|
||||
Created: &createdAt,
|
||||
DockerVersion: "",
|
||||
Labels: map[string]string{
|
||||
"maintainer": "CrazyMax",
|
||||
"org.label-schema.build-date": "2020-03-26T12:23:56Z",
|
||||
"org.label-schema.description": "Docker image update notifier",
|
||||
"org.label-schema.name": "Diun",
|
||||
"org.label-schema.schema-version": "1.0",
|
||||
"org.label-schema.url": "https://github.com/crazy-max/diun",
|
||||
"org.label-schema.vcs-ref": "e13f097c",
|
||||
"org.label-schema.vcs-url": "https://github.com/crazy-max/diun",
|
||||
"org.label-schema.vendor": "CrazyMax",
|
||||
"org.label-schema.version": "x.x.x",
|
||||
},
|
||||
Layers: []string{
|
||||
"sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819",
|
||||
"sha256:166c6f165b73185ede72415d780538a55c0c8e854bd177925bc007193e5b0d1b",
|
||||
"sha256:e05682efa9cc9d6239b2b9252fe0dc1e58d6e1585679733bb94a6549d49e9b10",
|
||||
"sha256:c6a5bfed445b3ed7e85523cd73c6532ac9f9b72bb588ca728fd5b33987ca6538",
|
||||
"sha256:df2140efb8abeb727ef0b27ff158b7010a7941eb1cfdade505f510a6e1eaf016",
|
||||
},
|
||||
Platform: "linux/amd64",
|
||||
},
|
||||
}
|
||||
|
||||
if len(c.notif.List()) == 0 {
|
||||
return &pb.NotifTestResponse{
|
||||
Message: "No notifier available",
|
||||
}, nil
|
||||
}
|
||||
|
||||
var sent []string
|
||||
for _, n := range c.notif.List() {
|
||||
if err := n.Send(entry); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sent = append(sent, n.Name())
|
||||
}
|
||||
|
||||
return &pb.NotifTestResponse{
|
||||
Message: fmt.Sprintf("Notifcation sent for %s notifier(s)", strings.Join(sent, ", ")),
|
||||
}, nil
|
||||
}
|
||||
@@ -6,24 +6,30 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/crazy-max/diun/v4/internal/model"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
LogLevel string
|
||||
LogJSON bool
|
||||
LogCaller bool
|
||||
LogNoColor bool
|
||||
}
|
||||
|
||||
// Configure configures logger
|
||||
func Configure(cli *model.Cli) {
|
||||
func Configure(opts Options) {
|
||||
var err error
|
||||
var w io.Writer
|
||||
|
||||
// Adds support for NO_COLOR. More info https://no-color.org/
|
||||
_, noColor := os.LookupEnv("NO_COLOR")
|
||||
|
||||
if !cli.LogJSON {
|
||||
if !opts.LogJSON {
|
||||
w = zerolog.ConsoleWriter{
|
||||
Out: os.Stdout,
|
||||
NoColor: noColor || cli.LogNoColor,
|
||||
NoColor: noColor || opts.LogNoColor,
|
||||
TimeFormat: time.RFC1123,
|
||||
}
|
||||
} else {
|
||||
@@ -31,20 +37,20 @@ func Configure(cli *model.Cli) {
|
||||
}
|
||||
|
||||
ctx := zerolog.New(w).With().Timestamp()
|
||||
if cli.LogCaller {
|
||||
if opts.LogCaller {
|
||||
ctx = ctx.Caller()
|
||||
}
|
||||
|
||||
log.Logger = ctx.Logger()
|
||||
|
||||
logLevel, err := zerolog.ParseLevel(cli.LogLevel)
|
||||
logLevel, err := zerolog.ParseLevel(opts.LogLevel)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Unknown log level")
|
||||
} else {
|
||||
zerolog.SetGlobalLevel(logLevel)
|
||||
}
|
||||
|
||||
logrusLevel, err := logrus.ParseLevel(cli.LogLevel)
|
||||
logrusLevel, err := logrus.ParseLevel(opts.LogLevel)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msgf("Unknown log level")
|
||||
} else {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/alecthomas/kong"
|
||||
|
||||
// Cli holds command line args, flags and cmds
|
||||
type Cli struct {
|
||||
Version kong.VersionFlag
|
||||
Cfgfile string `kong:"name='config',env='CONFIG',help='Diun configuration file.'"`
|
||||
ProfilerPath string `kong:"name='profiler-path',env='PROFILER_PATH',help='Base path where profiling files are written.'"`
|
||||
Profiler string `kong:"name='profiler',env='PROFILER',help='Profiler to use.'"`
|
||||
LogLevel string `kong:"name='log-level',env='LOG_LEVEL',default='info',help='Set log level.'"`
|
||||
LogJSON bool `kong:"name='log-json',env='LOG_JSON',default='false',help='Enable JSON logging output.'"`
|
||||
LogCaller bool `kong:"name='log-caller',env='LOG_CALLER',default='false',help='Add file:line of the caller to log output.'"`
|
||||
LogNoColor bool `kong:"name='log-nocolor',env='LOG_NOCOLOR',default='false',help='Disables the colorized output.'"`
|
||||
TestNotif bool `kong:"name='test-notif',default='false',help='Test notification settings.'"`
|
||||
}
|
||||
@@ -95,3 +95,8 @@ func (c *Client) Send(entry model.NotifEntry) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// List returns created notifiers
|
||||
func (c *Client) List() []notifier.Notifier {
|
||||
return c.notifiers
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ nav:
|
||||
- From binary: install/binary.md
|
||||
- Linux service: install/linux-service.md
|
||||
- Usage:
|
||||
- Command line: usage/cli.md
|
||||
- Command line: usage/command-line.md
|
||||
- Basic example: usage/basic-example.md
|
||||
- Configuration:
|
||||
- Overview: config/index.md
|
||||
@@ -125,6 +125,7 @@ nav:
|
||||
- FAQ: faq.md
|
||||
- Changelog: changelog.md
|
||||
- Migration:
|
||||
- Diun v4.0 to v4.17: migration/v4.0-to-v4.17.md
|
||||
- Diun v3 to v4: migration/v3-to-v4.md
|
||||
- Diun v2 to v3: migration/v2-to-v3.md
|
||||
- Diun v1 to v2: migration/v1-to-v2.md
|
||||
|
||||
3
pb/gen.go
Normal file
3
pb/gen.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package pb
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. image.proto notif.proto
|
||||
764
pb/image.pb.go
Normal file
764
pb/image.pb.go
Normal file
@@ -0,0 +1,764 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.0
|
||||
// source: image.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Manifest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
|
||||
MimeType string `protobuf:"bytes,2,opt,name=mime_type,json=mimeType,proto3" json:"mime_type,omitempty"`
|
||||
Digest string `protobuf:"bytes,3,opt,name=digest,proto3" json:"digest,omitempty"`
|
||||
Created *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"`
|
||||
Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Platform string `protobuf:"bytes,6,opt,name=platform,proto3" json:"platform,omitempty"`
|
||||
Size int64 `protobuf:"varint,7,opt,name=size,proto3" json:"size,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Manifest) Reset() {
|
||||
*x = Manifest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Manifest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Manifest) ProtoMessage() {}
|
||||
|
||||
func (x *Manifest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Manifest.ProtoReflect.Descriptor instead.
|
||||
func (*Manifest) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Manifest) GetTag() string {
|
||||
if x != nil {
|
||||
return x.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Manifest) GetMimeType() string {
|
||||
if x != nil {
|
||||
return x.MimeType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Manifest) GetDigest() string {
|
||||
if x != nil {
|
||||
return x.Digest
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Manifest) GetCreated() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Created
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Manifest) GetLabels() map[string]string {
|
||||
if x != nil {
|
||||
return x.Labels
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Manifest) GetPlatform() string {
|
||||
if x != nil {
|
||||
return x.Platform
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Manifest) GetSize() int64 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ImageListRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *ImageListRequest) Reset() {
|
||||
*x = ImageListRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageListRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageListRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ImageListRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageListRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ImageListRequest) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type ImageListResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Images []*ImageListResponse_Image `protobuf:"bytes,1,rep,name=images,proto3" json:"images,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageListResponse) Reset() {
|
||||
*x = ImageListResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageListResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageListResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ImageListResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageListResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ImageListResponse) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ImageListResponse) GetImages() []*ImageListResponse_Image {
|
||||
if x != nil {
|
||||
return x.Images
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImageInspectRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageInspectRequest) Reset() {
|
||||
*x = ImageInspectRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageInspectRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageInspectRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ImageInspectRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageInspectRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ImageInspectRequest) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ImageInspectRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ImageInspectResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Image *ImageInspectResponse_Image `protobuf:"bytes,1,opt,name=image,proto3" json:"image,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse) Reset() {
|
||||
*x = ImageInspectResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageInspectResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ImageInspectResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageInspectResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ImageInspectResponse) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse) GetImage() *ImageInspectResponse_Image {
|
||||
if x != nil {
|
||||
return x.Image
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImageRemoveRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageRemoveRequest) Reset() {
|
||||
*x = ImageRemoveRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageRemoveRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageRemoveRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ImageRemoveRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageRemoveRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ImageRemoveRequest) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ImageRemoveRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ImageRemoveResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Manifests []*Manifest `protobuf:"bytes,1,rep,name=manifests,proto3" json:"manifests,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageRemoveResponse) Reset() {
|
||||
*x = ImageRemoveResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageRemoveResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageRemoveResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ImageRemoveResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageRemoveResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ImageRemoveResponse) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ImageRemoveResponse) GetManifests() []*Manifest {
|
||||
if x != nil {
|
||||
return x.Manifests
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImageListResponse_Image struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
ManifestsCount int64 `protobuf:"varint,2,opt,name=manifestsCount,proto3" json:"manifestsCount,omitempty"`
|
||||
Latest *Manifest `protobuf:"bytes,3,opt,name=latest,proto3" json:"latest,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageListResponse_Image) Reset() {
|
||||
*x = ImageListResponse_Image{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageListResponse_Image) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageListResponse_Image) ProtoMessage() {}
|
||||
|
||||
func (x *ImageListResponse_Image) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageListResponse_Image.ProtoReflect.Descriptor instead.
|
||||
func (*ImageListResponse_Image) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{2, 0}
|
||||
}
|
||||
|
||||
func (x *ImageListResponse_Image) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ImageListResponse_Image) GetManifestsCount() int64 {
|
||||
if x != nil {
|
||||
return x.ManifestsCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ImageListResponse_Image) GetLatest() *Manifest {
|
||||
if x != nil {
|
||||
return x.Latest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImageInspectResponse_Image struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Manifests []*Manifest `protobuf:"bytes,2,rep,name=manifests,proto3" json:"manifests,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse_Image) Reset() {
|
||||
*x = ImageInspectResponse_Image{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_image_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse_Image) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ImageInspectResponse_Image) ProtoMessage() {}
|
||||
|
||||
func (x *ImageInspectResponse_Image) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_image_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ImageInspectResponse_Image.ProtoReflect.Descriptor instead.
|
||||
func (*ImageInspectResponse_Image) Descriptor() ([]byte, []int) {
|
||||
return file_image_proto_rawDescGZIP(), []int{4, 0}
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse_Image) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ImageInspectResponse_Image) GetManifests() []*Manifest {
|
||||
if x != nil {
|
||||
return x.Manifests
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_image_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_image_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70,
|
||||
0x62, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x22, 0xa4, 0x02, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61,
|
||||
0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x06,
|
||||
0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69,
|
||||
0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, 0x39,
|
||||
0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x12, 0x0a, 0x10, 0x49, 0x6d, 0x61,
|
||||
0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, 0x01,
|
||||
0x0a, 0x11, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65,
|
||||
0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73,
|
||||
0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d,
|
||||
0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a,
|
||||
0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x74,
|
||||
0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x13, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x95,
|
||||
0x01, 0x0a, 0x14, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x1a, 0x47, 0x0a,
|
||||
0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x6d, 0x61,
|
||||
0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x09, 0x6d, 0x61, 0x6e,
|
||||
0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x22, 0x41, 0x0a, 0x13, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66,
|
||||
0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65,
|
||||
0x73, 0x74, 0x73, 0x32, 0xd1, 0x01, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61,
|
||||
0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x43, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74,
|
||||
0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x49,
|
||||
0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1e, 0x5a, 0x1c, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x2d, 0x6d, 0x61, 0x78, 0x2f,
|
||||
0x64, 0x69, 0x75, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_image_proto_rawDescOnce sync.Once
|
||||
file_image_proto_rawDescData = file_image_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_image_proto_rawDescGZIP() []byte {
|
||||
file_image_proto_rawDescOnce.Do(func() {
|
||||
file_image_proto_rawDescData = protoimpl.X.CompressGZIP(file_image_proto_rawDescData)
|
||||
})
|
||||
return file_image_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_image_proto_goTypes = []interface{}{
|
||||
(*Manifest)(nil), // 0: pb.Manifest
|
||||
(*ImageListRequest)(nil), // 1: pb.ImageListRequest
|
||||
(*ImageListResponse)(nil), // 2: pb.ImageListResponse
|
||||
(*ImageInspectRequest)(nil), // 3: pb.ImageInspectRequest
|
||||
(*ImageInspectResponse)(nil), // 4: pb.ImageInspectResponse
|
||||
(*ImageRemoveRequest)(nil), // 5: pb.ImageRemoveRequest
|
||||
(*ImageRemoveResponse)(nil), // 6: pb.ImageRemoveResponse
|
||||
nil, // 7: pb.Manifest.LabelsEntry
|
||||
(*ImageListResponse_Image)(nil), // 8: pb.ImageListResponse.Image
|
||||
(*ImageInspectResponse_Image)(nil), // 9: pb.ImageInspectResponse.Image
|
||||
(*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp
|
||||
}
|
||||
var file_image_proto_depIdxs = []int32{
|
||||
10, // 0: pb.Manifest.created:type_name -> google.protobuf.Timestamp
|
||||
7, // 1: pb.Manifest.labels:type_name -> pb.Manifest.LabelsEntry
|
||||
8, // 2: pb.ImageListResponse.images:type_name -> pb.ImageListResponse.Image
|
||||
9, // 3: pb.ImageInspectResponse.image:type_name -> pb.ImageInspectResponse.Image
|
||||
0, // 4: pb.ImageRemoveResponse.manifests:type_name -> pb.Manifest
|
||||
0, // 5: pb.ImageListResponse.Image.latest:type_name -> pb.Manifest
|
||||
0, // 6: pb.ImageInspectResponse.Image.manifests:type_name -> pb.Manifest
|
||||
1, // 7: pb.ImageService.ImageList:input_type -> pb.ImageListRequest
|
||||
3, // 8: pb.ImageService.ImageInspect:input_type -> pb.ImageInspectRequest
|
||||
5, // 9: pb.ImageService.ImageRemove:input_type -> pb.ImageRemoveRequest
|
||||
2, // 10: pb.ImageService.ImageList:output_type -> pb.ImageListResponse
|
||||
4, // 11: pb.ImageService.ImageInspect:output_type -> pb.ImageInspectResponse
|
||||
6, // 12: pb.ImageService.ImageRemove:output_type -> pb.ImageRemoveResponse
|
||||
10, // [10:13] is the sub-list for method output_type
|
||||
7, // [7:10] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_image_proto_init() }
|
||||
func file_image_proto_init() {
|
||||
if File_image_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_image_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Manifest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageListRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageListResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageInspectRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageInspectResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageRemoveRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageRemoveResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageListResponse_Image); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_image_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ImageInspectResponse_Image); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_image_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 10,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_image_proto_goTypes,
|
||||
DependencyIndexes: file_image_proto_depIdxs,
|
||||
MessageInfos: file_image_proto_msgTypes,
|
||||
}.Build()
|
||||
File_image_proto = out.File
|
||||
file_image_proto_rawDesc = nil
|
||||
file_image_proto_goTypes = nil
|
||||
file_image_proto_depIdxs = nil
|
||||
}
|
||||
53
pb/image.proto
Normal file
53
pb/image.proto
Normal file
@@ -0,0 +1,53 @@
|
||||
syntax = "proto3";
|
||||
option go_package = "github.com/crazy-max/diun/pb";
|
||||
|
||||
package pb;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
message Manifest {
|
||||
string tag = 1;
|
||||
string mime_type = 2;
|
||||
string digest = 3;
|
||||
google.protobuf.Timestamp created = 4;
|
||||
map<string, string> labels = 5;
|
||||
string platform = 6;
|
||||
int64 size = 7;
|
||||
}
|
||||
|
||||
message ImageListRequest {}
|
||||
|
||||
message ImageListResponse {
|
||||
message Image {
|
||||
string name = 1;
|
||||
int64 manifestsCount = 2;
|
||||
Manifest latest = 3;
|
||||
}
|
||||
repeated Image images = 1;
|
||||
}
|
||||
|
||||
message ImageInspectRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message ImageInspectResponse {
|
||||
message Image {
|
||||
string name = 1;
|
||||
repeated Manifest manifests = 2;
|
||||
}
|
||||
Image image = 1;
|
||||
}
|
||||
|
||||
message ImageRemoveRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message ImageRemoveResponse {
|
||||
repeated Manifest manifests = 1;
|
||||
}
|
||||
|
||||
service ImageService {
|
||||
rpc ImageList(ImageListRequest) returns (ImageListResponse) {}
|
||||
rpc ImageInspect(ImageInspectRequest) returns (ImageInspectResponse) {}
|
||||
rpc ImageRemove(ImageRemoveRequest) returns (ImageRemoveResponse) {}
|
||||
}
|
||||
173
pb/image_grpc.pb.go
Normal file
173
pb/image_grpc.pb.go
Normal file
@@ -0,0 +1,173 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// ImageServiceClient is the client API for ImageService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ImageServiceClient interface {
|
||||
ImageList(ctx context.Context, in *ImageListRequest, opts ...grpc.CallOption) (*ImageListResponse, error)
|
||||
ImageInspect(ctx context.Context, in *ImageInspectRequest, opts ...grpc.CallOption) (*ImageInspectResponse, error)
|
||||
ImageRemove(ctx context.Context, in *ImageRemoveRequest, opts ...grpc.CallOption) (*ImageRemoveResponse, error)
|
||||
}
|
||||
|
||||
type imageServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewImageServiceClient(cc grpc.ClientConnInterface) ImageServiceClient {
|
||||
return &imageServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *imageServiceClient) ImageList(ctx context.Context, in *ImageListRequest, opts ...grpc.CallOption) (*ImageListResponse, error) {
|
||||
out := new(ImageListResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.ImageService/ImageList", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *imageServiceClient) ImageInspect(ctx context.Context, in *ImageInspectRequest, opts ...grpc.CallOption) (*ImageInspectResponse, error) {
|
||||
out := new(ImageInspectResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.ImageService/ImageInspect", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *imageServiceClient) ImageRemove(ctx context.Context, in *ImageRemoveRequest, opts ...grpc.CallOption) (*ImageRemoveResponse, error) {
|
||||
out := new(ImageRemoveResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.ImageService/ImageRemove", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ImageServiceServer is the server API for ImageService service.
|
||||
// All implementations must embed UnimplementedImageServiceServer
|
||||
// for forward compatibility
|
||||
type ImageServiceServer interface {
|
||||
ImageList(context.Context, *ImageListRequest) (*ImageListResponse, error)
|
||||
ImageInspect(context.Context, *ImageInspectRequest) (*ImageInspectResponse, error)
|
||||
ImageRemove(context.Context, *ImageRemoveRequest) (*ImageRemoveResponse, error)
|
||||
mustEmbedUnimplementedImageServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedImageServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedImageServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedImageServiceServer) ImageList(context.Context, *ImageListRequest) (*ImageListResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ImageList not implemented")
|
||||
}
|
||||
func (UnimplementedImageServiceServer) ImageInspect(context.Context, *ImageInspectRequest) (*ImageInspectResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ImageInspect not implemented")
|
||||
}
|
||||
func (UnimplementedImageServiceServer) ImageRemove(context.Context, *ImageRemoveRequest) (*ImageRemoveResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ImageRemove not implemented")
|
||||
}
|
||||
func (UnimplementedImageServiceServer) mustEmbedUnimplementedImageServiceServer() {}
|
||||
|
||||
// UnsafeImageServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ImageServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeImageServiceServer interface {
|
||||
mustEmbedUnimplementedImageServiceServer()
|
||||
}
|
||||
|
||||
func RegisterImageServiceServer(s grpc.ServiceRegistrar, srv ImageServiceServer) {
|
||||
s.RegisterService(&ImageService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ImageService_ImageList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ImageListRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ImageServiceServer).ImageList(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.ImageService/ImageList",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ImageServiceServer).ImageList(ctx, req.(*ImageListRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ImageService_ImageInspect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ImageInspectRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ImageServiceServer).ImageInspect(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.ImageService/ImageInspect",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ImageServiceServer).ImageInspect(ctx, req.(*ImageInspectRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ImageService_ImageRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ImageRemoveRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ImageServiceServer).ImageRemove(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.ImageService/ImageRemove",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ImageServiceServer).ImageRemove(ctx, req.(*ImageRemoveRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ImageService_ServiceDesc is the grpc.ServiceDesc for ImageService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ImageService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "pb.ImageService",
|
||||
HandlerType: (*ImageServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ImageList",
|
||||
Handler: _ImageService_ImageList_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ImageInspect",
|
||||
Handler: _ImageService_ImageInspect_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ImageRemove",
|
||||
Handler: _ImageService_ImageRemove_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "image.proto",
|
||||
}
|
||||
202
pb/notif.pb.go
Normal file
202
pb/notif.pb.go
Normal file
@@ -0,0 +1,202 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.0
|
||||
// source: notif.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type NotifTestRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *NotifTestRequest) Reset() {
|
||||
*x = NotifTestRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_notif_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NotifTestRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NotifTestRequest) ProtoMessage() {}
|
||||
|
||||
func (x *NotifTestRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_notif_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NotifTestRequest.ProtoReflect.Descriptor instead.
|
||||
func (*NotifTestRequest) Descriptor() ([]byte, []int) {
|
||||
return file_notif_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type NotifTestResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (x *NotifTestResponse) Reset() {
|
||||
*x = NotifTestResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_notif_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NotifTestResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NotifTestResponse) ProtoMessage() {}
|
||||
|
||||
func (x *NotifTestResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_notif_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NotifTestResponse.ProtoReflect.Descriptor instead.
|
||||
func (*NotifTestResponse) Descriptor() ([]byte, []int) {
|
||||
return file_notif_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *NotifTestResponse) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_notif_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_notif_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70,
|
||||
0x62, 0x22, 0x12, 0x0a, 0x10, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2d, 0x0a, 0x11, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x54, 0x65,
|
||||
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x32, 0x4a, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x54, 0x65, 0x73,
|
||||
0x74, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x54, 0x65, 0x73, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x74,
|
||||
0x69, 0x66, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x42, 0x1e, 0x5a, 0x1c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
|
||||
0x72, 0x61, 0x7a, 0x79, 0x2d, 0x6d, 0x61, 0x78, 0x2f, 0x64, 0x69, 0x75, 0x6e, 0x2f, 0x70, 0x62,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_notif_proto_rawDescOnce sync.Once
|
||||
file_notif_proto_rawDescData = file_notif_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_notif_proto_rawDescGZIP() []byte {
|
||||
file_notif_proto_rawDescOnce.Do(func() {
|
||||
file_notif_proto_rawDescData = protoimpl.X.CompressGZIP(file_notif_proto_rawDescData)
|
||||
})
|
||||
return file_notif_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_notif_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_notif_proto_goTypes = []interface{}{
|
||||
(*NotifTestRequest)(nil), // 0: pb.NotifTestRequest
|
||||
(*NotifTestResponse)(nil), // 1: pb.NotifTestResponse
|
||||
}
|
||||
var file_notif_proto_depIdxs = []int32{
|
||||
0, // 0: pb.NotifService.NotifTest:input_type -> pb.NotifTestRequest
|
||||
1, // 1: pb.NotifService.NotifTest:output_type -> pb.NotifTestResponse
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_notif_proto_init() }
|
||||
func file_notif_proto_init() {
|
||||
if File_notif_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_notif_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NotifTestRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_notif_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NotifTestResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_notif_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_notif_proto_goTypes,
|
||||
DependencyIndexes: file_notif_proto_depIdxs,
|
||||
MessageInfos: file_notif_proto_msgTypes,
|
||||
}.Build()
|
||||
File_notif_proto = out.File
|
||||
file_notif_proto_rawDesc = nil
|
||||
file_notif_proto_goTypes = nil
|
||||
file_notif_proto_depIdxs = nil
|
||||
}
|
||||
14
pb/notif.proto
Normal file
14
pb/notif.proto
Normal file
@@ -0,0 +1,14 @@
|
||||
syntax = "proto3";
|
||||
option go_package = "github.com/crazy-max/diun/pb";
|
||||
|
||||
package pb;
|
||||
|
||||
message NotifTestRequest {}
|
||||
|
||||
message NotifTestResponse {
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
service NotifService {
|
||||
rpc NotifTest(NotifTestRequest) returns (NotifTestResponse) {}
|
||||
}
|
||||
101
pb/notif_grpc.pb.go
Normal file
101
pb/notif_grpc.pb.go
Normal file
@@ -0,0 +1,101 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// NotifServiceClient is the client API for NotifService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type NotifServiceClient interface {
|
||||
NotifTest(ctx context.Context, in *NotifTestRequest, opts ...grpc.CallOption) (*NotifTestResponse, error)
|
||||
}
|
||||
|
||||
type notifServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewNotifServiceClient(cc grpc.ClientConnInterface) NotifServiceClient {
|
||||
return ¬ifServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *notifServiceClient) NotifTest(ctx context.Context, in *NotifTestRequest, opts ...grpc.CallOption) (*NotifTestResponse, error) {
|
||||
out := new(NotifTestResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.NotifService/NotifTest", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// NotifServiceServer is the server API for NotifService service.
|
||||
// All implementations must embed UnimplementedNotifServiceServer
|
||||
// for forward compatibility
|
||||
type NotifServiceServer interface {
|
||||
NotifTest(context.Context, *NotifTestRequest) (*NotifTestResponse, error)
|
||||
mustEmbedUnimplementedNotifServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedNotifServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedNotifServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedNotifServiceServer) NotifTest(context.Context, *NotifTestRequest) (*NotifTestResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method NotifTest not implemented")
|
||||
}
|
||||
func (UnimplementedNotifServiceServer) mustEmbedUnimplementedNotifServiceServer() {}
|
||||
|
||||
// UnsafeNotifServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to NotifServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeNotifServiceServer interface {
|
||||
mustEmbedUnimplementedNotifServiceServer()
|
||||
}
|
||||
|
||||
func RegisterNotifServiceServer(s grpc.ServiceRegistrar, srv NotifServiceServer) {
|
||||
s.RegisterService(&NotifService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _NotifService_NotifTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(NotifTestRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(NotifServiceServer).NotifTest(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.NotifService/NotifTest",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NotifServiceServer).NotifTest(ctx, req.(*NotifTestRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// NotifService_ServiceDesc is the grpc.ServiceDesc for NotifService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var NotifService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "pb.NotifService",
|
||||
HandlerType: (*NotifServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "NotifTest",
|
||||
Handler: _NotifService_NotifTest_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "notif.proto",
|
||||
}
|
||||
Reference in New Issue
Block a user