Skip to content
This repository has been archived by the owner on Oct 29, 2024. It is now read-only.

Add Bugsnag to report errors #58

Merged
merged 16 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Improve error handling
  • Loading branch information
felipecruz91 committed Sep 7, 2022
commit 3ef724094d00f99df612de0c445320668e76279d
32 changes: 12 additions & 20 deletions vm/internal/backend/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strconv"
"strings"

"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
Expand All @@ -24,19 +23,19 @@ type VolumeSize struct {
Human string
}

func GetVolumesSize(ctx context.Context, cli *client.Client, volumeName string) map[string]VolumeSize {
func GetVolumesSize(ctx context.Context, cli *client.Client, volumeName string) (map[string]VolumeSize, error) {
m := make(map[string]VolumeSize)

// Ensure the image is present before creating the container
reader, err := cli.ImagePull(ctx, internal.NsenterImage, types.ImagePullOptions{
Platform: "linux/" + runtime.GOARCH,
})
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}
_, err = io.Copy(os.Stdout, reader)
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

resp, err := cli.ContainerCreate(ctx, &container.Config{
Expand All @@ -55,42 +54,36 @@ func GetVolumesSize(ctx context.Context, cli *client.Client, volumeName string)
Privileged: true,
}, nil, nil, "")
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
select {
case err := <-errCh:
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}
case <-statusCh:
}

out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

buf := new(bytes.Buffer)
_, err = buf.ReadFrom(out)
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

output := buf.String()

lines := strings.Split(strings.TrimSuffix(output, "\n"), "\n")
m := make(map[string]VolumeSize)
for _, line := range lines {
s := strings.Split(line, "\t") // e.g. 924 /var/lib/docker/volumes/my-volume
if len(s) != 2 {
Expand Down Expand Up @@ -126,11 +119,10 @@ func GetVolumesSize(ctx context.Context, cli *client.Client, volumeName string)

err = cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{})
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctx)
return m, err
}

return m
return m, nil
}

// byteCountSI converts a size in bytes to a human-readable string in SI (decimal) format.
Expand Down
3 changes: 2 additions & 1 deletion vm/internal/handler/clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ func TestCloneVolume(t *testing.T) {
t.Fatal(err)
}
require.Len(t, clonedVolumeResp.Volumes, 1)
sizes := backend.GetVolumesSize(context.Background(), dockerClient, destVolume)
sizes, err := backend.GetVolumesSize(context.Background(), dockerClient, destVolume)
require.NoError(t, err)
require.Equal(t, int64(16000), sizes[destVolume].Bytes)
require.Equal(t, "16.0 kB", sizes[destVolume].Human)
}
6 changes: 3 additions & 3 deletions vm/internal/handler/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"runtime"
"strings"

"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/volumes-backup-extension/internal"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/volumes-backup-extension/internal"
"github.com/docker/volumes-backup-extension/internal/backend"
"github.com/docker/volumes-backup-extension/internal/log"
"github.com/labstack/echo"
Expand Down
2 changes: 1 addition & 1 deletion vm/internal/handler/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"os"
"runtime"

"github.com/bugsnag/bugsnag-go/v2"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/stdcopy"
Expand Down
6 changes: 4 additions & 2 deletions vm/internal/handler/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ func TestImportTarGzFile(t *testing.T) {

require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
sizes := backend.GetVolumesSize(c.Request().Context(), cli, volume)
sizes, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
require.Equal(t, int64(16000), sizes[volume].Bytes)
require.Equal(t, "16.0 kB", sizes[volume].Human)
}
Expand Down Expand Up @@ -142,7 +143,8 @@ func TestImportTarGzFileShouldRemovePreviousVolumeData(t *testing.T) {

require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
sizes := backend.GetVolumesSize(c.Request().Context(), cli, volume)
sizes, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
require.Equal(t, int64(16000), sizes[volume].Bytes)
require.Equal(t, "16.0 kB", sizes[volume].Human)
}
6 changes: 4 additions & 2 deletions vm/internal/handler/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ func TestLoadImage(t *testing.T) {

require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
sizes := backend.GetVolumesSize(c.Request().Context(), cli, volume)
sizes, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
t.Logf("Volume size after loading image into it: %+v", sizes[volume])
require.Equal(t, int64(16000), sizes[volume].Bytes)
require.Equal(t, "16.0 kB", sizes[volume].Human)
Expand Down Expand Up @@ -169,7 +170,8 @@ func TestLoadImageShouldRemovePreviousVolumeData(t *testing.T) {

require.NoError(t, err)
require.Equal(t, http.StatusOK, rec.Code)
sizes := backend.GetVolumesSize(c.Request().Context(), cli, volume)
sizes, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
t.Logf("Volume size after loading image into it: %+v", sizes[volume])
require.Equal(t, int64(16000), sizes[volume].Bytes)
require.Equal(t, "16.0 kB", sizes[volume].Human)
Expand Down
9 changes: 6 additions & 3 deletions vm/internal/handler/pull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ func TestPullVolume(t *testing.T) {
require.Equal(t, http.StatusCreated, rec.Code)

// Check the content of the volume
m := backend.GetVolumesSize(c.Request().Context(), cli, volume)
m, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
require.Equal(t, int64(16000), m[volume].Bytes)
require.Equal(t, "16.0 kB", m[volume].Human)
}
Expand Down Expand Up @@ -342,7 +343,8 @@ func TestPullVolumeUsingCorrectAuth(t *testing.T) {
require.Equal(t, http.StatusCreated, rec.Code)

// Check the content of the volume
m := backend.GetVolumesSize(c.Request().Context(), cli, volume)
m, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
require.Equal(t, int64(16000), m[volume].Bytes)
require.Equal(t, "16.0 kB", m[volume].Human)
}
Expand Down Expand Up @@ -481,7 +483,8 @@ func TestPullVolumeUsingWrongAuthShouldFail(t *testing.T) {
require.Equal(t, http.StatusUnauthorized, rec.Code)

// Check the content of the volume
m := backend.GetVolumesSize(c.Request().Context(), cli, volume)
m, err := backend.GetVolumesSize(c.Request().Context(), cli, volume)
require.NoError(t, err)
require.Equal(t, int64(0), m[volume].Bytes)
require.Equal(t, "0 B", m[volume].Human)
}
Expand Down
4 changes: 2 additions & 2 deletions vm/internal/handler/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package handler
import (
"net/http"

"github.com/bugsnag/bugsnag-go/v2"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/volumes-backup-extension/internal/backend"
"github.com/docker/volumes-backup-extension/internal/log"
"github.com/labstack/echo"
Expand All @@ -27,7 +27,7 @@ func (h *Handler) SaveVolume(ctx echo.Context) error {
cli, err := h.DockerClient()
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctxReq)
_ = bugsnag.Notify(err, ctxReq)
return ctx.String(http.StatusInternalServerError, err.Error())
}
defer func() {
Expand Down
10 changes: 9 additions & 1 deletion vm/internal/handler/size.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handler

import (
"github.com/bugsnag/bugsnag-go/v2"
"net/http"

"github.com/docker/volumes-backup-extension/internal/backend"
Expand All @@ -9,14 +10,21 @@ import (
)

func (h *Handler) VolumeSize(ctx echo.Context) error {
ctxReq := ctx.Request().Context()
volumeName := ctx.Param("volume")
cli, err := h.DockerClient()
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctxReq)
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

m := backend.GetVolumesSize(ctx.Request().Context(), cli, volumeName)
m, err := backend.GetVolumesSize(ctxReq, cli, volumeName)
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctxReq)
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

return ctx.JSON(http.StatusOK, m[volumeName])
}
14 changes: 10 additions & 4 deletions vm/internal/handler/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"net/http"
"sync"

"github.com/bugsnag/bugsnag-go/v2"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/docker/docker/api/types/filters"
"github.com/docker/volumes-backup-extension/internal/backend"
"github.com/docker/volumes-backup-extension/internal/log"
Expand All @@ -30,10 +30,10 @@ func (h *Handler) Volumes(ctx echo.Context) error {
cli, err := h.DockerClient()
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctxReq)
_ = bugsnag.Notify(err, ctxReq)
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

v, err := cli.VolumeList(ctx.Request().Context(), filters.NewArgs())
if err != nil {
log.Error(err)
Expand All @@ -48,7 +48,13 @@ func (h *Handler) Volumes(ctx echo.Context) error {
// Calculating the volume size by spinning a container that execs "du " **per volume** is too time-consuming.
// To reduce the time it takes, we get the volumes size by running only one container that execs "du"
// into the /var/lib/docker/volumes inside the VM.
volumesSize := backend.GetVolumesSize(ctxReq, cli, "*")
volumesSize, err := backend.GetVolumesSize(ctxReq, cli, "*")
if err != nil {
log.Error(err)
_ = bugsnag.Notify(err, ctxReq)
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

res.Lock()
for k, v := range volumesSize {
entry, ok := res.data[k]
Expand Down
8 changes: 6 additions & 2 deletions vm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"flag"
"github.com/bugsnag/bugsnag-go/v2"
"net"
"net/http"
"os"
Expand All @@ -12,7 +13,7 @@ import (
"github.com/docker/docker/client"
"github.com/docker/volumes-backup-extension/internal/handler"
"github.com/docker/volumes-backup-extension/internal/log"
"github.com/docker/volumes-backup-extension/internal/setup"
"github.com/docker/volumes-backup-extension/internal/setup"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
Expand Down Expand Up @@ -48,15 +49,16 @@ func main() {
log.Infof("Starting listening on %s\n", socketPath)
ln, err := net.Listen("unix", socketPath)
if err != nil {
_ = bugsnag.Notify(err)
log.Fatal(err)
}
router.Listener = ln

cliFactory := func() (*client.Client, error) {

return client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
}
if err != nil {
_ = bugsnag.Notify(err)
log.Fatal(err)
}

Expand All @@ -82,6 +84,7 @@ func main() {
setup.ConfigureBugsnagHandler(server)

if err := router.StartServer(server); err != nil && err != http.ErrServerClosed {
_ = bugsnag.Notify(err)
log.Fatal("shutting down the server")
}
}()
Expand All @@ -94,6 +97,7 @@ func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := router.Shutdown(ctx); err != nil {
_ = bugsnag.Notify(err)
log.Fatal(err)
}
}