fix logger

This commit is contained in:
Sergey Zhemoytel 2025-01-31 23:52:08 +03:00
parent a93af62172
commit d7d74741c4
4 changed files with 84 additions and 117 deletions

14
api.go
View file

@ -2,8 +2,9 @@ package main
import ( import (
"net/http" "net/http"
"github.com/go-chi/chi/v5"
"strings" "strings"
"github.com/go-chi/chi/v5"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -14,14 +15,12 @@ func (r *Repository) UploadHandler(w http.ResponseWriter, req *http.Request) {
logger.Error("Authorization header missing") logger.Error("Authorization header missing")
return return
} }
parts := strings.Split(authHeader, " ") parts := strings.Split(authHeader, " ")
if len(parts) != 2 || parts[0] != "Bearer" { if len(parts) != 2 || parts[0] != "Bearer" {
http.Error(w, "Unauthorized", http.StatusUnauthorized) http.Error(w, "Unauthorized", http.StatusUnauthorized)
logger.Error("Invalid Authorization header format") logger.Error("Invalid Authorization header format")
return return
} }
token := parts[1] token := parts[1]
if token != viper.GetString("auth.token") { if token != viper.GetString("auth.token") {
http.Error(w, "Unauthorized", http.StatusUnauthorized) http.Error(w, "Unauthorized", http.StatusUnauthorized)
@ -46,13 +45,14 @@ func (r *Repository) UploadHandler(w http.ResponseWriter, req *http.Request) {
logger.Infof("Uploading package %s for architecture %s", handler.Filename, arch) logger.Infof("Uploading package %s for architecture %s", handler.Filename, arch)
if err := r.SavePackage(arch, handler.Filename, file); err != nil { // Передаем управление в Repository для обработки файла
http.Error(w, "Error saving package", http.StatusInternalServerError) if err := r.ProcessPackage(arch, handler.Filename, file); err != nil {
logger.Errorf("Error saving package: %v", err) http.Error(w, "Error processing package", http.StatusInternalServerError)
logger.Errorf("Error processing package: %v", err)
return return
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte("Package uploaded successfully")) w.Write([]byte("Package uploaded successfully"))
logger.Infof("Package %s uploaded successfully for architecture %s", handler.Filename, arch) logger.Infof("Package %s uploaded successfully for architecture %s", handler.Filename, arch)
} }

View file

@ -10,19 +10,21 @@ var logger *logrus.Logger
func initLogger() { func initLogger() {
logger = &logrus.Logger{ logger = &logrus.Logger{
Out: logrus.StandardLogger().Out, Out: logrus.StandardLogger().Out,
Formatter: logrus.StandardLogger().Formatter, Formatter: &logrus.TextFormatter{},
Level: logrus.InfoLevel, Level: logrus.InfoLevel,
ReportCaller: true, ReportCaller: true,
} }
logLevel := viper.GetString("log.level") logLevel := viper.GetString("log.level")
if logLevel == "debug" { switch logLevel {
case "debug":
logger.SetLevel(logrus.DebugLevel) logger.SetLevel(logrus.DebugLevel)
} else if logLevel == "info" { case "info":
logger.SetLevel(logrus.InfoLevel) logger.SetLevel(logrus.InfoLevel)
} else if logLevel == "warn" { case "warn":
logger.SetLevel(logrus.WarnLevel) logger.SetLevel(logrus.WarnLevel)
} else if logLevel == "error" { case "error":
logger.SetLevel(logrus.ErrorLevel) logger.SetLevel(logrus.ErrorLevel)
default:
logger.SetLevel(logrus.InfoLevel)
} }
} }

106
main.go
View file

@ -1,29 +1,20 @@
package main package main
import ( import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http" "net/http"
"os" "os"
"strings"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware" "github.com/go-chi/chi/v5/middleware"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/kardianos/service" "github.com/kardianos/service"
"log"
) )
var srv service.Service
var logger *log.Logger
func main() { func main() {
viper.SetConfigName("config") viper.SetConfigName("config")
viper.AddConfigPath(".") viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err) logger.Fatalf("Error reading config file: %v", err)
} }
initLogger() initLogger()
repo := NewRepository() repo := NewRepository()
@ -41,12 +32,13 @@ func main() {
logger.Fatal(err) logger.Fatal(err)
} }
if len(os.Args) > 1 { if len(os.Args) > 1 {
if os.Args[1] == "install" { switch os.Args[1] {
case "install":
if err := s.Install(); err != nil { if err := s.Install(); err != nil {
logger.Fatal(err) logger.Fatal(err)
} }
return return
} else if os.Args[1] == "uninstall" { case "uninstall":
if err := s.Uninstall(); err != nil { if err := s.Uninstall(); err != nil {
logger.Fatal(err) logger.Fatal(err)
} }
@ -78,101 +70,15 @@ func (p *serviceProgram) Stop(s service.Service) error {
return nil return nil
} }
type Repository struct {
repoPath string
}
func NewRepository() *Repository {
return &Repository{
repoPath: viper.GetString("repository.path"),
}
}
func (r *Repository) UploadHandler(w http.ResponseWriter, r *http.Request) {
arch := chi.URLParam(r, "arch")
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// Вычисляем контрольную сумму загруженного файла
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
checksum := hex.EncodeToString(hash.Sum(nil))
// Проверяем, существует ли файл с такой контрольной суммой
if r.fileExistsWithChecksum(arch, header.Filename, checksum) {
logger.Info("File already exists with the same checksum, skipping upload.")
w.WriteHeader(http.StatusConflict)
fmt.Fprintf(w, "File already exists with the same checksum.")
return
}
// Возвращаемся к началу файла для записи
file.Seek(0, 0)
// Сохраняем файл в репозиторий
dstPath := fmt.Sprintf("%s/%s/%s", r.repoPath, arch, header.Filename)
if err := os.MkdirAll(fmt.Sprintf("%s/%s", r.repoPath, arch), os.ModePerm); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
out, err := os.Create(dstPath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer out.Close()
if _, err := io.Copy(out, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
logger.Info("File uploaded successfully.")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "File uploaded successfully.")
}
func (r *Repository) fileExistsWithChecksum(arch, filename, checksum string) bool {
filePath := fmt.Sprintf("%s/%s/%s", r.repoPath, arch, filename)
file, err := os.Open(filePath)
if err != nil {
if os.IsNotExist(err) {
return false
}
logger.Error(err)
return false
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
logger.Error(err)
return false
}
existingChecksum := hex.EncodeToString(hash.Sum(nil))
return existingChecksum == checksum
}
func authMiddleware(next http.Handler) http.Handler { func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authToken := r.Header.Get("Authorization") authToken := r.Header.Get("Authorization")
expectedToken := viper.GetString("auth.token") expectedToken := viper.GetString("auth.token")
if authToken != fmt.Sprintf("Bearer %s", expectedToken) { if authToken != "Bearer "+expectedToken {
http.Error(w, "Unauthorized", http.StatusUnauthorized) http.Error(w, "Unauthorized", http.StatusUnauthorized)
logger.Error("Unauthorized access attempt")
return return
} }
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
}) })
}
func initLogger() {
logger = log.New(os.Stdout, "", log.LstdFlags)
} }

View file

@ -1,12 +1,15 @@
package main package main
import ( import (
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"os/exec" "os/exec"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -29,15 +32,51 @@ func NewRepository() *Repository {
} }
} }
// ProcessPackage обрабатывает загруженный пакет
func (r *Repository) ProcessPackage(arch, filename string, body io.Reader) error {
// Преобразуем body к io.ReadSeeker для возможности использовать Seek
readSeeker, ok := body.(io.ReadSeeker)
if !ok {
logger.Errorf("Failed to cast body to io.ReadSeeker for file %s", filename)
return fmt.Errorf("failed to cast body to io.ReadSeeker")
}
// Вычисляем контрольную сумму загруженного файла
hash := sha256.New()
if _, err := io.Copy(hash, readSeeker); err != nil {
logger.Errorf("Error computing checksum for file %s: %v", filename, err)
return err
}
checksum := hex.EncodeToString(hash.Sum(nil))
// Возвращаемся к началу файла для записи
if _, err := readSeeker.Seek(0, 0); err != nil {
logger.Errorf("Error seeking to the beginning of file %s: %v", filename, err)
return err
}
// Проверяем, существует ли файл с такой контрольной суммой
if r.fileExistsWithChecksum(arch, filename, checksum) {
logger.Infof("File %s already exists with the same checksum, skipping upload.", filename)
return nil
}
// Сохраняем пакет
if err := r.SavePackage(arch, filename, readSeeker); err != nil {
logger.Errorf("Error saving package %s: %v", filename, err)
return err
}
return nil
}
func (r *Repository) SavePackage(arch, name string, body io.Reader) error { func (r *Repository) SavePackage(arch, name string, body io.Reader) error {
logger.Infof("Saving package %s for architecture %s", name, arch) logger.Infof("Saving package %s for architecture %s", name, arch)
dir := filepath.Join(r.BasePath, arch) dir := filepath.Join(r.BasePath, arch)
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0755); err != nil {
logger.Errorf("Failed to create directory %s: %v", dir, err) logger.Errorf("Failed to create directory %s: %v", dir, err)
return err return err
} }
filePath := filepath.Join(dir, name) filePath := filepath.Join(dir, name)
file, err := os.Create(filePath) file, err := os.Create(filePath)
if err != nil { if err != nil {
@ -45,7 +84,6 @@ func (r *Repository) SavePackage(arch, name string, body io.Reader) error {
return err return err
} }
defer file.Close() defer file.Close()
_, err = io.Copy(file, body) _, err = io.Copy(file, body)
if err != nil { if err != nil {
logger.Errorf("Failed to copy file content to %s: %v", filePath, err) logger.Errorf("Failed to copy file content to %s: %v", filePath, err)
@ -59,11 +97,32 @@ func (r *Repository) SavePackage(arch, name string, body io.Reader) error {
logger.Errorf("Failed to generate metadata: %v", err) logger.Errorf("Failed to generate metadata: %v", err)
return fmt.Errorf("failed to generate metadata: %w", err) return fmt.Errorf("failed to generate metadata: %w", err)
} }
logger.Infof("Package %s saved successfully for architecture %s", name, arch) logger.Infof("Package %s saved successfully for architecture %s", name, arch)
return nil return nil
} }
func (r *Repository) fileExistsWithChecksum(arch, filename, checksum string) bool {
filePath := filepath.Join(r.BasePath, arch, filename)
file, err := os.Open(filePath)
if err != nil {
if os.IsNotExist(err) {
return false
}
logger.Errorf("Error opening file %s: %v", filePath, err)
return false
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
logger.Errorf("Error computing checksum for file %s: %v", filePath, err)
return false
}
existingChecksum := hex.EncodeToString(hash.Sum(nil))
return existingChecksum == checksum
}
func (r *Repository) GetArch(arch string) string { func (r *Repository) GetArch(arch string) string {
switch strings.ToLower(arch) { switch strings.ToLower(arch) {
case ARCH_X86_64: case ARCH_X86_64: