Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
odrling committed Jul 14, 2024
0 parents commit 6c77685
Show file tree
Hide file tree
Showing 13 changed files with 2,192 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Build and push image

on:
push:
branches: ["main", "renovate/*"]
pull_request:
branches: ["main"]

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup S3 bucket
run: docker run -d -e MINIO_DEFAULT_BUCKETS=karaberus -p 9000:9000 bitnami/minio:latest

- name: Run tests
run: go test ./server
env:
KARABERUS_S3_ENDPOINT: localhost:9000
KARABERUS_S3_KEYID: minio
KARABERUS_S3_SECRET: miniosecret
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Producer

A file host using S3 as a backend
74 changes: 74 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module github.com/Japan7/producer

go 1.22.5

require (
github.com/danielgtaylor/huma/v2 v2.18.0
github.com/gofiber/fiber/v2 v2.52.5
)

require (
github.com/Jeffail/gabs/v2 v2.6.1 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/danielgtaylor/casing v0.0.0-20210126043903-4e55e6373ac3 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/goccy/go-yaml v1.9.5 // indirect
github.com/graphql-go/graphql v0.8.0 // indirect
github.com/graphql-go/handler v0.2.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron-go/gqlcost v0.2.2 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.10.1 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/danielgtaylor/huma v1.14.2
github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/minio/minio-go/v7 v7.0.73
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/cobra v1.8.1
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.52.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/sys v0.21.0 // indirect
)
900 changes: 900 additions & 0 deletions go.sum

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024 Japan7
package main

import "github.com/Japan7/producer/server"

func main() {
server.MakeCli()
}
43 changes: 43 additions & 0 deletions server/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024 Japan7
package server

import (
"fmt"

"github.com/spf13/cobra"
)

func MakeCli() {
app, api := SetupProducer()

rootCmd := &cobra.Command{
Use: "karaberus",
Short: "Start the karaberus server",
Run: func(cmd *cobra.Command, args []string) {
RunProducer(app, api)
},
}

// Add a command to print the OpenAPI spec.
rootCmd.AddCommand(&cobra.Command{
Use: "openapi",
Short: "Print the OpenAPI spec",
Run: func(cmd *cobra.Command, args []string) {
// Use downgrade to return OpenAPI 3.0.3 YAML since oapi-codegen doesn't
// support OpenAPI 3.1 fully yet. Use `.YAML()` instead for 3.1.
b, _ := api.OpenAPI().DowngradeYAML()
fmt.Println(string(b))
},
})

rootCmd.PersistentFlags().IntVarP(
&CONFIG.Listen.Port,
"port", "p",
CONFIG.Listen.Port,
"Port to listen on",
)

// Run the CLI. When passed no commands, it starts the server.
rootCmd.Execute()
}
102 changes: 102 additions & 0 deletions server/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024 Japan7
package server

import (
"fmt"
"os"
"reflect"
"strconv"
)

type ProducerListenConfig struct {
Host string `envkey:"HOST" default:"0.0.0.0"`
Port int `envkey:"PORT" default:"8140"`
}

func (c ProducerListenConfig) Addr() string {
return fmt.Sprintf("%s:%d", c.Host, c.Port)
}

type ProducerUploadConfig struct {
BodyLimit int `envkey:"BODY_LIMIT" default:"1073741824"`
BaseURL string `envkey:"BASE_URL"`
}

type ProducerS3Config struct {
// S3 host
Endpoint string `envkey:"ENDPOINT"`
// use HTTPS
Secure bool `envkey:"SECURE"`
KeyID string `envkey:"KEYID"`
Secret string `envkey:"SECRET"`
BucketName string `envkey:"BUCKET_NAME" default:"producer"`
}

type ProducerConfig struct {
Listen ProducerListenConfig `env_prefix:"LISTEN"`
Upload ProducerUploadConfig `env_prefix:"UPLOAD"`
S3 ProducerS3Config `env_prefix:"S3"`
}

func getEnvDefault(name string, defaultValue string) string {
envVar := os.Getenv(name)
if envVar != "" {
return envVar
}

return defaultValue
}

func getFieldValue(field_type reflect.StructField, prefix string) string {
envkey := field_type.Tag.Get("envkey")
if envkey == "" {
panic(fmt.Sprintf("envkey is not set for field %s", field_type.Name))
}
default_value := field_type.Tag.Get("default")
return getEnvDefault(prefix+envkey, default_value)
}

func setConfigValue(config_value reflect.Value, config_type reflect.Type, prefix string) {
for i := 0; i < config_type.NumField(); i++ {
field_type := config_type.Field(i)
field := config_value.FieldByName(field_type.Name)

switch field_type.Type.Kind() {
case reflect.String:
field.SetString(getFieldValue(field_type, prefix))
case reflect.Int:
value := getFieldValue(field_type, prefix)
int_value, err := strconv.Atoi(value)
if err != nil {
panic(err)
}
field.SetInt(int64(int_value))
case reflect.Bool:
field.SetBool(getFieldValue(field_type, prefix) != "")
case reflect.Struct:
field_prefix := prefix + field_type.Tag.Get("env_prefix") + "_"
setConfigValue(field, field_type.Type, field_prefix)
default:
panic(fmt.Sprintf("unknown field type for field %s: %s", field_type.Name, field_type.Type.Name()))
}
}
}

func getProducerConfig() ProducerConfig {
config := ProducerConfig{}

config_value := reflect.ValueOf(&config).Elem()
config_type := reflect.TypeOf(config)

setConfigValue(config_value, config_type, "PRODUCER_")

if config.Upload.BaseURL == "" {
// default to listen address
config.Upload.BaseURL = "http://" + config.Listen.Addr()
}

return config
}

var CONFIG = getProducerConfig()
Loading

0 comments on commit 6c77685

Please sign in to comment.