func (s3 S3ConnectionInfo) Connect() (*minio.Client, error) { var s3Client *minio.Client var err error if s3.SignatureVersion == "2" { s3Client, err = minio.NewV2(s3.Host, s3.AccessKey, s3.SecretKey, false) } else { s3Client, err = minio.NewV4(s3.Host, s3.AccessKey, s3.SecretKey, false) } if err != nil { return nil, err } transport := http.DefaultTransport transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: s3.SkipSSLValidation} if s3.SOCKS5Proxy != "" { dialer, err := proxy.SOCKS5("tcp", s3.SOCKS5Proxy, nil, proxy.Direct) if err != nil { fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err) os.Exit(1) } transport.(*http.Transport).Dial = dialer.Dial } s3Client.SetCustomTransport(transport) return s3Client, nil }
// PackageExists returns the ObjectInfo for the given package if it exists in bucket and cl can access that bucket. Otherwise, returns nil and a descriptive error of what happened func PackageExists(cl *s3.Client, bucket, pkg string) (*s3.ObjectInfo, error) { st, err := cl.StatObject(bucket, Name(pkg)) if err != nil { return nil, err } return &st, nil }
// UploadPackage uploads all files in dir to the correct location under bucketName for packageName func UploadPackage(cl *s3.Client, bucketName, packageName, dir string) error { files, err := getFiles(dir) if err != nil { return err } buf, err := tarFiles(dir, files) if err != nil { return err } // upload tarball to S3 if _, err := cl.PutObject(bucketName, Name(packageName), buf, tarContentType); err != nil { return err } return nil }
// NewGit returns the handler to be used for the Git server func NewGit(s3Client *s3.Client, bucketName, tmpDir string) http.Handler { hdl := githttp.New(tmpDir) // hdl.UploadPack = false hdl.FillRepo = func(repoDir string) error { if !strings.HasPrefix(repoDir, tmpDir) { return fmt.Errorf("invalid repoDir in FillRepo (%s)", repoDir) } packageName := repoDir[len(tmpDir)+1:] if err := os.MkdirAll(repoDir, os.ModePerm); err != nil { log.Printf("error creating %s (%s)", repoDir, err) return fmt.Errorf("error creating %s (%s)", repoDir, err) } objInfo, err := storage.PackageExists(s3Client, bucketName, packageName) needsDownload := true if err != nil { if err := gitClone(packageName, repoDir); err != nil { log.Printf("Error git cloning %s (%s)", packageName, err) return err } if err := storage.UploadPackage(s3Client, bucketName, packageName, repoDir); err != nil { log.Printf("Error uploading package %s from %s (%s)", packageName, repoDir, err) } needsDownload = false } if needsDownload { obj, err := s3Client.GetObject(bucketName, objInfo.Key) if err != nil { log.Printf("Error downloading %s from bucket %s (%s)", objInfo.Key, bucketName, err) return err } if err := storage.UntarToDisk(obj, repoDir); err != nil { log.Printf("Error untarring %s to %s (%s)", objInfo.Key, repoDir, err) return err } } return nil } return hdl }
// Index is the handler for the front page of the server func index(s3Client *s3.Client, bucketName string, tplCtx tpl.Context) (http.Handler, error) { tpl, err := tplCtx.Prepare(tpl.NewFiles("index.html")) if err != nil { return nil, err } tpl = tpl.Funcs(funcMap) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { doneCh := make(chan struct{}) defer close(doneCh) objCh := s3Client.ListObjects(bucketName, "", false, doneCh) i := 0 for range objCh { i++ } data := map[string]interface{}{ "NumObjects": i, } if err := tpl.Execute(w, data); err != nil { http.Error(w, "error executing index template", http.StatusInternalServerError) return } }), nil }