Skip to content

Commit

Permalink
server: add sort option
Browse files Browse the repository at this point in the history
This adds a '--sort' to the 'server' sub-command. Currently there is
only one sort option, which is by create date. I assumed that his is
useful in general, compared to a random order, so I made this the
default.

This is slightly over engineered, but makes it easier to add additional
sorting options later. One that comes to my mind is sorting by tag (some
kind of natsort/semversort).

Signed-off-by: Roland Kammerer <[email protected]>
  • Loading branch information
rck committed Jun 11, 2019
1 parent e29a4fd commit cfb87f8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,22 +225,24 @@ Run a static UI server for a registry.

Flags:

-u, --username username for the registry (default: <none>)
--listen-address address to listen on (default: <none>)
--asset-path Path to assets and templates (default: <none>)
-f, --force-non-ssl force allow use of non-ssl (default: false)
--once generate the templates once and then exit (default: false)
--skip-ping skip pinging the registry while establishing connection (default: false)
--timeout timeout for HTTP requests (default: 1m0s)
--auth-url alternate URL for registry authentication (ex. auth.docker.io) (default: <none>)
--cert path to ssl cert (default: <none>)
--clair url to clair instance (default: <none>)
-d enable debug logging (default: false)
-f, --force-non-ssl force allow use of non-ssl (default: false)
--interval interval to generate new index.html's at (default: 1h0m0s)
-k, --insecure do not verify tls certificates (default: false)
--key path to ssl key (default: <none>)
--listen-address address to listen on (default: <none>)
--once generate the templates once and then exit (default: false)
-p, --password password for the registry (default: <none>)
--port port for server to run on (default: 8080)
-r, --registry URL to the private registry (ex. r.j3ss.co) (default: <none>)
--clair url to clair instance (default: <none>)
-k, --insecure do not verify tls certificates (default: false)
--interval interval to generate new index.html's at (default: 1h0m0s)
-p, --password password for the registry (default: <none>)
--skip-ping skip pinging the registry while establishing connection (default: false)
--sort generate tag templates sorted by property (one of: created) (default: created)
--timeout timeout for HTTP requests (default: 1m0s)
-u, --username username for the registry (default: <none>)
```

**Screenshots:**
Expand Down Expand Up @@ -283,4 +285,4 @@ against an insecure registry.
**OR**

Run `make dind dtest` to avoid having to change your local docker config and
to run the tests as docker-in-docker.
to run the tests as docker-in-docker.
17 changes: 17 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
Expand All @@ -28,6 +29,7 @@ type registryController struct {
l sync.Mutex
tmpl *template.Template
generateOnly bool
repoSortBy string
}

type v1Compatibility struct {
Expand All @@ -44,6 +46,16 @@ type Repository struct {
VulnerabilityReport clair.VulnerabilityReport `json:"vulnerability"`
}

const (
sortByCreated = "created"
)

type repoByDate []Repository

func (r repoByDate) Len() int { return len(r) }
func (r repoByDate) Less(i, j int) bool { return r[i].Created.Before(r[j].Created) }
func (r repoByDate) Swap(i, j int) { r[i], r[j] = r[j], r[i] }

// An AnalysisResult holds all vulnerabilities of a scan
type AnalysisResult struct {
Repositories []Repository `json:"repositories"`
Expand Down Expand Up @@ -228,6 +240,11 @@ func (rc *registryController) generateTagsTemplate(ctx context.Context, repo str
result.Repositories = append(result.Repositories, rp)
}

switch rc.repoSortBy {
case sortByCreated:
sort.Sort(sort.Reverse(repoByDate(result.Repositories)))
}

// Execute the template.
var buf bytes.Buffer
if err := rc.tmpl.ExecuteTemplate(&buf, "tags", result); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func (cmd *serverCommand) Register(fs *flag.FlagSet) {
fs.StringVar(&cmd.assetPath, "asset-path", "", "Path to assets and templates")

fs.BoolVar(&cmd.generateAndExit, "once", false, "generate the templates once and then exit")

sortOpts := []string{sortByCreated}
fs.StringVar(&cmd.repoSortBy, "sort", sortByCreated,
fmt.Sprintf("generate tag templates sorted by property (one of: %s)", strings.Join(sortOpts, ",")))
}

type serverCommand struct {
Expand All @@ -57,6 +61,7 @@ type serverCommand struct {
listenAddress string
port string
assetPath string
repoSortBy string
}

func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
Expand All @@ -66,10 +71,15 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
return err
}

if cmd.repoSortBy != sortByCreated {
return fmt.Errorf("sort option invalid; '%s' is not valid", cmd.repoSortBy)
}

// Create the registry controller for the handlers.
rc := registryController{
reg: r,
generateOnly: cmd.generateAndExit,
repoSortBy: cmd.repoSortBy,
}

// Create a clair client if the user passed in a server address.
Expand Down

0 comments on commit cfb87f8

Please sign in to comment.