Skip to content

Commit

Permalink
add minimal web ui, lkar: add setup command
Browse files Browse the repository at this point in the history
Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
  • Loading branch information
Adphi committed Oct 10, 2023
1 parent 0977e07 commit 0eb603c
Show file tree
Hide file tree
Showing 114 changed files with 15,446 additions and 89 deletions.
1 change: 1 addition & 0 deletions .dockerignore
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
tmp
.env
bin
**/node_modules
**/build
27 changes: 22 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM golang:alpine
FROM node:alpine as react-builder

WORKDIR /app

COPY ui/package.json ui/yarn.lock ./

RUN yarn install --frozen-lockfile

COPY ui/ ./

RUN yarn build


FROM golang:alpine as go-builder

WORKDIR /app

Expand All @@ -22,15 +35,19 @@ RUN go mod download

COPY cmd ./cmd
COPY pkg ./pkg
COPY version.go ./version.go
COPY ui/ui.go ./ui/ui.go

COPY --from=react-builder /app/build ./ui/build

RUN go build -trimpath -ldflags="-s -w" -o artifact-registry ./cmd/artifact-registry
RUN go build -trimpath -ldflags="-s -w" -o lkard ./cmd/lkard
RUN go build -trimpath -ldflags="-s -w" -o lkar ./cmd/lkar

FROM alpine:latest

RUN apk --no-cache add ca-certificates

COPY --from=0 /app/artifact-registry /usr/local/bin/artifact-registry
COPY --from=0 /app/lkar /usr/local/bin/lkar
COPY --from=go-builder /app/lkard /usr/local/bin/lkard
COPY --from=go-builder /app/lkar /usr/local/bin/lkar

ENTRYPOINT ["/usr/local/bin/artifact-registry"]
ENTRYPOINT ["/usr/local/bin/lkard"]
30 changes: 26 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
IMAGE := "linkacloud/artifact-registry"
MODULE = go.linka.cloud/artifact-registry

install: docker-build
PROJECT = artifact-registry
REPOSITORY = linkacloud

UI := $(PWD)/ui

TAG = $(shell git describe --tags --exact-match 2> /dev/null)
VERSION_SUFFIX = $(shell git diff --quiet || echo "-dev")
VERSION = $(shell git describe --tags --exact-match 2> /dev/null || echo "`git describe --tags $$(git rev-list --tags --max-count=1) 2> /dev/null || echo v0.0.0`-`git rev-parse --short HEAD`")$(VERSION_SUFFIX)
show-version:
@echo $(VERSION)

build-ui:
@yarn --cwd $(UI) install
@yarn --cwd $(UI) build

install: build-ui
@go generate ./...
@go install -trimpath -ldflags "-s -w -X '$(MODULE).Version=$(VERSION)' -X '$(MODULE).BuildDate=$(shell date)'" ./cmd/artifact-registry
@go install -trimpath -ldflags "-s -w -X '$(MODULE).Version=$(VERSION)' -X '$(MODULE).BuildDate=$(shell date)'" ./cmd/lkar

DOCKER_BUILDX_ARGS := build --pull --load

docker: docker-build docker-push

.PHONY: docker-build
docker-build:
@docker build -t $(IMAGE) .
@docker buildx $(DOCKER_BUILDX_ARGS) --pull -t $(REPOSITORY)/$(PROJECT):$(VERSION) .
ifneq ($(TAG),)
@docker image tag $(REPOSITORY)/$(PROJECT):$(VERSION) $(REPOSITORY)/$(PROJECT):latest
endif

.PHONY: docker-push
docker-push:
@docker push $(IMAGE)
@docker image push $(REPOSITORY)/$(PROJECT):$(VERSION)
ifneq ($(TAG),)
@docker image push $(REPOSITORY)/$(PROJECT):latest
endif
20 changes: 17 additions & 3 deletions cmd/lkar/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,18 @@ var (
passStdin bool

loginCmd = &cobra.Command{
Use: "login [registry]",
Short: "Login to an Artifact Registry repository",
Use: "login [registry]",
Short: "Login to an Artifact Registry repository",
Example: `
Log in with username and password from command line flags:
lkar login -u username -p password localhost:5000
Log in with username and password from stdin:
lkar login -u username --password-stdin localhost:5000
Log in with username and password in an interactive terminal and no TLS check:
lkar login --insecure localhost:5000
`,
Args: cobra.ExactArgs(1),
PreRunE: setup,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -69,7 +79,11 @@ var (
return fmt.Errorf("password is required")
}
}
req, err := http.NewRequestWithContext(cmd.Context(), http.MethodGet, url()+"/_auth/"+repository, nil)
u := urlWithType() + "/_auth/login"
if repository != "" {
u = urlWithType() + fmt.Sprintf("/_auth/%s/login", repository)
}
req, err := http.NewRequestWithContext(cmd.Context(), http.MethodGet, u, nil)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/lkar/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func newPkgCmd(typ string) *cobra.Command {
newPkgUploadCmd(typ),
newPkgDownloadCmd(typ),
newPkgDeleteCmd(typ),
newPkgSetupCmd(typ),
)
return pkgCmd
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/lkar/packages_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func newPkgDeleteCmd(typ string) *cobra.Command {
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, url(typ)+"/"+repository+"/"+args[1], nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, urlWithType(typ)+"/"+repository+"/"+args[1], nil)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/lkar/packages_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func newPkgDownloadCmd(typ string) *cobra.Command {
if _, err := os.Stat(filepath.Dir(output)); err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url(typ)+"/"+repository+"/"+args[1], nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, urlWithType(typ)+"/"+repository+"/"+args[1], nil)
if err != nil {
return err
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/lkar/packages_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ func newPkgListCmd(typ string) *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url(typ)+"/_packages/"+repository, nil)
u := fmt.Sprintf("%s/_packages/%s/%s", url(), typ, repository)
if urlHasType() {
u = fmt.Sprintf("%s/_packages/%s", url(), repository)
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return err
}
Expand Down
110 changes: 110 additions & 0 deletions cmd/lkar/packages_setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright 2023 Linka Cloud All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"context"
"fmt"
"os"
"runtime"
"strings"

"github.com/spf13/cobra"

"go.linka.cloud/artifact-registry/pkg/packages/apk"
"go.linka.cloud/artifact-registry/pkg/packages/deb"
"go.linka.cloud/artifact-registry/pkg/packages/rpm"
)

func newPkgSetupCmd(typ string) *cobra.Command {
var (
force bool
use string
args int
setup func(ctx context.Context, args []string) error
)
scheme := "https"
if plainHTTP {
scheme = "http"
}
var prefix string
switch strings.Split(registry, ".")[0] {
case "apk", "deb", "rpm":
prefix = "/"
default:
prefix = "/" + typ + "/"
}
switch typ {
case "apk":
use = fmt.Sprintf("setup [repository] [branch] [apk-repository]")
args = 3
setup = func(ctx context.Context, args []string) error {
return apk.Setup(ctx, apk.SetupArgs{
User: user,
Password: pass,
Scheme: scheme,
Host: registry,
Path: prefix + repository,
Branch: args[1],
Repository: args[2],
}, force)
}
case "deb":
use = fmt.Sprintf("setup [repository] [distribution] [component]")
args = 3
setup = func(ctx context.Context, args []string) error {
return deb.Setup(ctx, deb.SetupArgs{
User: user,
Password: pass,
Scheme: scheme,
Host: registry,
Path: prefix + repository,
Name: strings.Replace(repository, "/", "-", -1),
Dist: args[1],
Component: args[2],
}, force)
}
case "rpm":
use = fmt.Sprintf("setup [repository]")
args = 1
setup = func(ctx context.Context, args []string) error {
return rpm.Setup(ctx, rpm.SetupArgs{
User: user,
Password: pass,
Scheme: scheme,
Host: registry,
Path: prefix + repository,
}, force)
}
}
cmd := &cobra.Command{
Use: use,
Short: fmt.Sprintf("Setup %s repository on the machine", typ),
Args: cobra.ExactArgs(args),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if runtime.GOOS != "linux" {
return fmt.Errorf("command only supported on Linux")
}
// Check if the user has root privileges
if os.Geteuid() != 0 {
return fmt.Errorf("please run as root or sudo")
}
return setup(ctx, args)
},
}
cmd.Flags().BoolVar(&force, "force", false, "Force setup")
return cmd
}
2 changes: 1 addition & 1 deletion cmd/lkar/packages_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func newPkgUploadCmd(typ string) *cobra.Command {
return err
}
pw := newProgressReader(f, i.Size())
req, err := http.NewRequestWithContext(ctx, http.MethodPut, url(typ)+"/"+repository+upload(args), pw)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, urlWithType(typ)+"/"+repository+upload(args), pw)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/lkar/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ var (
Aliases: []string{"repo", "repos"},
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
u := url() + "/_repositories/" + repository
u := urlWithType() + "/_repositories/" + repository
if repository == "" {
u = url() + "/_repositories"
u = urlWithType() + "/_repositories"
}
req, err := http.NewRequestWithContext(cmd.Context(), http.MethodGet, u, nil)
if err != nil {
Expand Down
23 changes: 17 additions & 6 deletions cmd/lkar/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,42 @@ import (
"crypto/tls"
"io"
"net/http"
"slices"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/dustin/go-humanize"
"github.com/sirupsen/logrus"

"go.linka.cloud/artifact-registry/pkg/packages"
)

func formatSize(v any) string {
return humanize.Bytes(uint64(v.(int64)))
}

func url(typ ...string) string {
scheme := "https"
if plainHTTP {
scheme = "http"
}
base := scheme + "://" + registry
func urlWithType(typ ...string) string {
base := url()
if len(typ) == 0 || strings.HasPrefix(registry, typ[0]+".") {
return base
}
return base + "/" + typ[0]
}

func urlHasType() bool {
return slices.Contains(packages.Providers(), strings.Split(registry, ".")[0])
}

func url() string {
scheme := "https"
if plainHTTP {
scheme = "http"
}
return scheme + "://" + registry
}

func repoURL() string {
if repository == "" {
return registry
Expand Down

0 comments on commit 0eb603c

Please sign in to comment.