Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: add sort option #184

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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