Skip to content

Commit

Permalink
use standard lib
Browse files Browse the repository at this point in the history
  • Loading branch information
CMGS committed Jul 2, 2024
1 parent ea85dfa commit 4fa15db
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 124 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ COPY . .
ENV GOPROXY https://goproxy.cn,direct
RUN apt update -y \
apt install -y libcephfs-dev librbd-dev librados-dev build-essential
RUN make deps CN=1
RUN make build CN=1
RUN make deps
RUN make build
RUN ./bin/vmihub --version

FROM debian:bookworm
Expand Down
5 changes: 2 additions & 3 deletions client/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"net/http"
"net/url"

"github.com/cockroachdb/errors"
"github.com/projecteru2/vmihub/client/terrors"
"github.com/projecteru2/vmihub/client/types"
)
Expand Down Expand Up @@ -105,7 +104,7 @@ func (i *APIImpl) HTTPDelete(ctx context.Context, reqURL string, urlQueryValues

func GetCommonRawResponse(resp *http.Response) (resRaw map[string]any, err error) {
if resp.StatusCode != http.StatusOK {
err = errors.Wrapf(terrors.ErrHTTPError, "status: %d, error: %v", resp.StatusCode, resRaw["error"])
err = fmt.Errorf("status: %d, error: %v, %w", resp.StatusCode, resRaw["error"], terrors.ErrHTTPError)
return
}
bs, err := io.ReadAll(resp.Body)
Expand All @@ -115,7 +114,7 @@ func GetCommonRawResponse(resp *http.Response) (resRaw map[string]any, err error
resRaw = map[string]any{}
err = json.Unmarshal(bs, &resRaw)
if err != nil {
err = errors.Wrapf(err, "failed to decode response: %s", string(bs))
err = fmt.Errorf("failed to decode response: %s, %w", string(bs), err)
return
}
return
Expand Down
15 changes: 7 additions & 8 deletions client/image/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"path/filepath"
"strconv"

"github.com/cockroachdb/errors"
"github.com/dustin/go-humanize"
"github.com/projecteru2/vmihub/client/terrors"
"github.com/projecteru2/vmihub/client/types"
Expand Down Expand Up @@ -142,7 +141,7 @@ func (i *APIImpl) DownloadImageChunk(ctx context.Context, chunk *types.ChunkSlic
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return errors.Wrapf(terrors.ErrNetworkError, "status: %s", resp.StatusCode)
return fmt.Errorf("status: %v, %w", resp.StatusCode, terrors.ErrNetworkError)
}

chunkSliceFile := chunk.SliceFileIndexPath(int(cIdx))
Expand All @@ -152,7 +151,7 @@ func (i *APIImpl) DownloadImageChunk(ctx context.Context, chunk *types.ChunkSlic

out, err := os.OpenFile(chunkSliceFile, os.O_WRONLY|os.O_CREATE, 0766)
if err != nil {
return errors.Wrapf(err, "failed to create %s", chunkSliceFile)
return fmt.Errorf("failed to create %s, %w", chunkSliceFile, err)
}
defer out.Close()

Expand All @@ -172,14 +171,14 @@ func (i *APIImpl) UploadImageChunk(ctx context.Context, chunk *types.ChunkSlice,
filePath := chunk.Filepath()
fp, err := os.Open(filePath)
if err != nil {
return errors.Wrapf(err, "failed to open %s", filePath)
return fmt.Errorf("failed to open %s, %w", filePath, err)
}
defer fp.Close()
// get slice part
offset := cIdx * chunk.ChunkSize
_, err = fp.Seek(offset, 0)
if err != nil {
return errors.Wrapf(err, "failed to seek to %d", offset)
return fmt.Errorf("failed to seek to %d, %w", offset, err)
}
reader := io.LimitReader(fp, chunk.ChunkSize)

Expand All @@ -188,11 +187,11 @@ func (i *APIImpl) UploadImageChunk(ctx context.Context, chunk *types.ChunkSlice,

part, err := writer.CreateFormFile("file", filepath.Base(filePath))
if err != nil {
return errors.Wrapf(err, "failed to create form field")
return fmt.Errorf("failed to create form field, %w", err)
}

if _, err := io.Copy(part, reader); err != nil {
return errors.Wrapf(err, "failed to copy")
return fmt.Errorf("failed to copy file content, %w", err)
}
_ = writer.Close()

Expand Down Expand Up @@ -228,7 +227,7 @@ func mergeSliceFile(chunk *types.ChunkSlice, nChunks int) error {
chunkSliceFile := chunk.SliceFilePath()
dest, err := os.OpenFile(chunk.SliceFilePath(), os.O_WRONLY|os.O_CREATE, 0766)
if err != nil {
return errors.Wrapf(err, "failed to create %s", chunkSliceFile)
return fmt.Errorf("failed to create %s, %w", chunkSliceFile, err)
}
defer dest.Close()

Expand Down
39 changes: 19 additions & 20 deletions client/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
Expand All @@ -17,7 +18,6 @@ import (
"strings"

"github.com/cenkalti/backoff/v4"
"github.com/cockroachdb/errors"
"github.com/dustin/go-humanize"
"github.com/panjf2000/ants/v2"

Expand Down Expand Up @@ -62,13 +62,12 @@ func NewAPI(addr string, baseDir string, cred *types.Credential, options ...Opti
if err != nil {
return nil, err
}
err = util.EnsureDir(filepath.Join(baseDir, "image"))
if err != nil {
return nil, errors.Wrapf(terrors.ErrFSError, "failed to create dir: %s", err)
if err := util.EnsureDir(filepath.Join(baseDir, "image")); err != nil {
return nil, fmt.Errorf("failed to create dir %w: %w", err, terrors.ErrFSError)
}
mdb, err := types.NewMetadataDB(baseDir, "images")
if err != nil {
return nil, errors.Wrapf(err, "failed to open db")
return nil, fmt.Errorf("failed to open db: %w", err)
}
img := &APIImpl{
APIImpl: *base.NewAPI(addr, cred),
Expand Down Expand Up @@ -118,11 +117,11 @@ func (i *APIImpl) ListImages(ctx context.Context, username string, pageN, pageSi
resRaw := map[string]any{}
err = json.Unmarshal(bs, &resRaw)
if err != nil {
err = errors.Wrapf(err, "failed to decode response: %s", string(bs))
err = fmt.Errorf("failed to decode response: %w %s", err, string(bs))
return
}
if resp.StatusCode != http.StatusOK {
err = errors.Wrapf(terrors.ErrHTTPError, "status: %d, error: %v", resp.StatusCode, resRaw["error"])
err = fmt.Errorf("status: %d, error: %v, %w", resp.StatusCode, resRaw["error"], terrors.ErrHTTPError)
return
}

Expand Down Expand Up @@ -249,7 +248,7 @@ func (i *APIImpl) startUpload(ctx context.Context, img *types.Image, force bool)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", errors.Wrap(err, "failed to execute http request")
return "", fmt.Errorf("failed to execute http request: %w", err)
}
defer resp.Body.Close()

Expand All @@ -271,7 +270,7 @@ func (i *APIImpl) upload(ctx context.Context, img *types.Image, uploadID string)
filePath := img.Filepath()
fp, err := os.Open(filePath)
if err != nil {
return errors.Wrapf(err, "failed to open %s", filePath)
return fmt.Errorf("failed to open %s: %w", filePath, err)
}
defer fp.Close()

Expand All @@ -284,11 +283,11 @@ func (i *APIImpl) upload(ctx context.Context, img *types.Image, uploadID string)

part, err := m.CreateFormFile("file", filepath.Base(filePath))
if err != nil {
errCh <- errors.Wrap(err, "failed to create form field")
errCh <- fmt.Errorf("failed to create form file: %w", err)
return
}
if _, err = io.Copy(part, fp); err != nil {
errCh <- errors.Wrap(err, "failed copy content from file to part")
errCh <- fmt.Errorf("failed to copy file: %w", err)
return
}
}()
Expand All @@ -300,15 +299,15 @@ func (i *APIImpl) upload(ctx context.Context, img *types.Image, uploadID string)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), r)
if err != nil {
return errors.Wrapf(err, "failed to create http request")
return fmt.Errorf("failed to create http request: %w", err)
}

req.Header.Set("Content-Type", m.FormDataContentType())
_ = i.AddAuth(req)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return errors.Wrap(err, "failed to execute http request")
return fmt.Errorf("failed to execute http request: %w", err)
}
defer resp.Body.Close()

Expand All @@ -319,9 +318,9 @@ func (i *APIImpl) upload(ctx context.Context, img *types.Image, uploadID string)
default:
}
if err != nil {
return errors.Wrapf(err, "failed to push: %s, %s", resp.Status, string(bs))
return fmt.Errorf("failed to push: %s, %s: %w", resp.Status, string(bs), err)
} else { //nolint:revive
return errors.Newf("failed to push: %s, %s", resp.Status, string(bs))
return fmt.Errorf("failed to push: %s, %s", resp.Status, string(bs))
}
}
return nil
Expand Down Expand Up @@ -391,7 +390,7 @@ func (i *APIImpl) GetInfo(ctx context.Context, imgFullname string) (info *types.
case http.StatusNotFound:
return nil, terrors.ErrImageNotFound
default:
return nil, errors.Wrapf(terrors.ErrHTTPError, "status: %d", resp.StatusCode)
return nil, fmt.Errorf("status: %d: %w", resp.StatusCode, terrors.ErrHTTPError)
}
bs, err := io.ReadAll(resp.Body)
if err != nil {
Expand All @@ -404,7 +403,7 @@ func (i *APIImpl) GetInfo(ctx context.Context, imgFullname string) (info *types.
}
dataObj, ok := resRaw["data"]
if !ok {
return nil, errors.Wrapf(terrors.ErrHTTPError, "response json object needs contain data field: %s", string(bs))
return nil, fmt.Errorf("response json object needs contain data field: %s: %w", string(bs), terrors.ErrHTTPError)
}
info = &types.Image{
BaseDir: i.baseDir,
Expand Down Expand Up @@ -453,7 +452,7 @@ func (i *APIImpl) Pull(ctx context.Context, imgName string, policy PullPolicy) (
}

if img.Format == "rbd" {
return nil, errors.Newf("image in rbd format is not alllowed to download")
return nil, fmt.Errorf("image in rbd format is not alllowed to download")
}
if cached, _ := img.Cached(); cached {
return img, nil
Expand Down Expand Up @@ -550,7 +549,7 @@ func (i *APIImpl) downloadWithChunk(ctx context.Context, img *types.Image) (err
for res := range resCh {
finished++
if res.err != nil {
downloadErr = errors.CombineErrors(downloadErr, res.err)
downloadErr = errors.Join(downloadErr, res.err)
}
if finished >= int(nChunks) {
break
Expand Down Expand Up @@ -595,7 +594,7 @@ func (i *APIImpl) download(ctx context.Context, img *types.Image) (err error) {

if resp.StatusCode != http.StatusOK {
bs, _ := io.ReadAll(resp.Body)
return errors.Newf("failed to pull image, status code: %d, body: %s", resp.StatusCode, string(bs))
return fmt.Errorf("failed to pull image, status code: %d, body: %s", resp.StatusCode, string(bs))
}
return i.mdb.CopyFile(img, resp.Body)
}
2 changes: 1 addition & 1 deletion client/terrors/errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package terrors

import "github.com/cockroachdb/errors"
import "errors"

var (
ErrInvalidImageName = errors.New("invalid image name")
Expand Down
7 changes: 3 additions & 4 deletions client/types/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"path/filepath"
"time"

"github.com/cockroachdb/errors"
"github.com/projecteru2/vmihub/client/util"
svctypes "github.com/projecteru2/vmihub/pkg/types"
svcutils "github.com/projecteru2/vmihub/pkg/utils"
Expand All @@ -31,13 +30,13 @@ type MetadataDB struct {
func NewMetadataDB(baseDir, bucket string) (*MetadataDB, error) {
db, err := bolt.Open(filepath.Join(baseDir, "metadata.db"), 0600, &bolt.Options{Timeout: 5 * time.Second})
if err != nil {
return nil, errors.Wrapf(err, "failed to open db")
return nil, fmt.Errorf("failed to open db: %w", err)
}
if err := db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte(bucket))
return err
}); err != nil {
return nil, errors.Wrapf(err, "failed to create bucket for image")
return nil, fmt.Errorf("failed to create bucket: %w", err)
}
return &MetadataDB{
baseDir: baseDir,
Expand Down Expand Up @@ -164,7 +163,7 @@ func (mdb *MetadataDB) update(img *Image, oldEmpty bool) (meta *Metadata, err er
err = mdb.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(mdb.bucket))
if oldEmpty && b.Get([]byte(fullname)) != nil {
return errors.Newf("canflict when load metadata of image %s", fullname)
return fmt.Errorf("canflict when load metadata of image %s", fullname)
}
return b.Put([]byte(fullname), bs)
})
Expand Down
39 changes: 18 additions & 21 deletions client/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package util
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"strconv"

"github.com/cockroachdb/errors"
"github.com/projecteru2/vmihub/client/terrors"
)

Expand Down Expand Up @@ -45,14 +45,12 @@ func ImageSize(fname string) (int64, int64, error) {
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return 0, 0, errors.Wrap(err, stderr.String())
if err := cmd.Run(); err != nil {
return 0, 0, fmt.Errorf("%w %s", err, stderr.String())
}
res := map[string]any{}
err = json.Unmarshal(stdout.Bytes(), &res)
if err != nil {
return 0, 0, errors.Wrapf(err, "failed to unmarshal json: %s", stdout.String())
if err := json.Unmarshal(stdout.Bytes(), &res); err != nil {
return 0, 0, fmt.Errorf("failed to unmarshal json: %w %s", err, stdout.String())
}
virtualSize := res["virtual-size"]
actualSize := res["actual-size"]
Expand All @@ -67,36 +65,37 @@ func GetFileSize(filepath string) (int64, error) {
return fi.Size(), nil
}

func CreateQcow2File(fname string, fmt string, cap int64) error {
func CreateQcow2File(fname string, format string, cap int64) error {
if err := EnsureDir(filepath.Dir(fname)); err != nil {
return err
}

cmd := exec.Command("qemu-img", "create", "-q", "-f", fmt, fname, strconv.FormatInt(cap, 10)) //nolint:gosec
cmd := exec.Command("qemu-img", "create", "-q", "-f", format, fname, strconv.FormatInt(cap, 10)) //nolint:gosec
bs, err := cmd.CombinedOutput()
return errors.Wrapf(err, "failed to create qemu image: %s", string(bs))
if err != nil {
return fmt.Errorf("failed to create qemu image %s: %w", string(bs), err)
}
return nil
}

func Copy(src, dest string) error {
srcF, err := os.OpenFile(src, os.O_RDONLY, 0766)
if err != nil {
return errors.Wrapf(err, "failed to open %s", src)
return fmt.Errorf("failed to open %s: %w", src, err)
}
defer srcF.Close()

if err := EnsureDir(filepath.Dir(dest)); err != nil {
return errors.Wrapf(err, "failed to create dir for %s", dest)
return fmt.Errorf("failed to create dir for %s: %w", dest, err)
}
destF, err := os.OpenFile(dest, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0766)
if err != nil {
return errors.Wrapf(err, "failed to open %s", dest)
return fmt.Errorf("failed to open %s: %w", dest, err)
}
defer destF.Close()

if _, err = io.Copy(destF, srcF); err != nil {
return err
}
return nil
_, err = io.Copy(destF, srcF)
return err
}

func Move(src, dest string) error {
Expand All @@ -115,12 +114,10 @@ func GetRespData(resp *http.Response) (data []byte, err error) {
resRaw := map[string]any{}
err = json.Unmarshal(bs, &resRaw)
if err != nil {
err = errors.Wrapf(err, "failed to decode response: %s", string(bs))
return
return data, fmt.Errorf("failed to decode response: %w %s", err, string(bs))
}
if resp.StatusCode != http.StatusOK {
err = errors.Wrapf(terrors.ErrHTTPError, "status: %d, error: %v", resp.StatusCode, resRaw["error"])
return
return data, fmt.Errorf("%w status: %d, error: %v", terrors.ErrHTTPError, resp.StatusCode, resRaw["error"])
}
val, ok := resRaw["data"]
if !ok {
Expand Down
Loading

0 comments on commit 4fa15db

Please sign in to comment.