v1-testing #1
83
.gitea/workflows/build.yaml
Normal file
83
.gitea/workflows/build.yaml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
name: Actions Build Binary
|
||||||
|
run-name: ${{ gitea.actor }} is building new image 🚀
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build-Binary:
|
||||||
|
runs-on: soaska
|
||||||
|
steps:
|
||||||
|
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||||
|
- name: Install Node.js, curl and go
|
||||||
|
run: |
|
||||||
|
apk add --no-cache nodejs curl go git
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
|
- name: Install go dependencies
|
||||||
|
run: |
|
||||||
|
go mod download
|
||||||
|
- name: Build Binary
|
||||||
|
run: |
|
||||||
|
go build -o $(basename ${{ gitea.repository }}) .
|
||||||
|
env:
|
||||||
|
ENVIRONMENT: production
|
||||||
|
- name: Upload binary to soaska.ru
|
||||||
|
run: |
|
||||||
|
package_name=$(basename ${{ gitea.repository }})
|
||||||
|
branch_name=$(git rev-parse --abbrev-ref HEAD)
|
||||||
|
current_date=$(git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M-%S')
|
||||||
|
curl --user ${{ secrets.username }}:${{ secrets.password }} \
|
||||||
|
--upload-file $package_name \
|
||||||
|
https://soaska.ru/api/packages/${{ secrets.username }}/generic/$package_name-$branch_name/$current_date/$package_name
|
||||||
|
env:
|
||||||
|
ENVIRONMENT: production
|
||||||
|
Build-Docker-Image:
|
||||||
|
runs-on: soaska
|
||||||
|
needs: Build-Binary
|
||||||
|
steps:
|
||||||
|
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||||
|
- name: Install Node.js and curl
|
||||||
|
run: |
|
||||||
|
apk add --no-cache nodejs curl git
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
|
- name: Install Docker
|
||||||
|
run: |
|
||||||
|
apk add --no-cache docker
|
||||||
|
- name: Start Docker service
|
||||||
|
run: |
|
||||||
|
dockerd &
|
||||||
|
sleep 5
|
||||||
|
docker info
|
||||||
|
- name: Get Binary from soaska.ru
|
||||||
|
run: |
|
||||||
|
package_name=$(basename ${{ gitea.repository }})
|
||||||
|
branch_name=$(git rev-parse --abbrev-ref HEAD)
|
||||||
|
current_date=$(git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M-%S')
|
||||||
|
curl --user ${{ secrets.username }}:${{ secrets.password }} \
|
||||||
|
--output main \
|
||||||
|
https://soaska.ru/api/packages/${{ secrets.username }}/generic/$package_name-$branch_name/$current_date/$package_name
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
- name: Build Dockerfile
|
||||||
|
run: |
|
||||||
|
docker build -t $(basename ${{ github.repository}} | tr '[:upper:]' '[:lower:]') .
|
||||||
|
docker image ls
|
||||||
|
- name: Upload Docker image to soaska.ru
|
||||||
|
run: |
|
||||||
|
package_name=$(basename ${{ github.repository}} | tr '[:upper:]' '[:lower:]')
|
||||||
|
branch_name=$(git rev-parse --abbrev-ref HEAD | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
docker login -u ${{ secrets.username }} -p ${{ secrets.password }} soaska.ru
|
||||||
|
docker tag $package_name:latest soaska.ru/${{ secrets.username }}/$package_name:$branch_name
|
||||||
|
docker tag $package_name:latest soaska.ru/${{ secrets.username }}/$package_name:latest
|
||||||
|
docker push soaska.ru/${{ secrets.username }}/$package_name:$branch_name
|
||||||
|
docker push soaska.ru/${{ secrets.username }}/$package_name:latest
|
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
# ---> Go
|
# ---> Go
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
@ -21,3 +23,13 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
=======
|
||||||
|
.env
|
||||||
|
.vscode
|
||||||
|
icon.jpg
|
||||||
|
>>>>>>> beta
|
||||||
|
=======
|
||||||
|
.env
|
||||||
|
.vscode
|
||||||
|
icon.jpg
|
||||||
|
>>>>>>> beta
|
||||||
|
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
FROM alpine
|
||||||
|
WORKDIR /root/
|
||||||
|
COPY main .
|
||||||
|
CMD ["./main"]
|
8
LICENSE
8
LICENSE
@ -6,4 +6,12 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
=======
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
>>>>>>> beta
|
||||||
|
=======
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
>>>>>>> beta
|
||||||
|
6
example.env
Normal file
6
example.env
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Примеры переменных
|
||||||
|
S3_ACCESS_KEY_ID=your_access_key_id
|
||||||
|
S3_SECRET_ACCESS_KEY=your_secret_access_key
|
||||||
|
S3_BUCKET_NAME=your_bucket_name
|
||||||
|
S3_ENDPOINT_URL=your_endpoint
|
||||||
|
PORT=8080
|
20
go.mod
Normal file
20
go.mod
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
module soaska.ru/soaska/MinIO-Share-S3
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gorilla/mux v1.8.1
|
||||||
|
github.com/minio/minio-go v6.0.14+incompatible
|
||||||
|
)
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.8.4 // indirect
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
golang.org/x/crypto v0.18.0 // indirect
|
||||||
|
golang.org/x/net v0.20.0 // indirect
|
||||||
|
golang.org/x/sys v0.16.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
)
|
26
go.sum
Normal file
26
go.sum
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||||
|
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
|
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
|
||||||
|
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||||
|
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||||
|
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||||
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
|
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||||
|
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
40
readme.md
Normal file
40
readme.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# MinIO Share S3
|
||||||
|
|
||||||
|
MinIO Share S3 is a project that enables users to embed links to objects in MinIO and easily share them with others.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Object Embedding**: Users can generate embeddable links for objects stored in MinIO.
|
||||||
|
- **Easy Sharing**: The generated links can be easily shared with others, allowing them to access the objects.
|
||||||
|
- **Access Control**: Users can control the access permissions for the shared objects, ensuring data security using MinIO polices.
|
||||||
|
- **Simplified Workflow**: MinIO Share S3 provides a simple usage to share all your files in bucket
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To install MinIO Share S3, follow these steps:
|
||||||
|
|
||||||
|
1. Clone the repository: `git clone https://soaska.ru/soaska/minio-share-s3.git`
|
||||||
|
2. Install the required dependencies: `go mod download`
|
||||||
|
3. Configure the MinIO connection settings in the `.env` file.
|
||||||
|
4. Start the application: `go run`
|
||||||
|
|
||||||
|
You also can download precompiled binary from packages or set up docker container using `soaska.ru/soaska/minio-share-s3:master` image.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Once the application is running, you can perform the following actions:
|
||||||
|
|
||||||
|
1. Upload objects to MinIO.
|
||||||
|
2. Generate access key and set up polices.
|
||||||
|
3. Set up MinIO Share S3.
|
||||||
|
4. Share links!
|
||||||
|
|
||||||
|
All environment variables are described in `sample.env` file.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! If you would like to contribute to MinIO Share S3, please open issue.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MinIO Share S3 is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
130
run.go
Normal file
130
run.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
"github.com/minio/minio-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Get environment variables
|
||||||
|
accessKeyID, secretAccessKey, bucketName, endpoint, port := getEnv()
|
||||||
|
|
||||||
|
// Initialize MinIO client
|
||||||
|
minioClient, err := minio.New(endpoint, accessKeyID, secretAccessKey, true)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new router
|
||||||
|
router := mux.NewRouter()
|
||||||
|
|
||||||
|
// Define the file handler
|
||||||
|
router.HandleFunc("/{path:.*}", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("Received request: %s %s", r.Method, r.RequestURI)
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
path := vars["path"]
|
||||||
|
|
||||||
|
log.Print("Path: ", path)
|
||||||
|
|
||||||
|
// Get the file from S3
|
||||||
|
object, err := minioClient.GetObject(bucketName, path, minio.GetObjectOptions{})
|
||||||
|
if err != nil {
|
||||||
|
if minio.ToErrorResponse(err).Code == "NoSuchKey" {
|
||||||
|
log.Printf("Object not found in S3: %s", err)
|
||||||
|
http.Error(w, "Object not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Error getting object from S3: %s", err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the object info
|
||||||
|
info, err := object.Stat()
|
||||||
|
if err != nil {
|
||||||
|
if minio.ToErrorResponse(err).Code == "NoSuchKey" {
|
||||||
|
log.Printf("Object not found in S3: %s", err)
|
||||||
|
http.Error(w, "Object not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Error getting object info: %s", err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the content type header
|
||||||
|
contentType := info.ContentType
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
|
||||||
|
// Copy the file to the response writer
|
||||||
|
_, err = io.Copy(w, object)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error copying file to response writer: %s", err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}).Methods("GET")
|
||||||
|
|
||||||
|
router.Use(loggingMiddleware)
|
||||||
|
|
||||||
|
// Start the server
|
||||||
|
|
||||||
|
if port == "" {
|
||||||
|
port = "8080"
|
||||||
|
}
|
||||||
|
addr := fmt.Sprintf(":%s", port)
|
||||||
|
log.Printf("Server listening on %s", addr)
|
||||||
|
log.Fatal(http.ListenAndServe(addr, router))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEnv() (string, string, string, string, string) {
|
||||||
|
if os.Getenv("ENVIRONMENT") != "production" {
|
||||||
|
err := godotenv.Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error loading .env file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get environment variables
|
||||||
|
port := os.Getenv("PORT")
|
||||||
|
accessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
|
||||||
|
secretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
|
||||||
|
bucketName := os.Getenv("S3_BUCKET_NAME")
|
||||||
|
endpoint := os.Getenv("S3_ENDPOINT_URL")
|
||||||
|
|
||||||
|
return accessKeyID, secretAccessKey, bucketName, endpoint, port
|
||||||
|
}
|
||||||
|
|
||||||
|
func loggingMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
|
||||||
|
duration := time.Since(startTime)
|
||||||
|
log.Printf("Processed request: %s %s. Duration: %v\n", r.Method, r.RequestURI, duration)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetObjectList(bucketName string, minioClient *minio.Client) ([]string, error) {
|
||||||
|
var objectList []string
|
||||||
|
|
||||||
|
// Get the list of objects
|
||||||
|
objectCh := minioClient.ListObjects(bucketName, "", true, nil)
|
||||||
|
for object := range objectCh {
|
||||||
|
if object.Err != nil {
|
||||||
|
return nil, object.Err
|
||||||
|
}
|
||||||
|
objectList = append(objectList, object.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectList, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user