Added Docker release for CLI, updated documentation, added docker-specific features to CLI

This commit is contained in:
Marc Ole Bulling
2025-08-08 23:29:53 +02:00
parent 9a574dbed5
commit 25fb6351be
7 changed files with 202 additions and 8 deletions

View File

@@ -0,0 +1,32 @@
name: Docker Publish CLI Custom Release Multiarch
on:
workflow_dispatch:
inputs:
tagname:
description: 'Tag name to be built'
required: true
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git checkout tags/${{ github.event.inputs.tagname }}
- name: install buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v1
with:
version: latest
- name: login to docker hub
run: echo "${{ secrets.DOCKER_PW }}" | docker login -u "${{ secrets.DOCKER_USER }}" --password-stdin
- name: build and push the image
run: |
docker buildx build -f Dockerfile.cli-tool --push --tag f0rc3/gokapi-cli:${{ github.event.inputs.tagname }} --platform linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 .

20
Dockerfile cli-tool Normal file
View File

@@ -0,0 +1,20 @@
FROM golang:1.24.0-alpine AS build_base
## Usage:
## docker build . -f Dockerfile.cli-tool -t gokapi-cli
## docker run --rm -v gokapi-cli-config:/app/config gokapi-cli
RUN mkdir /compile
COPY go.mod /compile
RUN cd /compile && go mod download
COPY . /compile
RUN cd /compile && go generate ./... && CGO_ENABLED=0 go build -ldflags="-s -w -X 'github.com/forceu/gokapi/internal/environment.IsDocker=true' -X 'github.com/forceu/gokapi/internal/environment.Builder=Project Docker File' -X 'github.com/forceu/gokapi/internal/environment.BuildTime=$(date)'" -o /compile/gokapi-cli github.com/forceu/gokapi/cmd/cli-uploader
FROM alpine:3.19
COPY --from=build_base /compile/gokapi-cli /app/gokapi-cli
WORKDIR /app
ENTRYPOINT ["/app/gokapi-cli"]

20
Dockerfile.cli-tool Normal file
View File

@@ -0,0 +1,20 @@
FROM golang:1.24.0-alpine AS build_base
## Usage:
## docker build . -f Dockerfile.cli-tool -t gokapi-cli
## docker run -it --rm -v gokapi-cli-config:/app/config gokapi-cli
RUN mkdir /compile
COPY go.mod /compile
RUN cd /compile && go mod download
COPY . /compile
RUN cd /compile && go generate ./... && CGO_ENABLED=0 go build -ldflags="-s -w -X 'github.com/forceu/gokapi/internal/environment.IsDocker=true' -X 'github.com/forceu/gokapi/internal/environment.Builder=Project Docker File' -X 'github.com/forceu/gokapi/internal/environment.BuildTime=$(date)'" -o /compile/gokapi-cli github.com/forceu/gokapi/cmd/cli-uploader
FROM alpine:3.19
COPY --from=build_base /compile/gokapi-cli /app/gokapi-cli
WORKDIR /app
ENTRYPOINT ["/app/gokapi-cli"]

View File

@@ -6,14 +6,17 @@ import (
"github.com/forceu/gokapi/cmd/cli-uploader/cliapi"
"github.com/forceu/gokapi/cmd/cli-uploader/cliconfig"
"github.com/forceu/gokapi/cmd/cli-uploader/cliflags"
"github.com/forceu/gokapi/internal/environment"
"github.com/forceu/gokapi/internal/helper"
"os"
)
func main() {
cliflags.Init(cliconfig.DockerFolderConfigFile, cliconfig.DockerFolderUpload)
mode := cliflags.Parse()
switch mode {
case cliflags.ModeLogin:
cliconfig.CreateLogin()
doLogin()
case cliflags.ModeLogout:
doLogout()
case cliflags.ModeUpload:
@@ -23,6 +26,11 @@ func main() {
}
}
func doLogin() {
checkDockerFolders()
cliconfig.CreateLogin()
}
func processUpload() {
cliconfig.Load()
uploadParam := cliflags.GetUploadParameters()
@@ -36,11 +44,12 @@ func processUpload() {
if uploadParam.JsonOutput {
jsonStr, _ := json.Marshal(result)
fmt.Println(string(jsonStr))
} else {
fmt.Println("File uploaded successfully")
fmt.Println("File ID: " + result.Id)
fmt.Println("File Download URL: " + result.UrlDownload)
return
}
fmt.Println("Upload successful")
fmt.Println("File Name: " + result.Name)
fmt.Println("File ID: " + result.Id)
fmt.Println("File Download URL: " + result.UrlDownload)
}
func doLogout() {
@@ -52,3 +61,16 @@ func doLogout() {
}
fmt.Println("Logged out. To login again, run: gokapi-cli login")
}
func checkDockerFolders() {
if !environment.IsDockerInstance() {
return
}
if !helper.FolderExists(cliconfig.DockerFolderConfig) {
fmt.Println("Warning: Docker folder does not exist, configuration will be lost when creating a new container")
helper.CreateDir(cliconfig.DockerFolderConfig)
}
if !helper.FolderExists(cliconfig.DockerFolderUpload) {
helper.CreateDir(cliconfig.DockerFolderUpload)
}
}

View File

@@ -15,6 +15,10 @@ import (
const minGokapiVersionInt = 20100
const minGokapiVersionStr = "2.1.0"
const DockerFolderConfig = "/app/config/"
const DockerFolderConfigFile = DockerFolderConfig + "config.json"
const DockerFolderUpload = "/upload/"
type configFile struct {
Url string `json:"Url"`
Apikey string `json:"Apikey"`

View File

@@ -2,7 +2,9 @@ package cliflags
import (
"fmt"
"github.com/forceu/gokapi/internal/environment"
"os"
"path/filepath"
"strconv"
)
@@ -13,6 +15,9 @@ const (
ModeInvalid
)
var dockerConfigFile string
var dockerUploadFolder string
type UploadConfig struct {
File string
JsonOutput bool
@@ -22,6 +27,11 @@ type UploadConfig struct {
Password string
}
func Init(dockerConfigPath, dockerUploadPath string) {
dockerConfigFile = dockerConfigPath
dockerUploadFolder = dockerUploadPath
}
func Parse() int {
if len(os.Args) < 2 {
printUsage()
@@ -59,8 +69,17 @@ func GetUploadParameters() UploadConfig {
}
}
if result.File == "" {
fmt.Println("ERROR: Missing parameter -f")
os.Exit(2)
if environment.IsDockerInstance() {
ok, dockerFile := getDockerUpload()
if !ok {
fmt.Println("ERROR: Missing parameter -f and no file or more than one file found in " + dockerUploadFolder)
os.Exit(2)
}
result.File = dockerFile
} else {
fmt.Println("ERROR: Missing parameter -f")
os.Exit(2)
}
}
if result.ExpiryDownloads < 0 {
result.ExpiryDownloads = 0
@@ -71,7 +90,37 @@ func GetUploadParameters() UploadConfig {
return result
}
func getDockerUpload() (bool, string) {
if !environment.IsDockerInstance() {
return false, ""
}
entries, err := os.ReadDir(dockerUploadFolder)
if err != nil {
return false, ""
}
var fileName string
var fileFound bool
for _, entry := range entries {
if entry.Type().IsRegular() {
if fileFound {
// More than one file exist
return false, ""
}
fileName = entry.Name()
fileFound = true
}
}
if !fileFound {
return false, ""
}
return true, filepath.Join(dockerUploadFolder, fileName)
}
func GetConfigLocation() string {
if environment.IsDockerInstance() {
return dockerConfigFile
}
for i := 2; i < len(os.Args); i++ {
switch os.Args[i] {
case "-c":

View File

@@ -210,13 +210,20 @@ Migrating Redis (``127.0.0.1:6379, User: test, Password: 1234, Prefix: gokapi_,
CLI Tool
********************************
Gokapi also has a CLI tool that allows uploads from the command line. Binaries are avaible on the release page (``gokapi-cli``) for Linux, Windows and MacOs. To compile it yourself, download the repository and run ``make build-cli`` in the top directory.
Gokapi also has a CLI tool that allows uploads from the command line. Binaries are avaible on the `Github release page <https://github.com/Forceu/Gokapi/releases>`_ for Linux, Windows and MacOS. To compile it yourself, download the repository and run ``make build-cli`` in the top directory.
Alternatively you can use the tool with Docker, although it will be slightly less user-friendly.
.. note::
Gokapi v2.1.0 or newer is required to use the CLI tool.
Login
=================================
First you need to login with the command ``gokapi-cli login``. You will then be asked for your server URL and a valid API key with upload permission. If end-to-end encryption is enabled, you will also need to enter your encyption key. By default the login data is saved to ``gokapi-cli.json``, but you can define a different location with the ``-c`` parameter.
To logout, either delete the configuration file or run ``gokapi-cli logout``.
.. warning::
@@ -224,6 +231,17 @@ To logout, either delete the configuration file or run ``gokapi-cli logout``.
The configuration file contains the login data as plain text.
Docker
---------------------------------
If you are using Docker, your config will always be saved to ``/app/config/config.json`` and the location cannot be changed. To login, execute the following command:
docker run -it --rm -v gokapi-cli-config:/app/config docker.io/f0rc3/gokapi-cli:latest login
The volume ``gokapi-cli-config:/app/config`` is not required if you re-use the container, but it is still highly recommended. If the volume is not mounted, you will need to log in again after every new container creation.
Upload
=================================
@@ -244,11 +262,40 @@ To upload a file, simply run ``gokapi-cli upload -f /path/to/file``. By default
| -c [path] | Use the configuration file specified |
+-----------------------------+---------------------------------------------------+
Example: Uploading the file ``/tmp/example``. It will expire in 10 days, has unlimited downloads and requires the password ``abcd``:
::
gokapi-cli upload -f /tmp/example --expiry-days 10 --password abcd
.. warning::
If you are using end-to-end encryption, do not upload other encrypted files simultaneously to avoid race conditions.
Docker
---------------------------------
As a Docker container cannot access your host files without a volume, you will need to mount the folder that contains your file to upload and then specify the internal file path with ``-f``. If no ``-f`` parameter is supplied and only a single file exists in the container folder ``/upload/``, this file will be uploaded.
Example: Uploading the file ``/tmp/example``. It will expire after 5 downloads, has no time expiry and has no password.
::
docker run --rm -v gokapi-cli-config:/app/config -v /tmp/:/upload/ docker.io/f0rc3/gokapi-cli:latest upload -f /upload/example --expiry-downloads 5
Example: Uploading the file ``/tmp/single/example``. There is no other file in the folder ``/tmp/single/``.
::
docker run --rm -v gokapi-cli-config:/app/config -v /tmp/single/:/upload/ docker.io/f0rc3/gokapi-cli:latest upload
Example: Uploading the file ``/tmp/multiple/example``. There are other files in the folder ``/tmp/multiple/``.
::
docker run --rm -v gokapi-cli-config:/app/config -v /tmp/multiple/example:/upload/example docker.io/f0rc3/gokapi-cli:latest upload
.. _api: