*: use new errors handling library
Implement a new error handling library based on pkg/errors. It provides stack saving on wrapping and exports some function to add stack saving also to external errors. It also implements custom zerolog error formatting without adding too much verbosity by just printing the chain error file:line without a full stack trace of every error. * Add a --detailed-errors options to print error with they full chain * Wrap all error returns. Use errors.WithStack to wrap without adding a new messsage and error.Wrap[f] to add a message. * Add golangci-lint wrapcheck to check that external packages errors are wrapped. This won't check that internal packages error are wrapped. But we want also to ensure this case so we'll have to find something else to check also these.
This commit is contained in:
parent
5df9ee19c4
commit
d2b09d854f
|
@ -1,2 +1,25 @@
|
|||
linters:
|
||||
enable: errorlint
|
||||
enable:
|
||||
- errorlint
|
||||
- wrapcheck
|
||||
|
||||
linters-settings:
|
||||
wrapcheck:
|
||||
# An array of strings that specify substrings of signatures to ignore.
|
||||
# If this set, it will override the default set of ignored signatures.
|
||||
# See https://github.com/tomarrell/wrapcheck#configuration for more information.
|
||||
ignoreSigs:
|
||||
- .Errorf(
|
||||
- errors.New(
|
||||
- errors.Unwrap(
|
||||
- .Wrap(
|
||||
- .Wrapf(
|
||||
- .WithMessage(
|
||||
- .WithMessagef(
|
||||
- .WithStack(
|
||||
- .NewDetailedError(
|
||||
ignoreSigRegexps:
|
||||
- \.New.*Error\(
|
||||
ignorePackageGlobs:
|
||||
- encoding/*
|
||||
- github.com/pkg/*
|
||||
|
|
|
@ -20,11 +20,11 @@ import (
|
|||
"time"
|
||||
|
||||
"agola.io/agola/cmd"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var token string
|
||||
|
@ -33,6 +33,7 @@ func init() {
|
|||
cw := zerolog.ConsoleWriter{
|
||||
Out: os.Stderr,
|
||||
TimeFormat: time.RFC3339Nano,
|
||||
FormatErrFieldValue: errors.FormatErrFieldValue,
|
||||
}
|
||||
|
||||
zerolog.TimeFieldFormat = time.RFC3339Nano
|
||||
|
@ -53,6 +54,9 @@ var cmdAgola = &cobra.Command{
|
|||
if agolaOpts.debug {
|
||||
log.Logger = log.Level(zerolog.DebugLevel)
|
||||
}
|
||||
if agolaOpts.detailedErrors {
|
||||
zerolog.ErrorMarshalFunc = errors.ErrorMarshalFunc
|
||||
}
|
||||
},
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
if err := c.Help(); err != nil {
|
||||
|
@ -64,6 +68,7 @@ var cmdAgola = &cobra.Command{
|
|||
type agolaOptions struct {
|
||||
gatewayURL string
|
||||
debug bool
|
||||
detailedErrors bool
|
||||
}
|
||||
|
||||
var agolaOpts agolaOptions
|
||||
|
@ -84,6 +89,7 @@ func init() {
|
|||
flags.StringVarP(&agolaOpts.gatewayURL, "gateway-url", "u", gatewayURL, "agola gateway exposed url")
|
||||
flags.StringVar(&token, "token", token, "api token")
|
||||
flags.BoolVarP(&agolaOpts.debug, "debug", "d", false, "debug")
|
||||
flags.BoolVar(&agolaOpts.detailedErrors, "detailed-errors", false, "enabled detailed errors logging")
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
|
|
|
@ -17,6 +17,7 @@ package cmd
|
|||
import (
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -33,11 +34,11 @@ func completionShell(cmd *cobra.Command, args []string, shell string) error {
|
|||
switch shell {
|
||||
case "bash":
|
||||
if err := cmdAgola.GenBashCompletion(os.Stdout); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
case "zsh":
|
||||
if err := cmdAgola.GenZshCompletion(os.Stdout); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsave "agola.io/agola/internal/git-save"
|
||||
"agola.io/agola/internal/util"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
|
@ -32,7 +33,6 @@ import (
|
|||
"github.com/gofrs/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdDirectRunStart = &cobra.Command{
|
||||
|
@ -80,15 +80,15 @@ func parseVariable(variable string) (string, string, error) {
|
|||
variable = strings.TrimLeftFunc(variable, unicode.IsSpace)
|
||||
arr := strings.SplitN(variable, "=", 2)
|
||||
if len(arr) != 2 {
|
||||
return "", "", fmt.Errorf("invalid variable definition: %s", variable)
|
||||
return "", "", errors.Errorf("invalid variable definition: %s", variable)
|
||||
}
|
||||
varname := arr[0]
|
||||
varvalue := arr[1]
|
||||
if varname == "" {
|
||||
return "", "", fmt.Errorf("invalid variable definition: %s", variable)
|
||||
return "", "", errors.Errorf("invalid variable definition: %s", variable)
|
||||
}
|
||||
if varvalue == "" {
|
||||
return "", "", fmt.Errorf("invalid variable definition: %s", variable)
|
||||
return "", "", errors.Errorf("invalid variable definition: %s", variable)
|
||||
}
|
||||
return varname, varvalue, nil
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
|
||||
for _, res := range directRunStartOpts.prRefRegexes {
|
||||
if _, err := regexp.Compile(res); err != nil {
|
||||
return fmt.Errorf("wrong regular expression %q: %w", res, err)
|
||||
return errors.Wrapf(err, "wrong regular expression %q", res)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,12 +123,12 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
branch = ""
|
||||
}
|
||||
if set > 1 {
|
||||
return fmt.Errorf(`only one of "--branch", "--tag" or "--ref" can be provided`)
|
||||
return errors.Errorf(`only one of "--branch", "--tag" or "--ref" can be provided`)
|
||||
}
|
||||
|
||||
user, _, err := gwclient.GetCurrentUser(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
variables := map[string]string{}
|
||||
|
@ -142,11 +142,11 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
var err error
|
||||
data, err = ioutil.ReadFile(varFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(data, &variables); err != nil {
|
||||
return errors.Errorf("failed to unmarshal values: %w", err)
|
||||
return errors.Wrapf(err, "failed to unmarshal values")
|
||||
}
|
||||
|
||||
// TODO(sgotti) validate variable name
|
||||
|
@ -155,7 +155,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
for _, variable := range directRunStartOpts.vars {
|
||||
varname, varvalue, err := parseVariable(variable)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
variables[varname] = varvalue
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
if repoUUID == "" {
|
||||
repoUUID = uuid.Must(uuid.NewV4()).String()
|
||||
if _, err := git.ConfigSet(context.Background(), "agola.repouuid", repoUUID); err != nil {
|
||||
return fmt.Errorf("failed to set agola repo uid in git config: %w", err)
|
||||
return errors.Wrapf(err, "failed to set agola repo uid in git config")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
|
||||
commitSHA, err := gs.Save(message, localBranch)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
log.Info().Msgf("pushing branch")
|
||||
|
@ -190,15 +190,15 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
// push to a branch with default branch refs "refs/heads/branch"
|
||||
if branch != "" {
|
||||
if err := gitsave.GitPush("", repoURL, fmt.Sprintf("%s:refs/heads/%s", path.Join(gs.RefsPrefix(), localBranch), branch)); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else if tag != "" {
|
||||
if err := gitsave.GitPush("", repoURL, fmt.Sprintf("%s:refs/tags/%s", path.Join(gs.RefsPrefix(), localBranch), tag)); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else if ref != "" {
|
||||
if err := gitsave.GitPush("", repoURL, fmt.Sprintf("%s:%s", path.Join(gs.RefsPrefix(), localBranch), ref)); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
|
|||
Variables: variables,
|
||||
}
|
||||
if _, err := gwclient.UserCreateRun(context.TODO(), req); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdLogDelete = &cobra.Command{
|
||||
|
@ -93,7 +93,7 @@ func logDelete(cmd *cobra.Command, args []string) error {
|
|||
|
||||
run, _, err := gwclient.GetRun(context.TODO(), logDeleteOpts.runid)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
for _, t := range run.Tasks {
|
||||
if t.Name == logDeleteOpts.taskname {
|
||||
|
|
|
@ -19,12 +19,12 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdLogGet = &cobra.Command{
|
||||
|
@ -102,7 +102,7 @@ func logGet(cmd *cobra.Command, args []string) error {
|
|||
|
||||
run, _, err := gwclient.GetRun(context.TODO(), logGetOpts.runid)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
for _, t := range run.Tasks {
|
||||
if t.Name == logGetOpts.taskname {
|
||||
|
@ -127,7 +127,7 @@ func logGet(cmd *cobra.Command, args []string) error {
|
|||
if flags.Changed("output") {
|
||||
f, err := os.Create(logGetOpts.output)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := io.Copy(f, resp.Body); err != nil {
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdOrgCreate = &cobra.Command{
|
||||
|
@ -71,7 +71,7 @@ func orgCreate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("creating org")
|
||||
org, _, err := gwclient.CreateOrg(context.TODO(), req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create org: %w", err)
|
||||
return errors.Wrapf(err, "failed to create org")
|
||||
}
|
||||
log.Info().Msgf("org %q created, ID: %q", org.Name, org.ID)
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdOrgDelete = &cobra.Command{
|
||||
|
@ -57,7 +57,7 @@ func orgDelete(cmd *cobra.Command, args []string) error {
|
|||
|
||||
log.Info().Msgf("deleting organization %q", orgDeleteOpts.name)
|
||||
if _, err := gwclient.DeleteOrg(context.TODO(), orgDeleteOpts.name); err != nil {
|
||||
return errors.Errorf("failed to delete organization: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete organization")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdOrgMemberAdd = &cobra.Command{
|
||||
|
@ -66,7 +66,7 @@ func orgMemberAdd(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("adding/updating member %q to organization %q with role %q", orgMemberAddOpts.username, orgMemberAddOpts.orgname, orgMemberAddOpts.role)
|
||||
_, _, err := gwclient.AddOrgMember(context.TODO(), orgMemberAddOpts.orgname, orgMemberAddOpts.username, gwapitypes.MemberRole(orgMemberAddOpts.role))
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to add/update organization member: %w", err)
|
||||
return errors.Wrapf(err, "failed to add/update organization member")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -19,11 +19,11 @@ import (
|
|||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdOrgMemberList = &cobra.Command{
|
||||
|
@ -59,12 +59,12 @@ func orgMemberList(cmd *cobra.Command, args []string) error {
|
|||
|
||||
orgMembers, _, err := gwclient.GetOrgMembers(context.TODO(), orgMemberListOpts.orgname)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get organization member: %w", err)
|
||||
return errors.Wrapf(err, "failed to get organization member")
|
||||
}
|
||||
|
||||
out, err := json.MarshalIndent(orgMembers, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
os.Stdout.Write(out)
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdOrgMemberRemove = &cobra.Command{
|
||||
|
@ -63,7 +63,7 @@ func orgMemberRemove(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("removing member %q from organization %q", orgMemberRemoveOpts.username, orgMemberRemoveOpts.orgname)
|
||||
_, err := gwclient.RemoveOrgMember(context.TODO(), orgMemberRemoveOpts.orgname, orgMemberRemoveOpts.username)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to remove organization member: %w", err)
|
||||
return errors.Wrapf(err, "failed to remove organization member")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectCreate = &cobra.Command{
|
||||
|
@ -106,7 +106,7 @@ func projectCreate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
project, _, err := gwclient.CreateProject(context.TODO(), req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project")
|
||||
}
|
||||
log.Info().Msgf("project %s created, ID: %s", project.Name, project.ID)
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectDelete = &cobra.Command{
|
||||
|
@ -58,7 +58,7 @@ func projectDelete(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("deleting project")
|
||||
|
||||
if _, err := gwclient.DeleteProject(context.TODO(), projectDeleteOpts.ref); err != nil {
|
||||
return errors.Errorf("failed to delete project: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectGroupCreate = &cobra.Command{
|
||||
|
@ -78,7 +78,7 @@ func projectGroupCreate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
projectGroup, _, err := gwclient.CreateProjectGroup(context.TODO(), req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project group: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project group")
|
||||
}
|
||||
log.Info().Msgf("project group %s created, ID: %s", projectGroup.Name, projectGroup.ID)
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectGroupDelete = &cobra.Command{
|
||||
|
@ -58,7 +58,7 @@ func projectGroupDelete(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("deleting project group")
|
||||
|
||||
if _, err := gwclient.DeleteProjectGroup(context.TODO(), projectGroupDeleteOpts.ref); err != nil {
|
||||
return errors.Errorf("failed to delete project group: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project group")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectGroupUpdate = &cobra.Command{
|
||||
|
@ -82,7 +82,7 @@ func projectGroupUpdate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("updating project group")
|
||||
projectGroup, _, err := gwclient.UpdateProjectGroup(context.TODO(), projectGroupUpdateOpts.ref, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project group: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project group")
|
||||
}
|
||||
log.Info().Msgf("project group %s update, ID: %s", projectGroup.Name, projectGroup.ID)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
|
@ -64,7 +65,7 @@ func projectList(cmd *cobra.Command, args []string) error {
|
|||
|
||||
projects, _, err := gwclient.GetProjectGroupProjects(context.TODO(), projectListOpts.parentPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
printProjects(projects)
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectReconfig = &cobra.Command{
|
||||
|
@ -57,7 +57,7 @@ func projectReconfig(cmd *cobra.Command, args []string) error {
|
|||
|
||||
log.Info().Msgf("reconfiguring remote project")
|
||||
if _, err := gwclient.ReconfigProject(context.TODO(), projectReconfigOpts.name); err != nil {
|
||||
return errors.Errorf("failed to reconfigure remote project: %w", err)
|
||||
return errors.Wrapf(err, "failed to reconfigure remote project")
|
||||
}
|
||||
log.Info().Msgf("project reconfigured")
|
||||
|
||||
|
|
|
@ -19,13 +19,13 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectSecretCreate = &cobra.Command{
|
||||
|
@ -82,12 +82,12 @@ func secretCreate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
if secretCreateOpts.file == "-" {
|
||||
data, err = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
data, err = ioutil.ReadFile(secretCreateOpts.file)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,14 +106,14 @@ func secretCreate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("creating project secret")
|
||||
secret, _, err := gwclient.CreateProjectSecret(context.TODO(), secretCreateOpts.parentRef, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project secret")
|
||||
}
|
||||
log.Info().Msgf("project secret %q created, ID: %q", secret.Name, secret.ID)
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("creating project group secret")
|
||||
secret, _, err := gwclient.CreateProjectGroupSecret(context.TODO(), secretCreateOpts.parentRef, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project group secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project group secret")
|
||||
}
|
||||
log.Info().Msgf("project group secret %q created, ID: %q", secret.Name, secret.ID)
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectSecretDelete = &cobra.Command{
|
||||
|
@ -65,14 +65,14 @@ func secretDelete(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("deleting project secret")
|
||||
_, err := gwclient.DeleteProjectSecret(context.TODO(), secretDeleteOpts.parentRef, secretDeleteOpts.name)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete project secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project secret")
|
||||
}
|
||||
log.Info().Msgf("project secret deleted")
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("deleting project group secret")
|
||||
_, err := gwclient.DeleteProjectGroupSecret(context.TODO(), secretDeleteOpts.parentRef, secretDeleteOpts.name)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete project group secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project group secret")
|
||||
}
|
||||
log.Info().Msgf("project group secret deleted")
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectSecretList = &cobra.Command{
|
||||
|
@ -57,10 +57,10 @@ func init() {
|
|||
|
||||
func secretList(cmd *cobra.Command, ownertype string, args []string) error {
|
||||
if err := printSecrets(ownertype, fmt.Sprintf("%s secrets", ownertype), false, false); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := printSecrets(ownertype, "All secrets (local and inherited)", true, true); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -79,11 +79,11 @@ func printSecrets(ownertype, description string, tree, removeoverridden bool) er
|
|||
secrets, _, err = gwclient.GetProjectGroupSecrets(context.TODO(), secretListOpts.parentRef, tree, removeoverridden)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to list %s secrets: %w", ownertype, err)
|
||||
return errors.Wrapf(err, "failed to list %s secrets", ownertype)
|
||||
}
|
||||
prettyJSON, err := json.MarshalIndent(secrets, "", "\t")
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to convert %s secrets to json: %w", ownertype, err)
|
||||
return errors.Wrapf(err, "failed to convert %s secrets to json", ownertype)
|
||||
}
|
||||
fmt.Printf("%s:\n%s\n", description, string(prettyJSON))
|
||||
return nil
|
||||
|
|
|
@ -19,13 +19,13 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectSecretUpdate = &cobra.Command{
|
||||
|
@ -84,12 +84,12 @@ func secretUpdate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
if secretUpdateOpts.file == "-" {
|
||||
data, err = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
data, err = ioutil.ReadFile(secretUpdateOpts.file)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,14 +113,14 @@ func secretUpdate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("creating project secret")
|
||||
secret, _, err := gwclient.UpdateProjectSecret(context.TODO(), secretUpdateOpts.parentRef, secretUpdateOpts.name, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project secret")
|
||||
}
|
||||
log.Info().Msgf("project secret %q updated, ID: %q", secret.Name, secret.ID)
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("creating project group secret")
|
||||
secret, _, err := gwclient.UpdateProjectGroupSecret(context.TODO(), secretUpdateOpts.parentRef, secretUpdateOpts.name, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project group secret: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project group secret")
|
||||
}
|
||||
log.Info().Msgf("project group secret %q updated, ID: %q", secret.Name, secret.ID)
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectUpdate = &cobra.Command{
|
||||
|
@ -88,7 +88,7 @@ func projectUpdate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("updating project")
|
||||
project, _, err := gwclient.UpdateProject(context.TODO(), projectUpdateOpts.ref, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project")
|
||||
}
|
||||
log.Info().Msgf("project %s update, ID: %s", project.Name, project.ID)
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ import (
|
|||
"os"
|
||||
|
||||
config "agola.io/agola/internal/config"
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectVariableCreate = &cobra.Command{
|
||||
|
@ -105,12 +105,12 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
if variableCreateOpts.file == "-" {
|
||||
data, err = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
data, err = ioutil.ReadFile(variableCreateOpts.file)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,14 +136,14 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("creating project variable")
|
||||
variable, _, err := gwclient.CreateProjectVariable(context.TODO(), variableCreateOpts.parentRef, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project variable")
|
||||
}
|
||||
log.Info().Msgf("project variable %q created, ID: %q", variable.Name, variable.ID)
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("creating project group variable")
|
||||
variable, _, err := gwclient.CreateProjectGroupVariable(context.TODO(), variableCreateOpts.parentRef, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create project group variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to create project group variable")
|
||||
}
|
||||
log.Info().Msgf("project group variable %q created, ID: %q", variable.Name, variable.ID)
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectVariableDelete = &cobra.Command{
|
||||
|
@ -65,14 +65,14 @@ func variableDelete(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("deleting project variable")
|
||||
_, err := gwclient.DeleteProjectVariable(context.TODO(), variableDeleteOpts.parentRef, variableDeleteOpts.name)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete project variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project variable")
|
||||
}
|
||||
log.Info().Msgf("project variable deleted")
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("deleting project group variable")
|
||||
_, err := gwclient.DeleteProjectGroupVariable(context.TODO(), variableDeleteOpts.parentRef, variableDeleteOpts.name)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete project group variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete project group variable")
|
||||
}
|
||||
log.Info().Msgf("project group variable deleted")
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectVariableList = &cobra.Command{
|
||||
|
@ -57,10 +57,10 @@ func init() {
|
|||
|
||||
func variableList(cmd *cobra.Command, ownertype string, args []string) error {
|
||||
if err := printVariables(ownertype, fmt.Sprintf("%s variables", ownertype), false, false); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := printVariables(ownertype, "All variables (local and inherited)", true, true); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -79,11 +79,11 @@ func printVariables(ownertype, description string, tree, removeoverridden bool)
|
|||
variables, _, err = gwclient.GetProjectGroupVariables(context.TODO(), variableListOpts.parentRef, tree, removeoverridden)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to list %s variables: %w", ownertype, err)
|
||||
return errors.Wrapf(err, "failed to list %s variables", ownertype)
|
||||
}
|
||||
prettyJSON, err := json.MarshalIndent(variables, "", "\t")
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to convert %s variables to json: %w", ownertype, err)
|
||||
return errors.Wrapf(err, "failed to convert %s variables to json", ownertype)
|
||||
}
|
||||
fmt.Printf("%s:\n%s\n", description, string(prettyJSON))
|
||||
return nil
|
||||
|
|
|
@ -19,13 +19,13 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdProjectVariableUpdate = &cobra.Command{
|
||||
|
@ -77,12 +77,12 @@ func variableUpdate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
if variableUpdateOpts.file == "-" {
|
||||
data, err = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
data, err = ioutil.ReadFile(variableUpdateOpts.file)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,14 +113,14 @@ func variableUpdate(cmd *cobra.Command, ownertype string, args []string) error {
|
|||
log.Info().Msgf("updating project variable")
|
||||
variable, _, err := gwclient.UpdateProjectVariable(context.TODO(), variableUpdateOpts.parentRef, variableUpdateOpts.name, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project variable")
|
||||
}
|
||||
log.Info().Msgf("project variable %q updated, ID: %q", variable.Name, variable.ID)
|
||||
case "projectgroup":
|
||||
log.Info().Msgf("updating project group variable")
|
||||
variable, _, err := gwclient.UpdateProjectGroupVariable(context.TODO(), variableUpdateOpts.parentRef, variableUpdateOpts.name, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update project group variable: %w", err)
|
||||
return errors.Wrapf(err, "failed to update project group variable")
|
||||
}
|
||||
log.Info().Msgf("project group variable %q updated, ID: %q", variable.Name, variable.ID)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/gitsources/github"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
@ -24,7 +25,6 @@ import (
|
|||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdRemoteSourceCreate = &cobra.Command{
|
||||
|
@ -117,7 +117,7 @@ func remoteSourceCreate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("creating remotesource")
|
||||
remoteSource, _, err := gwclient.CreateRemoteSource(context.TODO(), req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create remotesource: %w", err)
|
||||
return errors.Wrapf(err, "failed to create remotesource")
|
||||
}
|
||||
log.Info().Msgf("remotesource %s created, ID: %s", remoteSource.Name, remoteSource.ID)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
|
@ -62,7 +63,7 @@ func remoteSourceList(cmd *cobra.Command, args []string) error {
|
|||
|
||||
remouteSources, _, err := gwclient.GetRemoteSources(context.TODO(), remoteSourceListOpts.start, remoteSourceListOpts.limit, false)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
printRemoteSources(remouteSources)
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdRemoteSourceUpdate = &cobra.Command{
|
||||
|
@ -109,7 +109,7 @@ func remoteSourceUpdate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("updating remotesource")
|
||||
remoteSource, _, err := gwclient.UpdateRemoteSource(context.TODO(), remoteSourceUpdateOpts.ref, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to update remotesource: %w", err)
|
||||
return errors.Wrapf(err, "failed to update remotesource")
|
||||
}
|
||||
log.Info().Msgf("remotesource %s updated, ID: %s", remoteSource.Name, remoteSource.ID)
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
|
@ -76,7 +76,7 @@ func runCreate(cmd *cobra.Command, args []string) error {
|
|||
set++
|
||||
}
|
||||
if set != 1 {
|
||||
return fmt.Errorf(`one of "--branch", "--tag" or "--ref" must be provided`)
|
||||
return errors.Errorf(`one of "--branch", "--tag" or "--ref" must be provided`)
|
||||
}
|
||||
|
||||
req := &gwapitypes.ProjectCreateRunRequest{
|
||||
|
@ -88,5 +88,5 @@ func runCreate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
_, err := gwclient.ProjectCreateRun(context.TODO(), runCreateOpts.projectRef, req)
|
||||
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ import (
|
|||
"path"
|
||||
"sort"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
errors "golang.org/x/xerrors"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -104,14 +104,14 @@ func runList(cmd *cobra.Command, args []string) error {
|
|||
groups := []string{path.Join("/project", project.ID)}
|
||||
runsResp, _, err := gwclient.GetRuns(context.TODO(), runListOpts.phaseFilter, nil, groups, nil, runListOpts.start, runListOpts.limit, false)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
runs := make([]*runDetails, len(runsResp))
|
||||
for i, runResponse := range runsResp {
|
||||
run, _, err := gwclient.GetRun(context.TODO(), runResponse.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
tasks := []*taskDetails{}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"agola.io/agola/cmd"
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/config"
|
||||
"agola.io/agola/internal/services/configstore"
|
||||
"agola.io/agola/internal/services/executor"
|
||||
|
@ -33,7 +34,6 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"go.etcd.io/etcd/embed"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -96,7 +96,7 @@ func embeddedEtcd(ctx context.Context) error {
|
|||
log.Info().Msgf("starting embedded etcd server")
|
||||
e, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -132,12 +132,12 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
|
||||
c, err := config.Parse(serveOpts.config, serveOpts.components)
|
||||
if err != nil {
|
||||
return errors.Errorf("config error: %w", err)
|
||||
return errors.Wrapf(err, "config error")
|
||||
}
|
||||
|
||||
if serveOpts.embeddedEtcd {
|
||||
if err := embeddedEtcd(ctx); err != nil {
|
||||
return errors.Errorf("failed to start run service scheduler: %w", err)
|
||||
return errors.Wrapf(err, "failed to start run service scheduler")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("runservice") {
|
||||
rs, err = rsscheduler.NewRunservice(ctx, log.Logger, &c.Runservice)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start run service scheduler: %w", err)
|
||||
return errors.Wrapf(err, "failed to start run service scheduler")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("executor") {
|
||||
ex, err = executor.NewExecutor(ctx, log.Logger, &c.Executor)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start run service executor: %w", err)
|
||||
return errors.Wrapf(err, "failed to start run service executor")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("configstore") {
|
||||
cs, err = configstore.NewConfigstore(ctx, log.Logger, &c.Configstore)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start config store: %w", err)
|
||||
return errors.Wrapf(err, "failed to start config store")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("scheduler") {
|
||||
sched, err = scheduler.NewScheduler(ctx, log.Logger, &c.Scheduler)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start scheduler: %w", err)
|
||||
return errors.Wrapf(err, "failed to start scheduler")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("notification") {
|
||||
ns, err = notification.NewNotificationService(ctx, log.Logger, c)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start notification service: %w", err)
|
||||
return errors.Wrapf(err, "failed to start notification service")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("gateway") {
|
||||
gw, err = gateway.NewGateway(ctx, log.Logger, c)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start gateway: %w", err)
|
||||
return errors.Wrapf(err, "failed to start gateway")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||
if isComponentEnabled("gitserver") {
|
||||
gs, err = gitserver.NewGitserver(ctx, log.Logger, &c.Gitserver)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to start git server: %w", err)
|
||||
return errors.Wrapf(err, "failed to start git server")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserCreate = &cobra.Command{
|
||||
|
@ -63,7 +63,7 @@ func userCreate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("creating user")
|
||||
user, _, err := gwclient.CreateUser(context.TODO(), req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create user: %w", err)
|
||||
return errors.Wrapf(err, "failed to create user")
|
||||
}
|
||||
log.Info().Msgf("user %q created, ID: %q", user.UserName, user.ID)
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserDelete = &cobra.Command{
|
||||
|
@ -57,7 +57,7 @@ func userDelete(cmd *cobra.Command, args []string) error {
|
|||
|
||||
log.Info().Msgf("deleting user %q", userDeleteOpts.username)
|
||||
if _, err := gwclient.DeleteUser(context.TODO(), userDeleteOpts.username); err != nil {
|
||||
return errors.Errorf("failed to delete user: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete user")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -17,12 +17,12 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserLACreate = &cobra.Command{
|
||||
|
@ -74,7 +74,7 @@ func userLACreate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("creating linked account for user %q", userLACreateOpts.username)
|
||||
resp, _, err := gwclient.CreateUserLA(context.TODO(), userLACreateOpts.username, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create linked account: %w", err)
|
||||
return errors.Wrapf(err, "failed to create linked account")
|
||||
}
|
||||
if resp.Oauth2Redirect != "" {
|
||||
log.Info().Msgf("visit %s to continue", resp.Oauth2Redirect)
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserLADelete = &cobra.Command{
|
||||
|
@ -66,7 +66,7 @@ func userLADelete(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("deleting linked account %q for user %q", laID, userName)
|
||||
_, err := gwclient.DeleteUserLA(context.TODO(), userName, laID)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete linked account: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete linked account")
|
||||
}
|
||||
|
||||
log.Info().Msgf("linked account %q for user %q deleted", laID, userName)
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
|
@ -62,7 +63,7 @@ func userList(cmd *cobra.Command, args []string) error {
|
|||
|
||||
users, _, err := gwclient.GetUsers(context.TODO(), userListOpts.start, userListOpts.limit, false)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
printUsers(users)
|
||||
|
|
|
@ -18,12 +18,12 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwapitypes "agola.io/agola/services/gateway/api/types"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserTokenCreate = &cobra.Command{
|
||||
|
@ -69,7 +69,7 @@ func userTokenCreate(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("creating token for user %q", userTokenCreateOpts.username)
|
||||
resp, _, err := gwclient.CreateUserToken(context.TODO(), userTokenCreateOpts.username, req)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to create token: %w", err)
|
||||
return errors.Wrapf(err, "failed to create token")
|
||||
}
|
||||
log.Info().Msgf("token for user %q created: %s", userTokenCreateOpts.username, resp.Token)
|
||||
fmt.Println(resp.Token)
|
||||
|
|
|
@ -17,11 +17,11 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cmdUserTokenDelete = &cobra.Command{
|
||||
|
@ -66,7 +66,7 @@ func userTokenDelete(cmd *cobra.Command, args []string) error {
|
|||
log.Info().Msgf("deleting token %q for user %q", tokenName, userName)
|
||||
_, err := gwclient.DeleteUserToken(context.TODO(), userName, tokenName)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to delete user token: %w", err)
|
||||
return errors.Wrapf(err, "failed to delete user token")
|
||||
}
|
||||
|
||||
log.Info().Msgf("token %q for user %q deleted", tokenName, userName)
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gwclient "agola.io/agola/services/gateway/client"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
@ -43,7 +44,7 @@ func printVersions(cmd *cobra.Command, args []string) error {
|
|||
|
||||
gwversion, _, err := gwclient.GetVersion(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Gateway version:\t%s\n", gwversion.Version)
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -48,18 +49,18 @@ func createFile(r io.Reader) (string, error) {
|
|||
// create a temp dir if the image doesn't have one
|
||||
tmpDir := os.TempDir()
|
||||
if err := os.MkdirAll(tmpDir, 0777); err != nil {
|
||||
return "", fmt.Errorf("failed to create tmp dir %q", tmpDir)
|
||||
return "", errors.Errorf("failed to create tmp dir %q", tmpDir)
|
||||
}
|
||||
|
||||
file, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
filename := file.Name()
|
||||
if _, err := io.Copy(file, r); err != nil {
|
||||
file.Close()
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
file.Close()
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ package cmd
|
|||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -28,6 +27,8 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -48,20 +49,20 @@ func md5sum(filename string) (string, error) {
|
|||
|
||||
if info, err := os.Stat(filename); err == nil {
|
||||
if info.Size() > 1024*1024 {
|
||||
return "", fmt.Errorf("file %q is too big", filename)
|
||||
return "", errors.Errorf("file %q is too big", filename)
|
||||
}
|
||||
} else {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
|
@ -74,20 +75,20 @@ func sha256sum(filename string) (string, error) {
|
|||
|
||||
if info, err := os.Stat(filename); err == nil {
|
||||
if info.Size() > 1024*1024 {
|
||||
return "", fmt.Errorf("file %q is too big", filename)
|
||||
return "", errors.Errorf("file %q is too big", filename)
|
||||
}
|
||||
} else {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
|
|
10
doc/devel.md
10
doc/devel.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
#### Start the web interface
|
||||
|
||||
* Clone the [agola-web repository](https://github.com/agola-io/agola-web)
|
||||
- Clone the [agola-web repository](https://github.com/agola-io/agola-web)
|
||||
|
||||
For the first time you'll need the `vue cli` and its services installed as global modules:
|
||||
|
||||
|
@ -27,7 +27,7 @@ make
|
|||
|
||||
### Start the agola server
|
||||
|
||||
* Copy the `example/config.yml` where you prefer
|
||||
- Copy the `example/config.yml` where you prefer
|
||||
|
||||
```
|
||||
./bin/agola serve --embedded-etcd --config /path/to/your/config.yml --components all-base,executor
|
||||
|
@ -38,3 +38,9 @@ or use an external etcd (set it in the config.yml):
|
|||
```
|
||||
./bin/agola serve --config /path/to/your/config.yml --components all-base,executor
|
||||
```
|
||||
|
||||
### Error handling
|
||||
|
||||
Use the `--detailed-errors` option to easily follow the errors chain.
|
||||
|
||||
When developing you should wrap every error using `errors.Wrap[f]` or `errors.WithStack`. The ci uses `golangci-lint` with the `wrapcheck` linter enabled to check if some errors aren't wrapped.
|
||||
|
|
1
go.mod
1
go.mod
|
@ -35,7 +35,6 @@ require (
|
|||
go.starlark.net v0.0.0-20200203144150-6677ee5c7211
|
||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
|
|
|
@ -21,12 +21,12 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
"agola.io/agola/internal/objectstorage"
|
||||
"agola.io/agola/internal/services/config"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -43,7 +43,7 @@ func WriteFileAtomicFunc(filename string, perm os.FileMode, writeFunc func(f io.
|
|||
dir, name := path.Split(filename)
|
||||
f, err := ioutil.TempFile(dir, name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
err = writeFunc(f)
|
||||
if err == nil {
|
||||
|
@ -62,7 +62,7 @@ func WriteFileAtomicFunc(filename string, perm os.FileMode, writeFunc func(f io.
|
|||
if err != nil {
|
||||
os.Remove(f.Name())
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// WriteFileAtomic atomically writes a file
|
||||
|
@ -70,7 +70,7 @@ func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error {
|
|||
return WriteFileAtomicFunc(filename, perm,
|
||||
func(f io.Writer) error {
|
||||
_, err := f.Write(data)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ func NewObjectStorage(c *config.ObjectStorage) (*objectstorage.ObjStorage, error
|
|||
case config.ObjectStorageTypePosix:
|
||||
ost, err = objectstorage.NewPosix(c.Path)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to create posix object storage: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create posix object storage")
|
||||
}
|
||||
case config.ObjectStorageTypeS3:
|
||||
// minio golang client doesn't accept an url as an endpoint
|
||||
|
@ -103,7 +103,7 @@ func NewObjectStorage(c *config.ObjectStorage) (*objectstorage.ObjStorage, error
|
|||
}
|
||||
ost, err = objectstorage.NewS3(c.Bucket, c.Location, endpoint, c.AccessKey, c.SecretAccessKey, secure)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to create s3 object storage: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create s3 object storage")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ func NewEtcd(c *config.Etcd, log zerolog.Logger, prefix string) (*etcd.Store, er
|
|||
SkipTLSVerify: c.TLSSkipVerify,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to create etcd store: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create etcd store")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
|
|
|
@ -20,12 +20,12 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
itypes "agola.io/agola/internal/services/types"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/types"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
errors "golang.org/x/xerrors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
|
@ -201,7 +201,7 @@ type SaveContent struct {
|
|||
func (s *Steps) UnmarshalJSON(b []byte) error {
|
||||
var stepsRaw []json.RawMessage
|
||||
if err := json.Unmarshal(b, &stepsRaw); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
steps := make(Steps, len(stepsRaw))
|
||||
|
@ -210,13 +210,13 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
|
||||
var stepMap map[string]json.RawMessage
|
||||
if err := json.Unmarshal(stepRaw, &stepMap); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// handle default step definition using format { type: "steptype", other steps fields }
|
||||
if _, ok := stepMap["type"]; ok {
|
||||
var stepTypeI interface{}
|
||||
if err := json.Unmarshal(stepMap["type"], &stepTypeI); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
stepType, ok := stepTypeI.(string)
|
||||
if !ok {
|
||||
|
@ -227,7 +227,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "clone":
|
||||
var s CloneStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -235,7 +235,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "run":
|
||||
var s RunStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if s.Tty == nil {
|
||||
s.Tty = util.BoolP(true)
|
||||
|
@ -246,7 +246,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "save_to_workspace":
|
||||
var s SaveToWorkspaceStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -254,7 +254,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "restore_workspace":
|
||||
var s RestoreWorkspaceStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -262,7 +262,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "save_cache":
|
||||
var s SaveCacheStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -270,7 +270,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "restore_cache":
|
||||
var s RestoreCacheStep
|
||||
if err := json.Unmarshal(stepRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -285,14 +285,14 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
for stepType, stepSpecRaw := range stepMap {
|
||||
var stepSpec interface{}
|
||||
if err := json.Unmarshal(stepSpecRaw, &stepSpec); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
switch stepType {
|
||||
case "clone":
|
||||
var s CloneStep
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -304,7 +304,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
s.Command = stepSpec
|
||||
default:
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
s.Type = stepType
|
||||
|
@ -313,7 +313,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "save_to_workspace":
|
||||
var s SaveToWorkspaceStep
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -321,7 +321,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "restore_workspace":
|
||||
var s RestoreWorkspaceStep
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -329,7 +329,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "save_cache":
|
||||
var s SaveCacheStep
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -337,7 +337,7 @@ func (s *Steps) UnmarshalJSON(b []byte) error {
|
|||
case "restore_cache":
|
||||
var s RestoreCacheStep
|
||||
if err := json.Unmarshal(stepSpecRaw, &s); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
s.Type = stepType
|
||||
step = &s
|
||||
|
@ -359,14 +359,14 @@ func (d *Depends) UnmarshalJSON(b []byte) error {
|
|||
var dependsRaw []json.RawMessage
|
||||
|
||||
if err := json.Unmarshal(b, &dependsRaw); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
depends := make([]*Depend, len(dependsRaw))
|
||||
for i, dependRaw := range dependsRaw {
|
||||
var dependi interface{}
|
||||
if err := json.Unmarshal(dependRaw, &dependi); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
var depend *Depend
|
||||
isSimpler := false
|
||||
|
@ -391,7 +391,7 @@ func (d *Depends) UnmarshalJSON(b []byte) error {
|
|||
if !isSimpler {
|
||||
// handle default depends definition using format "task": "taskname", conditions: [ list of conditions ]
|
||||
if err := json.Unmarshal(dependRaw, &depend); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
// handle simpler (for yaml) depends definition using format "taskname": [ list of conditions ]
|
||||
|
@ -401,7 +401,7 @@ func (d *Depends) UnmarshalJSON(b []byte) error {
|
|||
type deplist map[string][]DependCondition
|
||||
var dl deplist
|
||||
if err := json.Unmarshal(dependRaw, &dl); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if len(dl) != 1 {
|
||||
return errors.Errorf("unsupported depend entry format")
|
||||
|
@ -440,7 +440,7 @@ type Value struct {
|
|||
func (val *Value) UnmarshalJSON(b []byte) error {
|
||||
var ival interface{}
|
||||
if err := json.Unmarshal(b, &ival); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
switch valValue := ival.(type) {
|
||||
case string:
|
||||
|
@ -479,7 +479,7 @@ func (w *When) ToWhen() *types.When {
|
|||
func (w *When) UnmarshalJSON(b []byte) error {
|
||||
var wi *when
|
||||
if err := json.Unmarshal(b, &wi); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
@ -487,21 +487,21 @@ func (w *When) UnmarshalJSON(b []byte) error {
|
|||
if wi.Branch != nil {
|
||||
w.Branch, err = parseWhenConditions(wi.Branch)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
if wi.Tag != nil {
|
||||
w.Tag, err = parseWhenConditions(wi.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
if wi.Ref != nil {
|
||||
w.Ref, err = parseWhenConditions(wi.Ref)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) {
|
|||
case []interface{}:
|
||||
ss, err := parseSliceString(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
include = ss
|
||||
case map[string]interface{}:
|
||||
|
@ -530,12 +530,12 @@ func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) {
|
|||
case "include":
|
||||
include, err = parseStringOrSlice(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
case "exclude":
|
||||
exclude, err = parseStringOrSlice(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
default:
|
||||
return nil, errors.Errorf(`expected one of "include" or "exclude", got %s`, k)
|
||||
|
@ -547,11 +547,11 @@ func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) {
|
|||
|
||||
w.Include, err = parseWhenConditionSlice(include)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
w.Exclude, err = parseWhenConditionSlice(exclude)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return w, nil
|
||||
|
@ -566,7 +566,7 @@ func parseWhenConditionSlice(conds []string) ([]types.WhenCondition, error) {
|
|||
for _, cond := range conds {
|
||||
wc, err := parseWhenCondition(cond)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
wcs = append(wcs, *wc)
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ func parseWhenCondition(s string) (*types.WhenCondition, error) {
|
|||
|
||||
if isRegExp {
|
||||
if _, err := regexp.Compile(s); err != nil {
|
||||
return nil, errors.Errorf("wrong regular expression: %w", err)
|
||||
return nil, errors.Wrapf(err, "wrong regular expression")
|
||||
}
|
||||
wc.Type = types.WhenConditionTypeRegExp
|
||||
} else {
|
||||
|
@ -608,7 +608,7 @@ func parseStringOrSlice(si interface{}) ([]string, error) {
|
|||
var err error
|
||||
ss, err = parseSliceString(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
return ss, nil
|
||||
|
@ -669,14 +669,14 @@ func ParseConfig(configData []byte, format ConfigFormat, configContext *ConfigCo
|
|||
var err error
|
||||
configData, err = execJsonnet(configData, configContext)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to execute jsonnet: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to execute jsonnet")
|
||||
}
|
||||
case ConfigFormatStarlark:
|
||||
// Generate json from starlark
|
||||
var err error
|
||||
configData, err = execStarlark(configData, configContext)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to execute starlark: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to execute starlark")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,7 +686,7 @@ func ParseConfig(configData []byte, format ConfigFormat, configContext *ConfigCo
|
|||
|
||||
config := DefaultConfig
|
||||
if err := yaml.Unmarshal(configData, &config); err != nil {
|
||||
return nil, errors.Errorf("failed to unmarshal config: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal config")
|
||||
}
|
||||
|
||||
return &config, checkConfig(&config)
|
||||
|
|
|
@ -15,14 +15,13 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/types"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
errors "golang.org/x/xerrors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
|
@ -35,14 +34,14 @@ func TestParseConfig(t *testing.T) {
|
|||
{
|
||||
name: "test no runs 1",
|
||||
in: ``,
|
||||
err: fmt.Errorf(`no runs defined`),
|
||||
err: errors.Errorf(`no runs defined`),
|
||||
},
|
||||
{
|
||||
name: "test no runs 2",
|
||||
in: `
|
||||
runs:
|
||||
`,
|
||||
err: fmt.Errorf(`no runs defined`),
|
||||
err: errors.Errorf(`no runs defined`),
|
||||
},
|
||||
{
|
||||
name: "test empty run",
|
||||
|
@ -50,7 +49,7 @@ func TestParseConfig(t *testing.T) {
|
|||
runs:
|
||||
-
|
||||
`,
|
||||
err: fmt.Errorf(`run at index 0 is empty`),
|
||||
err: errors.Errorf(`run at index 0 is empty`),
|
||||
},
|
||||
{
|
||||
name: "test empty task",
|
||||
|
@ -60,7 +59,7 @@ func TestParseConfig(t *testing.T) {
|
|||
tasks:
|
||||
-
|
||||
`,
|
||||
err: fmt.Errorf(`run "run01": task at index 0 is empty`),
|
||||
err: errors.Errorf(`run "run01": task at index 0 is empty`),
|
||||
},
|
||||
{
|
||||
name: "test empty runtime arch",
|
||||
|
@ -88,7 +87,7 @@ func TestParseConfig(t *testing.T) {
|
|||
containers:
|
||||
- image: busybox
|
||||
`,
|
||||
err: fmt.Errorf(`task "task01" runtime: invalid arch "invalidarch"`),
|
||||
err: errors.Errorf(`task "task01" runtime: invalid arch "invalidarch"`),
|
||||
},
|
||||
{
|
||||
name: "test missing task dependency",
|
||||
|
@ -104,7 +103,7 @@ func TestParseConfig(t *testing.T) {
|
|||
depends:
|
||||
- task02
|
||||
`,
|
||||
err: fmt.Errorf(`run task "task02" needed by task "task01" doesn't exist`),
|
||||
err: errors.Errorf(`run task "task02" needed by task "task01" doesn't exist`),
|
||||
},
|
||||
{
|
||||
name: "test circular dependency between 2 tasks a -> b -> a",
|
||||
|
|
|
@ -17,21 +17,21 @@ package config
|
|||
import (
|
||||
"encoding/json"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/google/go-jsonnet"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func execJsonnet(configData []byte, configContext *ConfigContext) ([]byte, error) {
|
||||
vm := jsonnet.MakeVM()
|
||||
cj, err := json.Marshal(configContext)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal config context: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal config context")
|
||||
}
|
||||
|
||||
vm.TLACode("ctx", string(cj))
|
||||
out, err := vm.EvaluateSnippet("", string(configData))
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to evaluate jsonnet config: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to evaluate jsonnet config")
|
||||
}
|
||||
|
||||
return []byte(out), nil
|
||||
|
|
|
@ -19,29 +19,29 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"go.starlark.net/starlark"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func starlarkArgs(cc *ConfigContext) (starlark.Tuple, error) {
|
||||
d := &starlark.Dict{}
|
||||
if err := d.SetKey(starlark.String("ref_type"), starlark.String(cc.RefType)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if err := d.SetKey(starlark.String("ref"), starlark.String(cc.Ref)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if err := d.SetKey(starlark.String("branch"), starlark.String(cc.Branch)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if err := d.SetKey(starlark.String("tag"), starlark.String(cc.Tag)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if err := d.SetKey(starlark.String("pull_request_id"), starlark.String(cc.PullRequestID)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if err := d.SetKey(starlark.String("commit_sha"), starlark.String(cc.CommitSHA)); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return []starlark.Value{d}, nil
|
||||
|
@ -59,13 +59,13 @@ func starlarkJSON(out *bytes.Buffer, v starlark.Value) error {
|
|||
case starlark.Int:
|
||||
data, err := json.Marshal(v.BigInt())
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
out.Write(data)
|
||||
case starlark.Float:
|
||||
data, err := json.Marshal(float64(v))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
out.Write(data)
|
||||
case starlark.String:
|
||||
|
@ -76,7 +76,7 @@ func starlarkJSON(out *bytes.Buffer, v starlark.Value) error {
|
|||
e := json.NewEncoder(data)
|
||||
e.SetEscapeHTML(false)
|
||||
if err := e.Encode(string(v)); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// remove final \n introduced by the encoder
|
||||
out.Write(bytes.TrimSuffix(data.Bytes(), []byte("\n")))
|
||||
|
@ -87,7 +87,7 @@ func starlarkJSON(out *bytes.Buffer, v starlark.Value) error {
|
|||
out.WriteString(", ")
|
||||
}
|
||||
if err := starlarkJSON(out, v.Index(i)); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
out.WriteByte(']')
|
||||
|
@ -98,20 +98,20 @@ func starlarkJSON(out *bytes.Buffer, v starlark.Value) error {
|
|||
out.WriteString(", ")
|
||||
}
|
||||
if _, ok := item[0].(starlark.String); !ok {
|
||||
return fmt.Errorf("cannot convert non-string dict key to JSON")
|
||||
return errors.Errorf("cannot convert non-string dict key to JSON")
|
||||
}
|
||||
if err := starlarkJSON(out, item[0]); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
out.WriteString(": ")
|
||||
if err := starlarkJSON(out, item[1]); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
out.WriteByte('}')
|
||||
|
||||
default:
|
||||
return fmt.Errorf("cannot convert starlark type %q to JSON", v.Type())
|
||||
return errors.Errorf("cannot convert starlark type %q to JSON", v.Type())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func execStarlark(configData []byte, configContext *ConfigContext) ([]byte, erro
|
|||
}
|
||||
globals, err := starlark.ExecFile(thread, "config.star", configData, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// we require a main function that will be called wiht one
|
||||
|
@ -139,18 +139,18 @@ func execStarlark(configData []byte, configContext *ConfigContext) ([]byte, erro
|
|||
}
|
||||
args, err := starlarkArgs(configContext)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot create startlark arguments: %w", err)
|
||||
return nil, errors.Wrapf(err, "cannot create startlark arguments")
|
||||
}
|
||||
mainVal, err = starlark.Call(thread, main, args, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
switch v := mainVal.(type) {
|
||||
case *starlark.Dict:
|
||||
if err := starlarkJSON(buf, v); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
default:
|
||||
return nil, errors.Errorf("wrong starlark output, must be a dict")
|
||||
|
|
|
@ -16,10 +16,10 @@ package config
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"go.starlark.net/starlark"
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ func TestStarlarkJSON(t *testing.T) {
|
|||
_ = s.SetKey(starlark.MakeInt(10), starlark.String("string01"))
|
||||
return starlark.Value(s)
|
||||
}(),
|
||||
err: fmt.Errorf("cannot convert non-string dict key to JSON"),
|
||||
err: errors.Errorf("cannot convert non-string dict key to JSON"),
|
||||
},
|
||||
{
|
||||
name: "test list",
|
||||
|
|
|
@ -24,11 +24,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
|
||||
etcdclientv3rpc "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/mvcc/mvccpb"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// TODO(sgotti) rewrite this to use a sqlite local cache
|
||||
|
@ -132,7 +132,7 @@ func (d *DataManager) applyWalChanges(ctx context.Context, walData *WalData, rev
|
|||
|
||||
walDataFile, err := d.ost.ReadObject(walDataFilePath)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to read waldata %q: %w", walDataFilePath, err)
|
||||
return errors.Wrapf(err, "failed to read waldata %q", walDataFilePath)
|
||||
}
|
||||
defer walDataFile.Close()
|
||||
dec := json.NewDecoder(walDataFile)
|
||||
|
@ -148,7 +148,7 @@ func (d *DataManager) applyWalChanges(ctx context.Context, walData *WalData, rev
|
|||
break
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to decode wal file: %w", err)
|
||||
return errors.Wrapf(err, "failed to decode wal file")
|
||||
}
|
||||
|
||||
d.applyWalChangesAction(ctx, action, walData.WalSequence, revision)
|
||||
|
@ -200,7 +200,7 @@ func (d *DataManager) initializeChanges(ctx context.Context) error {
|
|||
for {
|
||||
listResp, err := d.e.ListPaged(ctx, etcdWalsDir+"/", 0, 10, continuation)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
resp := listResp.Resp
|
||||
continuation = listResp.Continuation
|
||||
|
@ -210,10 +210,10 @@ func (d *DataManager) initializeChanges(ctx context.Context) error {
|
|||
for _, kv := range resp.Kvs {
|
||||
var walData *WalData
|
||||
if err := json.Unmarshal(kv.Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := d.applyWalChanges(ctx, walData, revision); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
if !listResp.HasMore {
|
||||
|
@ -226,7 +226,7 @@ func (d *DataManager) initializeChanges(ctx context.Context) error {
|
|||
for {
|
||||
listResp, err := d.e.ListPaged(ctx, etcdChangeGroupsDir+"/", 0, 10, continuation)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
resp := listResp.Resp
|
||||
continuation = listResp.Continuation
|
||||
|
@ -267,7 +267,7 @@ func (d *DataManager) watcher(ctx context.Context) error {
|
|||
d.changes.initialized = false
|
||||
d.changes.Unlock()
|
||||
}
|
||||
return errors.Errorf("watch error: %w", err)
|
||||
return errors.Wrapf(err, "watch error")
|
||||
}
|
||||
revision := wresp.Header.Revision
|
||||
|
||||
|
@ -280,13 +280,13 @@ func (d *DataManager) watcher(ctx context.Context) error {
|
|||
case mvccpb.PUT:
|
||||
var walData *WalData
|
||||
if err := json.Unmarshal(ev.Kv.Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if walData.WalStatus != WalStatusCommitted {
|
||||
continue
|
||||
}
|
||||
if err := d.applyWalChanges(ctx, walData, revision); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
case mvccpb.DELETE:
|
||||
walseq := path.Base(string(key))
|
||||
|
|
|
@ -26,11 +26,11 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/objectstorage"
|
||||
"agola.io/agola/internal/sequence"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// ErrNoDataStatus represent when there's no data status files in the ost
|
||||
|
@ -96,12 +96,12 @@ func (d *DataManager) walIndex(ctx context.Context, wals []*WalData) (walIndex,
|
|||
for _, walData := range wals {
|
||||
header, err := d.ReadWal(walData.WalSequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
walFile, err := d.ReadWalData(header.WalDataFileID)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot read wal data file %q: %w", header.WalDataFileID, err)
|
||||
return nil, errors.Wrapf(err, "cannot read wal data file %q", header.WalDataFileID)
|
||||
}
|
||||
defer walFile.Close()
|
||||
|
||||
|
@ -115,7 +115,7 @@ func (d *DataManager) walIndex(ctx context.Context, wals []*WalData) (walIndex,
|
|||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to decode wal file: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to decode wal file")
|
||||
}
|
||||
|
||||
if _, ok := wimap[action.DataType]; !ok {
|
||||
|
@ -148,7 +148,7 @@ func (d *DataManager) walIndex(ctx context.Context, wals []*WalData) (walIndex,
|
|||
func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) error {
|
||||
dataSequence, err := sequence.IncSequence(ctx, d.e, etcdCheckpointSeqKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
var lastWalSequence string
|
||||
|
@ -164,7 +164,7 @@ func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) er
|
|||
|
||||
curDataStatus, err := d.GetLastDataStatus()
|
||||
if err != nil && !errors.Is(err, ErrNoDataStatus) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
startWalIndex := 0
|
||||
|
@ -184,7 +184,7 @@ func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) er
|
|||
|
||||
wi, err := d.walIndex(ctx, wals)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, dataType := range d.dataTypes {
|
||||
|
@ -194,14 +194,14 @@ func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) er
|
|||
}
|
||||
dataStatusFiles, err := d.writeDataType(ctx, wi, dataType, dataSequence, curDataStatusFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
dataStatus.Files[dataType] = dataStatusFiles
|
||||
}
|
||||
|
||||
dataStatusj, err := json.Marshal(dataStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil {
|
||||
return fromOSTError(err)
|
||||
|
@ -212,7 +212,7 @@ func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) er
|
|||
|
||||
func (d *DataManager) writeDataFile(ctx context.Context, buf *bytes.Buffer, size int64, dataFileIndex *DataFileIndex, dataFileID, dataType string) error {
|
||||
if buf.Len() == 0 {
|
||||
return fmt.Errorf("empty data entries")
|
||||
return errors.Errorf("empty data entries")
|
||||
}
|
||||
|
||||
if err := d.ost.WriteObject(d.DataFilePath(dataType, dataFileID), buf, size, true); err != nil {
|
||||
|
@ -221,7 +221,7 @@ func (d *DataManager) writeDataFile(ctx context.Context, buf *bytes.Buffer, size
|
|||
|
||||
dataFileIndexj, err := json.Marshal(dataFileIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := d.ost.WriteObject(d.DataFileIndexPath(dataType, dataFileID), bytes.NewReader(dataFileIndexj), int64(len(dataFileIndexj)), true); err != nil {
|
||||
return fromOSTError(err)
|
||||
|
@ -354,7 +354,7 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
|
|||
}
|
||||
if err != nil {
|
||||
oldDataf.Close()
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataEntries = append(dataEntries, de)
|
||||
|
@ -434,10 +434,10 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
|
|||
lastEntryID = de.ID
|
||||
dataEntryj, err := json.Marshal(de)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if _, err := buf.Write(dataEntryj); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
dataFileIndex.Index[de.ID] = pos - lastSplitPos
|
||||
prevPos := pos
|
||||
|
@ -470,7 +470,7 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
|
|||
for i, sp := range splitPoints {
|
||||
curDataFileID := d.dataFileID(dataSequence, uuid.Must(uuid.NewV4()).String())
|
||||
if err := d.writeDataFile(ctx, &buf, sp.pos-curPos, dataFileIndexes[i], curDataFileID, dataType); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
// insert new dataStatusFile
|
||||
dataStatusFiles = append(dataStatusFiles, &DataStatusFile{
|
||||
|
@ -492,7 +492,7 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
|
|||
func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
|
||||
curDataStatus, err := d.GetLastDataStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
curFiles := curDataStatus.Files
|
||||
|
||||
|
@ -519,7 +519,7 @@ func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
|
|||
err = dec.Decode(&dataFileIndex)
|
||||
if err != nil {
|
||||
dataFileIndexf.Close()
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
dataFileIndexf.Close()
|
||||
|
||||
|
@ -534,13 +534,13 @@ func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
|
|||
}
|
||||
if _, err := dataf.Seek(int64(pos), io.SeekStart); err != nil {
|
||||
dataf.Close()
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
var de *DataEntry
|
||||
dec = json.NewDecoder(dataf)
|
||||
if err := dec.Decode(&de); err != nil {
|
||||
dataf.Close()
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
dataf.Close()
|
||||
|
||||
|
@ -640,7 +640,7 @@ func (d *DataManager) GetDataStatus(dataSequence *sequence.Sequence) (*DataStatu
|
|||
func (d *DataManager) GetFirstDataStatusSequence() (*sequence.Sequence, error) {
|
||||
dataStatusSequences, err := d.GetFirstDataStatusSequences(1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return dataStatusSequences[0], nil
|
||||
|
@ -649,7 +649,7 @@ func (d *DataManager) GetFirstDataStatusSequence() (*sequence.Sequence, error) {
|
|||
func (d *DataManager) GetLastDataStatusSequence() (*sequence.Sequence, error) {
|
||||
dataStatusSequences, err := d.GetLastDataStatusSequences(1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return dataStatusSequences[0], nil
|
||||
|
@ -658,7 +658,7 @@ func (d *DataManager) GetLastDataStatusSequence() (*sequence.Sequence, error) {
|
|||
func (d *DataManager) GetFirstDataStatus() (*DataStatus, error) {
|
||||
dataStatusSequence, err := d.GetFirstDataStatusSequence()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return d.GetDataStatus(dataStatusSequence)
|
||||
|
@ -667,7 +667,7 @@ func (d *DataManager) GetFirstDataStatus() (*DataStatus, error) {
|
|||
func (d *DataManager) GetLastDataStatus() (*DataStatus, error) {
|
||||
dataStatusSequence, err := d.GetLastDataStatusSequence()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return d.GetDataStatus(dataStatusSequence)
|
||||
|
@ -675,12 +675,12 @@ func (d *DataManager) GetLastDataStatus() (*DataStatus, error) {
|
|||
|
||||
func (d *DataManager) Export(ctx context.Context, w io.Writer) error {
|
||||
if err := d.checkpoint(ctx, true); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
curDataStatus, err := d.GetLastDataStatus()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, dataType := range d.dataTypes {
|
||||
|
@ -695,7 +695,7 @@ func (d *DataManager) Export(ctx context.Context, w io.Writer) error {
|
|||
}
|
||||
if _, err := io.Copy(w, dataf); err != nil {
|
||||
dataf.Close()
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataf.Close()
|
||||
|
@ -708,7 +708,7 @@ func (d *DataManager) Export(ctx context.Context, w io.Writer) error {
|
|||
func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
||||
// delete contents in etcd
|
||||
if err := d.deleteEtcd(ctx); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// we require all entries of the same datatypes grouped together
|
||||
|
@ -717,7 +717,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
// create a new sequence, we assume that it'll be greater than previous data sequences
|
||||
dataSequence, err := sequence.IncSequence(ctx, d.e, etcdCheckpointSeqKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataStatus := &DataStatus{
|
||||
|
@ -745,7 +745,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
if errors.Is(err, io.EOF) {
|
||||
dataFileID := d.dataFileID(dataSequence, uuid.Must(uuid.NewV4()).String())
|
||||
if err := d.writeDataFile(ctx, &buf, int64(buf.Len()), dataFileIndex, dataFileID, curDataType); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataStatusFiles = append(dataStatusFiles, &DataStatusFile{
|
||||
|
@ -779,7 +779,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
if mustWrite {
|
||||
dataFileID := d.dataFileID(dataSequence, uuid.Must(uuid.NewV4()).String())
|
||||
if err := d.writeDataFile(ctx, &buf, int64(buf.Len()), dataFileIndex, dataFileID, curDataType); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataStatusFiles = append(dataStatusFiles, &DataStatusFile{
|
||||
|
@ -810,10 +810,10 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
|
||||
dataEntryj, err := json.Marshal(de)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, err := buf.Write(dataEntryj); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
dataFileIndex.Index[de.ID] = pos
|
||||
pos += int64(len(dataEntryj))
|
||||
|
@ -821,7 +821,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
|
||||
dataStatusj, err := json.Marshal(dataStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil {
|
||||
return fromOSTError(err)
|
||||
|
@ -829,7 +829,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
|
||||
// initialize etcd providing the specific datastatus
|
||||
if err := d.InitEtcd(ctx, dataStatus); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -838,7 +838,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
|
|||
func (d *DataManager) CleanOldCheckpoints(ctx context.Context) error {
|
||||
dataStatusSequences, err := d.GetLastDataStatusSequences(dataStatusToKeep)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return d.cleanOldCheckpoints(ctx, dataStatusSequences)
|
||||
|
@ -894,7 +894,7 @@ func (d *DataManager) cleanOldCheckpoints(ctx context.Context, dataStatusSequenc
|
|||
for _, dataStatusSequence := range dataStatusSequences {
|
||||
dataStatus, err := d.GetDataStatus(dataStatusSequence)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for dataType := range dataStatus.Files {
|
||||
|
|
|
@ -21,12 +21,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
"agola.io/agola/internal/objectstorage"
|
||||
"agola.io/agola/internal/sequence"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// TODO(sgotti) handle etcd unwanted changes:
|
||||
|
@ -252,7 +252,7 @@ func (d *DataManager) deleteEtcd(ctx context.Context) error {
|
|||
}
|
||||
for _, prefix := range prefixes {
|
||||
if err := d.e.DeletePrefix(ctx, prefix); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,12 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/objectstorage"
|
||||
"agola.io/agola/internal/testutil"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func setupEtcd(t *testing.T, log zerolog.Logger, dir string) *testutil.TestEmbeddedEtcd {
|
||||
|
@ -612,7 +612,7 @@ func doAndCheckCheckpoint(t *testing.T, ctx context.Context, dm *DataManager, ac
|
|||
// populate with a wal
|
||||
_, err := dm.WriteWal(ctx, actionGroup, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,11 +621,11 @@ func doAndCheckCheckpoint(t *testing.T, ctx context.Context, dm *DataManager, ac
|
|||
|
||||
// do a checkpoint
|
||||
if err := dm.checkpoint(ctx, true); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := checkDataFiles(ctx, t, dm, expectedEntries); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return expectedEntries, nil
|
||||
|
@ -635,7 +635,7 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
// read the data file
|
||||
curDataStatus, err := dm.GetLastDataStatus()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
allEntriesMap := map[string]*DataEntry{}
|
||||
|
@ -645,14 +645,14 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
for i, file := range curDataStatus.Files[dataType] {
|
||||
dataFileIndexf, err := dm.ost.ReadObject(dm.DataFileIndexPath(dataType, file.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
var dataFileIndex *DataFileIndex
|
||||
dec := json.NewDecoder(dataFileIndexf)
|
||||
err = dec.Decode(&dataFileIndex)
|
||||
if err != nil {
|
||||
dataFileIndexf.Close()
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
dataFileIndexf.Close()
|
||||
|
@ -660,7 +660,7 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
dataEntries := []*DataEntry{}
|
||||
dataf, err := dm.ost.ReadObject(dm.DataFilePath(dataType, file.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
dec = json.NewDecoder(dataf)
|
||||
var prevEntryID string
|
||||
|
@ -674,15 +674,15 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
}
|
||||
if err != nil {
|
||||
dataf.Close()
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// check that there are no duplicate entries
|
||||
if _, ok := allEntriesMap[de.ID]; ok {
|
||||
return fmt.Errorf("duplicate entry id: %s", de.ID)
|
||||
return errors.Errorf("duplicate entry id: %s", de.ID)
|
||||
}
|
||||
// check that the entries are in order
|
||||
if de.ID < prevEntryID {
|
||||
return fmt.Errorf("previous entry id: %s greater than entry id: %s", prevEntryID, de.ID)
|
||||
return errors.Errorf("previous entry id: %s greater than entry id: %s", prevEntryID, de.ID)
|
||||
}
|
||||
|
||||
dataEntriesMap[de.ID] = de
|
||||
|
@ -693,7 +693,7 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
|
||||
// check that the index matches the entries
|
||||
if len(dataFileIndex.Index) != len(dataEntriesMap) {
|
||||
return fmt.Errorf("index entries: %d different than data entries: %d", len(dataFileIndex.Index), len(dataEntriesMap))
|
||||
return errors.Errorf("index entries: %d different than data entries: %d", len(dataFileIndex.Index), len(dataEntriesMap))
|
||||
}
|
||||
indexIDs := make([]string, len(dataFileIndex.Index))
|
||||
entriesIDs := make([]string, len(dataEntriesMap))
|
||||
|
@ -706,19 +706,19 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
sort.Strings(indexIDs)
|
||||
sort.Strings(entriesIDs)
|
||||
if !reflect.DeepEqual(indexIDs, entriesIDs) {
|
||||
return fmt.Errorf("index entries ids don't match data entries ids: index: %v, data: %v", indexIDs, entriesIDs)
|
||||
return errors.Errorf("index entries ids don't match data entries ids: index: %v, data: %v", indexIDs, entriesIDs)
|
||||
}
|
||||
|
||||
if file.LastEntryID != dataEntries[len(dataEntries)-1].ID {
|
||||
return fmt.Errorf("lastEntryID for datafile %d: %s is different than real last entry id: %s", i, file.LastEntryID, dataEntries[len(dataEntries)-1].ID)
|
||||
return errors.Errorf("lastEntryID for datafile %d: %s is different than real last entry id: %s", i, file.LastEntryID, dataEntries[len(dataEntries)-1].ID)
|
||||
}
|
||||
|
||||
// check that all the files are in order
|
||||
if file.LastEntryID == prevLastEntryID {
|
||||
return fmt.Errorf("lastEntryID for datafile %d is equal than previous file lastEntryID: %s == %s", i, file.LastEntryID, prevLastEntryID)
|
||||
return errors.Errorf("lastEntryID for datafile %d is equal than previous file lastEntryID: %s == %s", i, file.LastEntryID, prevLastEntryID)
|
||||
}
|
||||
if file.LastEntryID < prevLastEntryID {
|
||||
return fmt.Errorf("lastEntryID for datafile %d is less than previous file lastEntryID: %s < %s", i, file.LastEntryID, prevLastEntryID)
|
||||
return errors.Errorf("lastEntryID for datafile %d is less than previous file lastEntryID: %s < %s", i, file.LastEntryID, prevLastEntryID)
|
||||
}
|
||||
prevLastEntryID = file.LastEntryID
|
||||
}
|
||||
|
@ -726,10 +726,10 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
|
|||
|
||||
// check that the number of entries is right
|
||||
if len(allEntriesMap) != len(expectedEntriesMap) {
|
||||
return fmt.Errorf("expected %d total entries, got %d", len(expectedEntriesMap), len(allEntriesMap))
|
||||
return errors.Errorf("expected %d total entries, got %d", len(expectedEntriesMap), len(allEntriesMap))
|
||||
}
|
||||
if !reflect.DeepEqual(expectedEntriesMap, allEntriesMap) {
|
||||
return fmt.Errorf("expected entries don't match current entries")
|
||||
return errors.Errorf("expected entries don't match current entries")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
"agola.io/agola/internal/objectstorage"
|
||||
"agola.io/agola/internal/sequence"
|
||||
|
@ -34,7 +35,6 @@ import (
|
|||
"go.etcd.io/etcd/clientv3/concurrency"
|
||||
etcdclientv3rpc "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/mvcc/mvccpb"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type ActionType string
|
||||
|
@ -127,7 +127,7 @@ func (d *DataManager) ReadObject(dataType, id string, cgNames []string) (io.Read
|
|||
}
|
||||
|
||||
f, err := d.Read(dataType, id)
|
||||
return ioutil.NopCloser(f), cgt, err
|
||||
return ioutil.NopCloser(f), cgt, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (d *DataManager) HasOSTWal(walseq string) (bool, error) {
|
||||
|
@ -150,7 +150,7 @@ func (d *DataManager) ReadWal(walseq string) (*WalHeader, error) {
|
|||
dec := json.NewDecoder(walFilef)
|
||||
var header *WalHeader
|
||||
if err = dec.Decode(&header); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return header, nil
|
||||
|
@ -260,7 +260,7 @@ func (d *DataManager) ListEtcdChangeGroups(ctx context.Context, revision int64)
|
|||
changeGroupsRevisions := changeGroupsRevisions{}
|
||||
resp, err := d.e.List(ctx, etcdChangeGroupsDir, "", revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
for _, kv := range resp.Kvs {
|
||||
changegroupID := path.Base(string(kv.Key))
|
||||
|
@ -277,7 +277,7 @@ func (d *DataManager) FirstAvailableWalData(ctx context.Context) (*WalData, int6
|
|||
// list waldata and just get the first if available
|
||||
listResp, err := d.e.ListPaged(ctx, etcdWalsDir, 0, 1, nil)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, errors.WithStack(err)
|
||||
}
|
||||
resp := listResp.Resp
|
||||
revision := resp.Header.Revision
|
||||
|
@ -288,7 +288,7 @@ func (d *DataManager) FirstAvailableWalData(ctx context.Context) (*WalData, int6
|
|||
|
||||
var walData *WalData
|
||||
if err := json.Unmarshal(resp.Kvs[0].Value, &walData); err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return walData, revision, nil
|
||||
|
@ -297,7 +297,7 @@ func (d *DataManager) FirstAvailableWalData(ctx context.Context) (*WalData, int6
|
|||
func (d *DataManager) LastCommittedStorageWal(ctx context.Context) (string, int64, error) {
|
||||
resp, err := d.e.Get(ctx, etcdLastCommittedStorageWalSeqKey, 0)
|
||||
if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return "", 0, err
|
||||
return "", 0, errors.WithStack(err)
|
||||
}
|
||||
if errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return "", 0, errors.Errorf("no last committedstorage wal on etcd")
|
||||
|
@ -424,17 +424,17 @@ func (d *DataManager) WriteWalAdditionalOps(ctx context.Context, actions []*Acti
|
|||
|
||||
walSequence, err := sequence.IncSequence(ctx, d.e, etcdWalSeqKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
resp, err := d.e.Get(ctx, etcdWalsDataKey, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var walsData WalsData
|
||||
if err := json.Unmarshal(resp.Kvs[0].Value, &walsData); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
walsData.Revision = resp.Kvs[0].ModRevision
|
||||
|
||||
|
@ -446,10 +446,10 @@ func (d *DataManager) WriteWalAdditionalOps(ctx context.Context, actions []*Acti
|
|||
for _, action := range actions {
|
||||
actionj, err := json.Marshal(action)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if _, err := buf.Write(actionj); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
if err := d.ost.WriteObject(walDataFilePath, bytes.NewReader(buf.Bytes()), int64(buf.Len()), true); err != nil {
|
||||
|
@ -468,11 +468,11 @@ func (d *DataManager) WriteWalAdditionalOps(ctx context.Context, actions []*Acti
|
|||
|
||||
walsDataj, err := json.Marshal(walsData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
walDataj, err := json.Marshal(walData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if cmp == nil {
|
||||
|
@ -512,7 +512,7 @@ func (d *DataManager) WriteWalAdditionalOps(ctx context.Context, actions []*Acti
|
|||
txn := d.e.Client().Txn(ctx).If(cmp...).Then(then...).Else(getWalsData, getWal)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return nil, etcd.FromEtcdError(err)
|
||||
return nil, errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
walsDataRev := tresp.Responses[0].GetResponseRange().Kvs[0].ModRevision
|
||||
|
@ -559,7 +559,7 @@ func (d *DataManager) syncLoop(ctx context.Context) {
|
|||
func (d *DataManager) sync(ctx context.Context) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -569,18 +569,18 @@ func (d *DataManager) sync(ctx context.Context) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
resp, err := d.e.List(ctx, etcdWalsDir+"/", "", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
for _, kv := range resp.Kvs {
|
||||
var walData WalData
|
||||
if err := json.Unmarshal(kv.Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// wals must be committed and checkpointed in order.
|
||||
// TODO(sgotti) this could be optimized by parallelizing writes of wals that don't have common change groups
|
||||
|
@ -594,7 +594,7 @@ func (d *DataManager) sync(ctx context.Context) error {
|
|||
}
|
||||
headerj, err := json.Marshal(header)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
walFileCommittedPath := walFilePath + ".committed"
|
||||
|
@ -606,7 +606,7 @@ func (d *DataManager) sync(ctx context.Context) error {
|
|||
walData.WalStatus = WalStatusCommittedStorage
|
||||
walDataj, err := json.Marshal(walData)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
cmp := []etcdclientv3.Cmp{}
|
||||
|
@ -619,7 +619,7 @@ func (d *DataManager) sync(ctx context.Context) error {
|
|||
txn := d.e.Client().Txn(ctx).If(cmp...).Then(then...)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
return errors.Errorf("failed to write committedstorage wal: concurrent update")
|
||||
|
@ -648,7 +648,7 @@ func (d *DataManager) checkpointLoop(ctx context.Context) {
|
|||
func (d *DataManager) checkpoint(ctx context.Context, force bool) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -658,19 +658,19 @@ func (d *DataManager) checkpoint(ctx context.Context, force bool) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
resp, err := d.e.List(ctx, etcdWalsDir+"/", "", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
walsData := []*WalData{}
|
||||
for _, kv := range resp.Kvs {
|
||||
var walData *WalData
|
||||
if err := json.Unmarshal(kv.Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
walData.Revision = kv.ModRevision
|
||||
|
||||
|
@ -692,7 +692,7 @@ func (d *DataManager) checkpoint(ctx context.Context, force bool) error {
|
|||
}
|
||||
|
||||
if err := d.writeDataSnapshot(ctx, walsData); err != nil {
|
||||
return errors.Errorf("checkpoint function error: %w", err)
|
||||
return errors.Wrapf(err, "checkpoint function error")
|
||||
}
|
||||
|
||||
for _, walData := range walsData {
|
||||
|
@ -700,11 +700,11 @@ func (d *DataManager) checkpoint(ctx context.Context, force bool) error {
|
|||
walData.WalStatus = WalStatusCheckpointed
|
||||
walDataj, err := json.Marshal(walData)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
walKey := etcdWalKey(walData.WalSequence)
|
||||
if _, err := d.e.AtomicPut(ctx, walKey, walDataj, walData.Revision, nil); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,7 +730,7 @@ func (d *DataManager) checkpointCleanLoop(ctx context.Context) {
|
|||
func (d *DataManager) checkpointClean(ctx context.Context) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -740,12 +740,12 @@ func (d *DataManager) checkpointClean(ctx context.Context) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
if err := d.CleanOldCheckpoints(ctx); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -773,7 +773,7 @@ func (d *DataManager) etcdWalCleanerLoop(ctx context.Context) {
|
|||
func (d *DataManager) etcdWalCleaner(ctx context.Context) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -783,13 +783,13 @@ func (d *DataManager) etcdWalCleaner(ctx context.Context) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
resp, err := d.e.List(ctx, etcdWalsDir+"/", "", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if len(resp.Kvs) <= d.etcdWalsKeepNum {
|
||||
return nil
|
||||
|
@ -799,7 +799,7 @@ func (d *DataManager) etcdWalCleaner(ctx context.Context) error {
|
|||
for _, kv := range resp.Kvs {
|
||||
var walData WalData
|
||||
if err := json.Unmarshal(kv.Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if walData.WalStatus != WalStatusCheckpointed {
|
||||
break
|
||||
|
@ -814,7 +814,7 @@ func (d *DataManager) etcdWalCleaner(ctx context.Context) error {
|
|||
// arrive to a differnt S3 server that is not yet in sync?
|
||||
d.log.Info().Msgf("removing wal %q from etcd", walData.WalSequence)
|
||||
if _, err := d.e.AtomicDelete(ctx, string(kv.Key), kv.ModRevision); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
removeCount--
|
||||
|
@ -846,7 +846,7 @@ func (d *DataManager) storageWalCleanerLoop(ctx context.Context) {
|
|||
func (d *DataManager) storageWalCleaner(ctx context.Context) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -856,13 +856,13 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
firstDataStatus, err := d.GetFirstDataStatus()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
firstWalSequence := firstDataStatus.WalSequence
|
||||
|
||||
|
@ -870,14 +870,14 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
|
|||
// it's lesser than the first data status wal sequence
|
||||
resp, err := d.e.List(ctx, etcdWalsDir+"/", "", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if len(resp.Kvs) == 0 {
|
||||
return errors.Errorf("no wals in etcd")
|
||||
}
|
||||
var walData WalData
|
||||
if err := json.Unmarshal(resp.Kvs[0].Value, &walData); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if walData.WalSequence < firstWalSequence {
|
||||
firstWalSequence = walData.WalSequence
|
||||
|
@ -902,7 +902,7 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
|
|||
|
||||
header, err := d.ReadWal(walSequence)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// first remove wal data file
|
||||
|
@ -956,7 +956,7 @@ func (d *DataManager) compactChangeGroupsLoop(ctx context.Context) {
|
|||
func (d *DataManager) compactChangeGroups(ctx context.Context) error {
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -966,13 +966,13 @@ func (d *DataManager) compactChangeGroups(ctx context.Context) error {
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
resp, err := d.e.Client().Get(ctx, etcdChangeGroupMinRevisionKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if len(resp.Kvs) == 0 {
|
||||
|
@ -986,7 +986,8 @@ func (d *DataManager) compactChangeGroups(ctx context.Context) error {
|
|||
txn := d.e.Client().Txn(ctx).If(cmp).Then(then)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
return errors.Errorf("failed to update change group min revision key due to concurrent update")
|
||||
|
@ -997,7 +998,7 @@ func (d *DataManager) compactChangeGroups(ctx context.Context) error {
|
|||
// then remove all the groups keys with modrevision < minrevision
|
||||
resp, err = d.e.List(ctx, etcdChangeGroupsDir, "", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
for _, kv := range resp.Kvs {
|
||||
if kv.ModRevision < revision-etcdChangeGroupMinRevisionRange {
|
||||
|
@ -1006,7 +1007,7 @@ func (d *DataManager) compactChangeGroups(ctx context.Context) error {
|
|||
txn := d.e.Client().Txn(ctx).If(cmp).Then(then)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
d.log.Err(err).Msgf("failed to update change group min revision key due to concurrent update")
|
||||
|
@ -1040,7 +1041,7 @@ func (d *DataManager) etcdPingerLoop(ctx context.Context) {
|
|||
|
||||
func (d *DataManager) etcdPinger(ctx context.Context) error {
|
||||
if _, err := d.e.Put(ctx, etcdPingKey, []byte{}, nil); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1055,7 +1056,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
var header *WalHeader
|
||||
if err = dec.Decode(&header); err != nil && !errors.Is(err, io.EOF) {
|
||||
walFile.Close()
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
walFile.Close()
|
||||
|
||||
|
@ -1073,7 +1074,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
}
|
||||
walDataj, err := json.Marshal(walData)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
cmp := []etcdclientv3.Cmp{}
|
||||
|
@ -1084,7 +1085,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
txn := d.e.Client().Txn(ctx).If(cmp...).Then(then...)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
return errors.Errorf("failed to sync etcd: wal %q already written", wal.WalSequence)
|
||||
|
@ -1094,7 +1095,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
|
||||
session, err := concurrency.NewSession(d.e.Client(), concurrency.WithTTL(5), concurrency.WithContext(ctx))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
|
@ -1104,7 +1105,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
if errors.Is(err, etcd.ErrLocked) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() { _ = m.Unlock(ctx) }()
|
||||
|
||||
|
@ -1113,7 +1114,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
_, err = d.e.Get(ctx, etcdWalsDataKey, 0)
|
||||
if err != nil {
|
||||
if !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
mustInit = true
|
||||
}
|
||||
|
@ -1123,7 +1124,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
|
||||
// delete all wals from etcd
|
||||
if err := d.deleteEtcd(ctx); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1135,7 +1136,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
then = append(then, etcdclientv3.OpPut(etcdChangeGroupMinRevisionKey, ""))
|
||||
txn := d.e.Client().Txn(ctx).If(cmp...).Then(then...)
|
||||
if _, err := txn.Commit(); err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
|
||||
if !mustInit {
|
||||
|
@ -1150,7 +1151,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
} else {
|
||||
dataStatus, err = d.GetLastDataStatus()
|
||||
if err != nil && !errors.Is(err, ErrNoDataStatus) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// set the first wal to import in etcd if there's a snapshot. In this way we'll
|
||||
// ignore older wals (or wals left after an import)
|
||||
|
@ -1172,7 +1173,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
}
|
||||
d.log.Debug().Msgf("wal: %s", wal)
|
||||
if wal.Err != nil {
|
||||
return wal.Err
|
||||
return errors.WithStack(wal.Err)
|
||||
}
|
||||
|
||||
if wal.WalSequence < firstWal {
|
||||
|
@ -1182,7 +1183,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
lastCommittedStorageWalSequence = wal.WalSequence
|
||||
|
||||
if err := writeWal(wal, previousWalSequence); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
previousWalSequence = wal.WalSequence
|
||||
wroteWals++
|
||||
|
@ -1192,7 +1193,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
// insert an empty wal and make it already committedstorage
|
||||
walSequence, err := sequence.IncSequence(ctx, d.e, etcdWalSeqKey)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
walDataFileID := uuid.Must(uuid.NewV4()).String()
|
||||
|
@ -1212,7 +1213,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
}
|
||||
headerj, err := json.Marshal(header)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
walFileCommittedPath := walFilePath + ".committed"
|
||||
if err := d.ost.WriteObject(walFileCommittedPath, bytes.NewReader(headerj), int64(len(headerj)), true); err != nil {
|
||||
|
@ -1234,12 +1235,12 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
|
||||
walDataj, err := json.Marshal(walData)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
walsDataj, err := json.Marshal(walsData)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// save walsdata and lastcommittedstoragewalseq only after writing all the
|
||||
|
@ -1256,7 +1257,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
txn = d.e.Client().Txn(ctx).If(cmp...).Then(then...)
|
||||
tresp, err := txn.Commit()
|
||||
if err != nil {
|
||||
return etcd.FromEtcdError(err)
|
||||
return errors.WithStack(etcd.FromEtcdError(err))
|
||||
}
|
||||
if !tresp.Succeeded {
|
||||
return errors.Errorf("failed to sync etcd: walsdata already written")
|
||||
|
@ -1264,7 +1265,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
|
|||
|
||||
// force a checkpoint
|
||||
if err := d.checkpoint(ctx, true); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -18,8 +18,8 @@ import (
|
|||
"context"
|
||||
"database/sql"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const dbVersionTableDDLTmpl = `
|
||||
|
@ -33,22 +33,22 @@ func (db *DB) Create(ctx context.Context, stmts []string) error {
|
|||
|
||||
err := db.Do(ctx, func(tx *Tx) error {
|
||||
if _, err := tx.Exec(dbVersionTableDDLTmpl); err != nil {
|
||||
return errors.Errorf("failed to create dbversion table: %w", err)
|
||||
return errors.Wrapf(err, "failed to create dbversion table")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
err = db.Do(ctx, func(tx *Tx) error {
|
||||
var version sql.NullInt64
|
||||
q, args, err := sb.Select("max(version)").From("dbversion").ToSql()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := tx.QueryRow(q, args...).Scan(&version); err != nil {
|
||||
return errors.Errorf("cannot get current db version: %w", err)
|
||||
return errors.Wrapf(err, "cannot get current db version")
|
||||
}
|
||||
if version.Valid {
|
||||
return nil
|
||||
|
@ -56,18 +56,18 @@ func (db *DB) Create(ctx context.Context, stmts []string) error {
|
|||
|
||||
for _, stmt := range stmts {
|
||||
if _, err := tx.Exec(stmt); err != nil {
|
||||
return errors.Errorf("creation failed: %w", err)
|
||||
return errors.Wrapf(err, "creation failed")
|
||||
}
|
||||
}
|
||||
|
||||
q, args, err = sb.Insert("dbversion").Columns("version", "time").Values(dbVersion, "now()").ToSql()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, err := tx.Exec(q, args...); err != nil {
|
||||
return errors.Errorf("failed to update dbversion table: %w", err)
|
||||
return errors.Wrapf(err, "failed to update dbversion table")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ import (
|
|||
"regexp"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type Type string
|
||||
|
@ -128,7 +128,7 @@ func NewDB(dbType Type, dbConnString string) (*DB, error) {
|
|||
|
||||
sqldb, err := sql.Open(driverName, dbConnString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
db := &DB{
|
||||
|
@ -151,11 +151,12 @@ type Tx struct {
|
|||
}
|
||||
|
||||
func (db *DB) Close() error {
|
||||
return db.db.Close()
|
||||
return errors.WithStack(db.db.Close())
|
||||
}
|
||||
|
||||
func (db *DB) Conn(ctx context.Context) (*sql.Conn, error) {
|
||||
return db.db.Conn(ctx)
|
||||
c, err := db.db.Conn(ctx)
|
||||
return c, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (db *DB) NewUnstartedTx() *Tx {
|
||||
|
@ -167,7 +168,7 @@ func (db *DB) NewUnstartedTx() *Tx {
|
|||
func (db *DB) NewTx(ctx context.Context) (*Tx, error) {
|
||||
tx := db.NewUnstartedTx()
|
||||
if err := tx.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
|
@ -188,14 +189,14 @@ func (db *DB) Do(ctx context.Context, f func(tx *Tx) error) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DB) do(ctx context.Context, f func(tx *Tx) error) error {
|
||||
tx, err := db.NewTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
|
@ -205,7 +206,7 @@ func (db *DB) do(ctx context.Context, f func(tx *Tx) error) error {
|
|||
}()
|
||||
if err = f(tx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
@ -213,12 +214,12 @@ func (db *DB) do(ctx context.Context, f func(tx *Tx) error) error {
|
|||
func (tx *Tx) Start(ctx context.Context) error {
|
||||
wtx, err := tx.db.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
switch tx.db.data.t {
|
||||
case Postgres:
|
||||
if _, err := wtx.Exec("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
tx.tx = wtx
|
||||
|
@ -230,26 +231,26 @@ func (tx *Tx) Commit() error {
|
|||
if tx.tx == nil {
|
||||
return nil
|
||||
}
|
||||
return tx.tx.Commit()
|
||||
return errors.WithStack(tx.tx.Commit())
|
||||
}
|
||||
|
||||
func (tx *Tx) Rollback() error {
|
||||
if tx.tx == nil {
|
||||
return nil
|
||||
}
|
||||
return tx.tx.Rollback()
|
||||
return errors.WithStack(tx.tx.Rollback())
|
||||
}
|
||||
|
||||
func (tx *Tx) Exec(query string, args ...interface{}) (sql.Result, error) {
|
||||
query = tx.db.data.translate(query)
|
||||
r, err := tx.tx.ExecContext(tx.ctx, query, tx.db.data.translateArgs(args)...)
|
||||
return r, err
|
||||
return r, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (tx *Tx) Query(query string, args ...interface{}) (*sql.Rows, error) {
|
||||
query = tx.db.data.translate(query)
|
||||
r, err := tx.tx.QueryContext(tx.ctx, query, tx.db.data.translateArgs(args)...)
|
||||
return r, err
|
||||
return r, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *sql.Row {
|
||||
|
@ -262,13 +263,14 @@ func (tx *Tx) CurTime() (time.Time, error) {
|
|||
case Sqlite3:
|
||||
var timestring string
|
||||
if err := tx.QueryRow("select now()").Scan(×tring); err != nil {
|
||||
return time.Time{}, err
|
||||
return time.Time{}, errors.WithStack(err)
|
||||
}
|
||||
return time.ParseInLocation("2006-01-02 15:04:05.999999999", timestring, time.UTC)
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05.999999999", timestring, time.UTC)
|
||||
return t, errors.WithStack(err)
|
||||
case Postgres:
|
||||
var now time.Time
|
||||
if err := tx.QueryRow("select now()").Scan(&now); err != nil {
|
||||
return time.Time{}, err
|
||||
return time.Time{}, errors.WithStack(err)
|
||||
}
|
||||
return now, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type werror struct {
|
||||
cause error
|
||||
msg string
|
||||
*Stack
|
||||
}
|
||||
|
||||
func (w *werror) Error() string {
|
||||
if w.cause == nil {
|
||||
return w.msg
|
||||
}
|
||||
if w.msg != "" {
|
||||
return w.msg + ": " + w.cause.Error()
|
||||
} else {
|
||||
return w.cause.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *werror) Format(s fmt.State, verb rune) {
|
||||
_, _ = io.WriteString(s, w.Error())
|
||||
}
|
||||
|
||||
func (w *werror) Unwrap() error { return w.cause }
|
||||
|
||||
// New returns an error with the supplied message.
|
||||
// New also records the stack trace at the point it was called.
|
||||
func New(message string) error {
|
||||
return &werror{
|
||||
msg: message,
|
||||
Stack: Callers(0),
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf formats according to a format specifier and returns the string
|
||||
// as a value that satisfies error.
|
||||
// Errorf also records the stack trace at the point it was called.
|
||||
func Errorf(format string, args ...interface{}) error {
|
||||
return &werror{
|
||||
msg: fmt.Sprintf(format, args...),
|
||||
Stack: Callers(0),
|
||||
}
|
||||
}
|
||||
|
||||
// WithStack annotates err with a stack trace at the point WithStack was called.
|
||||
// If err is nil, WithStack returns nil.
|
||||
func WithStack(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &werror{
|
||||
err,
|
||||
"",
|
||||
Callers(0),
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap returns an error annotating err with a stack trace
|
||||
// at the point Wrap is called, and the supplied message.
|
||||
// If err is nil, Wrap returns nil.
|
||||
func Wrap(err error, message string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &werror{
|
||||
err,
|
||||
message,
|
||||
Callers(0),
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapf returns an error annotating err with a stack trace
|
||||
// at the point Wrapf is called, and the format specifier.
|
||||
// If err is nil, Wrapf returns nil.
|
||||
func Wrapf(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &werror{
|
||||
err,
|
||||
fmt.Sprintf(format, args...),
|
||||
Callers(0),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func PrintErrorDetails(err error) []string {
|
||||
type stackTracer interface {
|
||||
StackTrace() StackTrace
|
||||
}
|
||||
type errWithStack struct {
|
||||
err error
|
||||
msg string
|
||||
stack StackTrace
|
||||
}
|
||||
|
||||
var stackErrs []errWithStack
|
||||
errCause := err
|
||||
for errCause != nil {
|
||||
stackErr := errWithStack{
|
||||
err: errCause,
|
||||
msg: errCause.Error(),
|
||||
}
|
||||
//nolint:errorlint
|
||||
if s, ok := errCause.(stackTracer); ok {
|
||||
stackErr.stack = s.StackTrace()
|
||||
}
|
||||
stackErrs = append(stackErrs, stackErr)
|
||||
errCause = errors.Unwrap(errCause)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var lines []string
|
||||
for _, stackErr := range stackErrs {
|
||||
if len(stackErr.stack) > 0 {
|
||||
frame := stackErr.stack[0]
|
||||
lines = append(lines, fmt.Sprintf("(%T) %+v: %s", stackErr.err, frame, stackErr.msg))
|
||||
} else {
|
||||
lines = append(lines, fmt.Sprintf("(%T) %s", stackErr.err, stackErr.msg))
|
||||
}
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// +build go1.13
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
stderrors "errors"
|
||||
)
|
||||
|
||||
// Is reports whether any error in err's chain matches target.
|
||||
//
|
||||
// The chain consists of err itself followed by the sequence of errors obtained by
|
||||
// repeatedly calling Unwrap.
|
||||
//
|
||||
// An error is considered to match a target if it is equal to that target or if
|
||||
// it implements a method Is(error) bool such that Is(target) returns true.
|
||||
func Is(err, target error) bool { return stderrors.Is(err, target) }
|
||||
|
||||
// As finds the first error in err's chain that matches target, and if so, sets
|
||||
// target to that error value and returns true.
|
||||
//
|
||||
// The chain consists of err itself followed by the sequence of errors obtained by
|
||||
// repeatedly calling Unwrap.
|
||||
//
|
||||
// An error matches target if the error's concrete value is assignable to the value
|
||||
// pointed to by target, or if the error has a method As(interface{}) bool such that
|
||||
// As(target) returns true. In the latter case, the As method is responsible for
|
||||
// setting target.
|
||||
//
|
||||
// As will panic if target is not a non-nil pointer to either a type that implements
|
||||
// error, or to any interface type. As returns false if err is nil.
|
||||
func As(err error, target interface{}) bool { return stderrors.As(err, target) }
|
||||
|
||||
// Unwrap returns the result of calling the Unwrap method on err, if err's
|
||||
// type contains an Unwrap method returning error.
|
||||
// Otherwise, Unwrap returns nil.
|
||||
func Unwrap(err error) error {
|
||||
return stderrors.Unwrap(err)
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultSkip = 3
|
||||
)
|
||||
|
||||
// Frame represents a program counter inside a stack frame.
|
||||
// For historical reasons if Frame is interpreted as a uintptr
|
||||
// its value represents the program counter + 1.
|
||||
type Frame uintptr
|
||||
|
||||
// pc returns the program counter for this frame;
|
||||
// multiple frames may have the same PC value.
|
||||
func (f Frame) pc() uintptr { return uintptr(f) - 1 }
|
||||
|
||||
// file returns the full path to the file that contains the
|
||||
// function for this Frame's pc.
|
||||
func (f Frame) file() string {
|
||||
fn := runtime.FuncForPC(f.pc())
|
||||
if fn == nil {
|
||||
return "unknown"
|
||||
}
|
||||
file, _ := fn.FileLine(f.pc())
|
||||
return file
|
||||
}
|
||||
|
||||
// line returns the line number of source code of the
|
||||
// function for this Frame's pc.
|
||||
func (f Frame) line() int {
|
||||
fn := runtime.FuncForPC(f.pc())
|
||||
if fn == nil {
|
||||
return 0
|
||||
}
|
||||
_, line := fn.FileLine(f.pc())
|
||||
return line
|
||||
}
|
||||
|
||||
// name returns the name of this function, if known.
|
||||
func (f Frame) name() string {
|
||||
fn := runtime.FuncForPC(f.pc())
|
||||
if fn == nil {
|
||||
return "unknown"
|
||||
}
|
||||
return fn.Name()
|
||||
}
|
||||
|
||||
// Format formats the frame according to the fmt.Formatter interface.
|
||||
//
|
||||
// %s source file
|
||||
// %d source line
|
||||
// %n function name
|
||||
// %v equivalent to %s:%d
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+s function name and path of source file relative to the compile time
|
||||
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
||||
// %+v equivalent to %+s:%d
|
||||
func (f Frame) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
switch {
|
||||
case s.Flag('+'):
|
||||
_, _ = io.WriteString(s, f.name())
|
||||
_, _ = io.WriteString(s, "\n\t")
|
||||
_, _ = io.WriteString(s, f.file())
|
||||
default:
|
||||
_, _ = io.WriteString(s, path.Base(f.file()))
|
||||
}
|
||||
case 'd':
|
||||
_, _ = io.WriteString(s, strconv.Itoa(f.line()))
|
||||
case 'n':
|
||||
_, _ = io.WriteString(s, funcname(f.name()))
|
||||
case 'v':
|
||||
f.Format(s, 's')
|
||||
_, _ = io.WriteString(s, ":")
|
||||
f.Format(s, 'd')
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalText formats a stacktrace Frame as a text string. The output is the
|
||||
// same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.
|
||||
func (f Frame) MarshalText() ([]byte, error) {
|
||||
name := f.name()
|
||||
if name == "unknown" {
|
||||
return []byte(name), nil
|
||||
}
|
||||
return []byte(fmt.Sprintf("%s %s:%d", name, f.file(), f.line())), nil
|
||||
}
|
||||
|
||||
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
||||
type StackTrace []Frame
|
||||
|
||||
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
||||
//
|
||||
// %s lists source files for each Frame in the stack
|
||||
// %v lists the source file and line number for each Frame in the stack
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+v Prints filename, function, and line number for each Frame in the stack.
|
||||
func (st StackTrace) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
switch {
|
||||
case s.Flag('+'):
|
||||
for _, f := range st {
|
||||
_, _ = io.WriteString(s, "\n")
|
||||
f.Format(s, verb)
|
||||
}
|
||||
case s.Flag('#'):
|
||||
fmt.Fprintf(s, "%#v", []Frame(st))
|
||||
default:
|
||||
st.formatSlice(s, verb)
|
||||
}
|
||||
case 's':
|
||||
st.formatSlice(s, verb)
|
||||
}
|
||||
}
|
||||
|
||||
// formatSlice will format this StackTrace into the given buffer as a slice of
|
||||
// Frame, only valid when called with '%s' or '%v'.
|
||||
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
|
||||
_, _ = io.WriteString(s, "[")
|
||||
for i, f := range st {
|
||||
if i > 0 {
|
||||
_, _ = io.WriteString(s, " ")
|
||||
}
|
||||
f.Format(s, verb)
|
||||
}
|
||||
_, _ = io.WriteString(s, "]")
|
||||
}
|
||||
|
||||
// Stack represents a Stack of program counters.
|
||||
type Stack []uintptr
|
||||
|
||||
func (s *Stack) Format(st fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
switch {
|
||||
case st.Flag('+'):
|
||||
for _, pc := range *s {
|
||||
f := Frame(pc)
|
||||
fmt.Fprintf(st, "\n%+v", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stack) StackTrace() StackTrace {
|
||||
f := make([]Frame, len(*s))
|
||||
for i := 0; i < len(f); i++ {
|
||||
f[i] = Frame((*s)[i])
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func Callers(additionalSkip int) *Stack {
|
||||
const depth = 32
|
||||
var pcs [depth]uintptr
|
||||
n := runtime.Callers(defaultSkip+additionalSkip, pcs[:])
|
||||
var st Stack = pcs[0:n]
|
||||
return &st
|
||||
}
|
||||
|
||||
// funcname removes the path prefix component of a function's name reported by func.Name().
|
||||
func funcname(name string) string {
|
||||
i := strings.LastIndex(name, "/")
|
||||
name = name[i+1:]
|
||||
i = strings.Index(name, ".")
|
||||
return name[i+1:]
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// copied from zerolog console writer since they aren't exported
|
||||
//nolint
|
||||
const (
|
||||
colorBlack = iota + 30
|
||||
colorRed
|
||||
colorGreen
|
||||
colorYellow
|
||||
colorBlue
|
||||
colorMagenta
|
||||
colorCyan
|
||||
colorWhite
|
||||
)
|
||||
|
||||
// colorize returns the string s wrapped in ANSI code c, unless disabled is true.
|
||||
func colorize(s interface{}, c int, disabled bool) string {
|
||||
if disabled {
|
||||
return fmt.Sprintf("%s", s)
|
||||
}
|
||||
return fmt.Sprintf("\x1b[%dm%v\x1b[0m", c, s)
|
||||
}
|
||||
|
||||
type errorFormat = struct {
|
||||
Error string
|
||||
Details []string
|
||||
}
|
||||
|
||||
func FormatErrFieldValue(i interface{}) string {
|
||||
switch d := i.(type) {
|
||||
case []byte:
|
||||
var ed errorFormat
|
||||
if err := json.Unmarshal(d, &ed); err != nil {
|
||||
return fmt.Sprintf("error: %v", err)
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("%s\n", ed.Error))
|
||||
if len(ed.Details) > 0 {
|
||||
sb.WriteString("error details:\n")
|
||||
for _, l := range ed.Details {
|
||||
sb.WriteString(fmt.Sprintf("%s\n", l))
|
||||
}
|
||||
}
|
||||
return colorize(sb.String(), colorRed, false)
|
||||
|
||||
default:
|
||||
return colorize(fmt.Sprintf("%s", d), colorRed, false)
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorMarshalFunc(err error) interface{} {
|
||||
ef := errorFormat{
|
||||
Error: err.Error(),
|
||||
Details: PrintErrorDetails(err),
|
||||
}
|
||||
return ef
|
||||
}
|
|
@ -22,6 +22,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -29,7 +30,6 @@ import (
|
|||
etcdclientv3 "go.etcd.io/etcd/clientv3"
|
||||
"go.etcd.io/etcd/clientv3/namespace"
|
||||
"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -65,7 +65,7 @@ func FromEtcdError(err error) error {
|
|||
if errors.Is(err, rpctypes.ErrKeyNotFound) {
|
||||
return ErrKeyNotFound
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
|
@ -90,7 +90,7 @@ func New(cfg Config) (*Store, error) {
|
|||
for _, e := range endpoints {
|
||||
u, err := url.Parse(e)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot parse endpoint %q: %w", e, err)
|
||||
return nil, errors.Wrapf(err, "cannot parse endpoint %q", e)
|
||||
}
|
||||
if scheme == "" {
|
||||
scheme = u.Scheme
|
||||
|
@ -108,7 +108,7 @@ func New(cfg Config) (*Store, error) {
|
|||
var err error
|
||||
tlsConfig, err = util.NewTLSConfig(cfg.CertFile, cfg.KeyFile, cfg.CAFile, cfg.SkipTLSVerify)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot create tls config: %w", err)
|
||||
return nil, errors.Wrapf(err, "cannot create tls config")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ func New(cfg Config) (*Store, error) {
|
|||
|
||||
c, err := etcdclientv3.New(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
c.KV = namespace.NewKV(c.KV, prefix)
|
||||
|
@ -150,7 +150,7 @@ func (s *Store) Put(ctx context.Context, key string, value []byte, options *Writ
|
|||
if options.TTL > 0 {
|
||||
lease, err := s.c.Grant(ctx, int64(options.TTL.Seconds()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
etcdv3Options = append(etcdv3Options, etcdclientv3.WithLease(lease.ID))
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ func (s *Store) AtomicPut(ctx context.Context, key string, value []byte, prevRev
|
|||
if options.TTL > 0 {
|
||||
lease, err := s.c.Grant(ctx, int64(options.TTL))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
etcdv3Options = append(etcdv3Options, etcdclientv3.WithLease(lease.ID))
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ func (s *Store) AtomicPut(ctx context.Context, key string, value []byte, prevRev
|
|||
func (s *Store) Delete(ctx context.Context, key string) error {
|
||||
_, err := s.c.Delete(ctx, key)
|
||||
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *Store) DeletePrefix(ctx context.Context, prefix string) error {
|
||||
|
@ -298,7 +298,7 @@ func (s *Store) DeletePrefix(ctx context.Context, prefix string) error {
|
|||
|
||||
_, err := s.c.Delete(ctx, key, etcdv3Options...)
|
||||
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *Store) AtomicDelete(ctx context.Context, key string, revision int64) (*etcdclientv3.TxnResponse, error) {
|
||||
|
@ -333,7 +333,7 @@ func (s *Store) Watch(ctx context.Context, prefix string, revision int64) etcdcl
|
|||
}
|
||||
|
||||
func (s *Store) Close() error {
|
||||
return s.c.Close()
|
||||
return errors.WithStack(s.c.Close())
|
||||
}
|
||||
|
||||
func (s *Store) compactor(ctx context.Context, interval time.Duration) {
|
||||
|
@ -364,7 +364,7 @@ func (s *Store) compact(ctx context.Context, version, rev int64) (int64, int64,
|
|||
).Commit()
|
||||
|
||||
if err != nil {
|
||||
return version, rev, err
|
||||
return version, rev, errors.WithStack(err)
|
||||
}
|
||||
|
||||
curRev := resp.Header.Revision
|
||||
|
@ -380,7 +380,7 @@ func (s *Store) compact(ctx context.Context, version, rev int64) (int64, int64,
|
|||
}
|
||||
if _, err = s.c.Compact(ctx, rev); err != nil {
|
||||
s.log.Warn().Msgf("compact error: %v", err)
|
||||
return curVersion, curRev, err
|
||||
return curVersion, curRev, errors.WithStack(err)
|
||||
}
|
||||
s.log.Info().Msgf("compacted revision: %d", rev)
|
||||
return curVersion, curRev, nil
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// have the TryLock function not yet available on stable v3.4 client
|
||||
// Remove this when updating the client to a version providing TryLock
|
||||
|
||||
//nolint:wrapcheck
|
||||
package etcd
|
||||
|
||||
import (
|
||||
|
|
|
@ -24,10 +24,10 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -109,21 +109,21 @@ func InfoRefsResponse(ctx context.Context, repoPath, serviceName string) ([]byte
|
|||
git := &util.Git{}
|
||||
out, err := git.Output(ctx, nil, serviceName, "--stateless-rpc", "--advertise-refs", repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
buf.Write(out)
|
||||
|
||||
return buf.Bytes(), err
|
||||
return buf.Bytes(), errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitService(ctx context.Context, w io.Writer, r io.Reader, repoPath, serviceName string) error {
|
||||
git := &util.Git{GitDir: repoPath}
|
||||
return git.Pipe(ctx, w, r, serviceName, "--stateless-rpc", repoPath)
|
||||
return errors.WithStack(git.Pipe(ctx, w, r, serviceName, "--stateless-rpc", repoPath))
|
||||
}
|
||||
|
||||
func gitFetchFile(ctx context.Context, w io.Writer, r io.Reader, repoPath, ref, path string) error {
|
||||
git := &util.Git{GitDir: repoPath}
|
||||
return git.Pipe(ctx, w, r, "show", fmt.Sprintf("%s:%s", ref, path))
|
||||
return errors.WithStack(git.Pipe(ctx, w, r, "show", fmt.Sprintf("%s:%s", ref, path)))
|
||||
}
|
||||
|
||||
var ErrWrongRepoPath = errors.New("wrong repository path")
|
||||
|
|
|
@ -20,11 +20,11 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -35,24 +35,24 @@ const (
|
|||
func copyFile(src, dest string) error {
|
||||
srcf, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer srcf.Close()
|
||||
|
||||
destf, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer destf.Close()
|
||||
|
||||
_, err = io.Copy(destf, srcf)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func fileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return false, err
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
return !os.IsNotExist(err), nil
|
||||
}
|
||||
|
@ -62,24 +62,24 @@ func GitDir() (string, error) {
|
|||
git := &util.Git{}
|
||||
lines, err := git.OutputLines(context.Background(), nil, "rev-parse", "--git-dir")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
return "", errors.Errorf("received %d lines, expected one line", len(lines))
|
||||
}
|
||||
return lines[0], err
|
||||
return lines[0], errors.WithStack(err)
|
||||
}
|
||||
|
||||
func currentGitBranch() (string, error) {
|
||||
git := &util.Git{}
|
||||
lines, err := git.OutputLines(context.Background(), nil, "symbolic-ref", "--short", "HEAD")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
return "", errors.Errorf("received %d lines, expected one line", len(lines))
|
||||
}
|
||||
return lines[0], err
|
||||
return lines[0], errors.WithStack(err)
|
||||
}
|
||||
|
||||
// gitDir returns the git dir relative to the working dir
|
||||
|
@ -87,60 +87,60 @@ func gitWriteTree(indexPath string) (string, error) {
|
|||
git := &util.Git{Env: []string{"GIT_INDEX_FILE=" + indexPath}}
|
||||
lines, err := git.OutputLines(context.Background(), nil, "write-tree")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
return "", errors.Errorf("received %d lines, expected one line", len(lines))
|
||||
}
|
||||
return lines[0], err
|
||||
return lines[0], errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitCommitTree(message, treeSHA string) (string, error) {
|
||||
git := &util.Git{}
|
||||
lines, err := git.OutputLines(context.Background(), nil, "commit-tree", "-m", message, treeSHA)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
return "", errors.Errorf("received %d lines, expected one line", len(lines))
|
||||
}
|
||||
return lines[0], err
|
||||
return lines[0], errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitUpdateRef(message, ref, commitSHA string) error {
|
||||
git := &util.Git{}
|
||||
_, err := git.Output(context.Background(), nil, "update-ref", "-m", message, ref, commitSHA)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitUpdateFiles(indexPath string) error {
|
||||
git := &util.Git{Env: []string{"GIT_INDEX_FILE=" + indexPath}}
|
||||
_, err := git.Output(context.Background(), nil, "add", "-u")
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitAddUntrackedFiles(indexPath string) error {
|
||||
git := &util.Git{Env: []string{"GIT_INDEX_FILE=" + indexPath}}
|
||||
_, err := git.Output(context.Background(), nil, "add", ".")
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func gitAddIgnoredFiles(indexPath string) error {
|
||||
git := &util.Git{Env: []string{"GIT_INDEX_FILE=" + indexPath}}
|
||||
_, err := git.Output(context.Background(), nil, "add", "-f", "-A", ".")
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GitAddRemote(configPath, name, url string) error {
|
||||
git := &util.Git{}
|
||||
_, err := git.Output(context.Background(), nil, "remote", "add", name, url)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GitPush(configPath, remote, branch string) error {
|
||||
git := &util.Git{}
|
||||
_, err := git.Output(context.Background(), nil, "push", remote, branch, "-f")
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
type GitSaveConfig struct {
|
||||
|
@ -178,7 +178,7 @@ func (s *GitSave) RefsPrefix() string {
|
|||
func (s *GitSave) Save(message, branchName string) (string, error) {
|
||||
gitdir, err := GitDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
tmpIndexPath := filepath.Join(gitdir, "gitsave-index-"+uuid.Must(uuid.NewV4()).String())
|
||||
|
@ -188,25 +188,25 @@ func (s *GitSave) Save(message, branchName string) (string, error) {
|
|||
|
||||
curBranch, err := currentGitBranch()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
indexExists, err := fileExists(indexPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
if indexExists {
|
||||
// copy current git index to a temporary index
|
||||
if err := copyFile(indexPath, tmpIndexPath); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
s.log.Info().Msgf("created temporary index: %s", tmpIndexPath)
|
||||
// read the current branch tree information into the index
|
||||
git := &util.Git{Env: []string{"GIT_INDEX_FILE=" + tmpIndexPath}}
|
||||
_, err = git.Output(context.Background(), nil, "read-tree", curBranch)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
s.log.Info().Msgf("index %s does not exist", indexPath)
|
||||
|
@ -214,40 +214,40 @@ func (s *GitSave) Save(message, branchName string) (string, error) {
|
|||
|
||||
s.log.Info().Msgf("updating files already in the index")
|
||||
if err := gitUpdateFiles(tmpIndexPath); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
if s.conf.AddUntracked {
|
||||
s.log.Info().Msgf("adding untracked files")
|
||||
if err := gitAddUntrackedFiles(tmpIndexPath); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
if s.conf.AddIgnored {
|
||||
s.log.Info().Msgf("adding ignored files")
|
||||
if err := gitAddIgnoredFiles(tmpIndexPath); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
s.log.Info().Msgf("writing tree file")
|
||||
treeSHA, err := gitWriteTree(tmpIndexPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
s.log.Info().Msgf("tree: %s", treeSHA)
|
||||
|
||||
s.log.Info().Msgf("committing tree")
|
||||
commitSHA, err := gitCommitTree(message, treeSHA)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
s.log.Info().Msgf("commit: %s", commitSHA)
|
||||
|
||||
s.log.Info().Msgf("updating ref")
|
||||
if err = gitUpdateRef("git-save", filepath.Join(s.refsPrefix, branchName), commitSHA); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return commitSHA, nil
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsource "agola.io/agola/internal/gitsources"
|
||||
"agola.io/agola/internal/services/types"
|
||||
"agola.io/agola/internal/util"
|
||||
|
@ -75,29 +76,31 @@ func (c *Client) SetHTTPClient(client *http.Client) {
|
|||
func (c *Client) doRequest(method, path string, query url.Values, header http.Header, ibody io.Reader) (*http.Response, error) {
|
||||
u, err := url.Parse(c.url + "/" + path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
u.RawQuery = query.Encode()
|
||||
|
||||
req, err := http.NewRequest(method, u.String(), ibody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
for k, v := range header {
|
||||
req.Header[k] = v
|
||||
}
|
||||
|
||||
return c.client.Do(req)
|
||||
res, err := c.client.Do(req)
|
||||
|
||||
return res, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) getResponse(method, path string, query url.Values, header http.Header, ibody io.Reader) (*http.Response, error) {
|
||||
resp, err := c.doRequest(method, path, query, header, ibody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := util.ErrFromRemote(resp); err != nil {
|
||||
return resp, err
|
||||
return resp, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
|
@ -114,12 +117,12 @@ func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
|||
func (c *Client) GetFile(repopath, commit, file string) ([]byte, error) {
|
||||
resp, err := c.getResponse("GET", fmt.Sprintf("%s.git/raw/%s/%s", repopath, commit, file), nil, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
return data, err
|
||||
return data, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
|
@ -174,7 +177,7 @@ func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
|
||||
return -1, "", errors.Errorf("unsupported ref: %s", ref)
|
||||
}
|
||||
|
||||
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
|
||||
|
|
|
@ -28,11 +28,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsource "agola.io/agola/internal/gitsources"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"golang.org/x/oauth2"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -146,7 +146,7 @@ func (c *Client) RequestOauth2Token(callbackURL, code string) (*oauth2.Token, er
|
|||
var config = c.oauth2Config(callbackURL)
|
||||
token, err := config.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot get oauth2 token: %w", err)
|
||||
return nil, errors.Wrapf(err, "cannot get oauth2 token")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
@ -158,7 +158,9 @@ func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error)
|
|||
var config = c.oauth2Config("")
|
||||
token := &oauth2.Token{RefreshToken: refreshToken}
|
||||
ts := config.TokenSource(ctx, token)
|
||||
return ts.Token()
|
||||
ntoken, err := ts.Token()
|
||||
|
||||
return ntoken, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) LoginPassword(username, password, tokenName string) (string, error) {
|
||||
|
@ -172,16 +174,16 @@ func (c *Client) LoginPassword(username, password, tokenName string) (string, er
|
|||
tokens := make([]*gitea.AccessToken, 0, 10)
|
||||
req, err := http.NewRequest("GET", c.APIURL+"/api/v1"+fmt.Sprintf("/users/%s/tokens", username), nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password)))
|
||||
|
||||
resp, err := c.oauth2HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if resp.StatusCode == http.StatusUnauthorized {
|
||||
return "", gitsource.ErrUnauthorized
|
||||
return "", errors.WithStack(gitsource.ErrUnauthorized)
|
||||
}
|
||||
if resp.StatusCode/100 != 2 {
|
||||
return "", errors.Errorf("gitea api status code %d", resp.StatusCode)
|
||||
|
@ -190,7 +192,7 @@ func (c *Client) LoginPassword(username, password, tokenName string) (string, er
|
|||
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
if err := dec.Decode(&tokens); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
for _, token := range tokens {
|
||||
if token.Name == tokenName {
|
||||
|
@ -206,7 +208,7 @@ func (c *Client) LoginPassword(username, password, tokenName string) (string, er
|
|||
gitea.CreateAccessTokenOption{Name: tokenName},
|
||||
)
|
||||
if terr != nil {
|
||||
return "", terr
|
||||
return "", errors.WithStack(terr)
|
||||
}
|
||||
accessToken = token.Token
|
||||
}
|
||||
|
@ -217,7 +219,7 @@ func (c *Client) LoginPassword(username, password, tokenName string) (string, er
|
|||
func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
||||
user, err := c.client.GetMyUserInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return &gitsource.UserInfo{
|
||||
ID: strconv.FormatInt(user.ID, 10),
|
||||
|
@ -229,11 +231,11 @@ func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
|||
func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
rr, err := c.client.GetRepo(owner, reponame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return fromGiteaRepo(rr), nil
|
||||
}
|
||||
|
@ -241,23 +243,23 @@ func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
|||
func (c *Client) GetFile(repopath, commit, file string) ([]byte, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
data, err := c.client.GetFile(owner, reponame, commit, file)
|
||||
return data, err
|
||||
return data, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, err = c.client.CreateDeployKey(owner, reponame, gitea.CreateKeyOption{
|
||||
Title: title,
|
||||
Key: pubKey,
|
||||
ReadOnly: readonly,
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -266,7 +268,7 @@ func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// NOTE(sgotti) gitea has a bug where if we delete and remove the same key with
|
||||
// the same value it is correctly readded and the admin must force a
|
||||
|
@ -274,7 +276,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
// when the public key value has changed
|
||||
keys, err := c.client.ListDeployKeys(owner, reponame, gitea.ListDeployKeysOptions{})
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
|
@ -283,7 +285,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
return nil
|
||||
}
|
||||
if err := c.client.DeleteDeployKey(owner, reponame, key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +295,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
Key: pubKey,
|
||||
ReadOnly: readonly,
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -302,17 +304,17 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) DeleteDeployKey(repopath, title string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
keys, err := c.client.ListDeployKeys(owner, reponame, gitea.ListDeployKeysOptions{})
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if key.Title == title {
|
||||
if err := c.client.DeleteDeployKey(owner, reponame, key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +325,7 @@ func (c *Client) DeleteDeployKey(repopath, title string) error {
|
|||
func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
opts := gitea.CreateHookOption{
|
||||
|
@ -338,7 +340,7 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
}
|
||||
|
||||
if _, err = c.client.CreateRepoHook(owner, reponame, opts); err != nil {
|
||||
return errors.Errorf("error creating repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error creating repository webhook")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -347,11 +349,11 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
hooks, err := c.client.ListRepoHooks(owner, reponame, gitea.ListHooksOptions{})
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving repository webhooks: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving repository webhooks")
|
||||
}
|
||||
|
||||
// match the full url so we can have multiple webhooks for different agola
|
||||
|
@ -359,7 +361,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
for _, hook := range hooks {
|
||||
if hook.Config["url"] == u {
|
||||
if err := c.client.DeleteRepoHook(owner, reponame, hook.ID); err != nil {
|
||||
return errors.Errorf("error deleting existing repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error deleting existing repository webhook")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +372,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource.CommitStatus, targetURL, description, context string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
_, err = c.client.CreateStatus(owner, reponame, commitSHA, gitea.CreateStatusOption{
|
||||
State: fromCommitStatus(status),
|
||||
|
@ -378,7 +380,7 @@ func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource
|
|||
Description: description,
|
||||
Context: context,
|
||||
})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
||||
|
@ -396,7 +398,7 @@ func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
|||
)
|
||||
|
||||
if err != nil {
|
||||
return []*gitsource.RepoInfo{}, err
|
||||
return []*gitsource.RepoInfo{}, errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, repo := range remoteRepos {
|
||||
|
@ -429,12 +431,12 @@ func fromGiteaRepo(rr *gitea.Repository) *gitsource.RepoInfo {
|
|||
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
remoteRefs, err := c.client.GetRepoRefs(owner, reponame, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
if len(remoteRefs) == 0 {
|
||||
return nil, errors.Errorf("no ref %q for repository %q", ref, repopath)
|
||||
|
@ -480,12 +482,12 @@ func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
|
|||
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
commit, err := c.client.GetSingleCommit(owner, reponame, commitSHA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &gitsource.Commit{
|
||||
|
|
|
@ -27,9 +27,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/types"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -48,7 +47,7 @@ const (
|
|||
func (c *Client) ParseWebhook(r *http.Request, secret string) (*types.WebhookData, error) {
|
||||
data, err := ioutil.ReadAll(io.LimitReader(r.Body, 10*1024*1024))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// verify signature
|
||||
|
@ -83,7 +82,7 @@ func parsePushHook(data []byte) (*types.WebhookData, error) {
|
|||
push := new(pushHook)
|
||||
err := json.Unmarshal(data, push)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return webhookDataFromPush(push)
|
||||
|
@ -93,7 +92,7 @@ func parsePullRequestHook(data []byte) (*types.WebhookData, error) {
|
|||
prhook := new(pullRequestHook)
|
||||
err := json.Unmarshal(data, prhook)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// skip non open pull requests
|
||||
|
@ -144,7 +143,7 @@ func webhookDataFromPush(hook *pushHook) (*types.WebhookData, error) {
|
|||
whd.Message = fmt.Sprintf("Tag %s", whd.Tag)
|
||||
default:
|
||||
// ignore received webhook since it doesn't have a ref we're interested in
|
||||
return nil, fmt.Errorf("unsupported webhook ref %q", hook.Ref)
|
||||
return nil, errors.Errorf("unsupported webhook ref %q", hook.Ref)
|
||||
}
|
||||
|
||||
return whd, nil
|
||||
|
|
|
@ -28,11 +28,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsource "agola.io/agola/internal/gitsources"
|
||||
|
||||
"github.com/google/go-github/v29/github"
|
||||
"golang.org/x/oauth2"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -81,7 +81,7 @@ func fromCommitStatus(status gitsource.CommitStatus) string {
|
|||
case gitsource.CommitStatusFailed:
|
||||
return "failure"
|
||||
default:
|
||||
panic(fmt.Errorf("unknown commit status %q", status))
|
||||
panic(errors.Errorf("unknown commit status %q", status))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,8 @@ func (t *TokenTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
|||
if t.token != "" {
|
||||
r.Header.Set("Authorization", "Bearer "+t.token)
|
||||
}
|
||||
|
||||
//nolint:wrapcheck
|
||||
return t.rt.RoundTrip(r)
|
||||
}
|
||||
|
||||
|
@ -184,7 +186,7 @@ func (c *Client) RequestOauth2Token(callbackURL, code string) (*oauth2.Token, er
|
|||
var config = c.oauth2Config(callbackURL)
|
||||
token, err := config.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot get oauth2 token: %w", err)
|
||||
return nil, errors.Wrapf(err, "cannot get oauth2 token")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
@ -196,13 +198,15 @@ func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error)
|
|||
var config = c.oauth2Config("")
|
||||
token := &oauth2.Token{RefreshToken: refreshToken}
|
||||
ts := config.TokenSource(ctx, token)
|
||||
return ts.Token()
|
||||
ntoken, err := ts.Token()
|
||||
|
||||
return ntoken, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
||||
user, _, err := c.client.Users.Get(context.TODO(), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
userInfo := &gitsource.UserInfo{
|
||||
|
@ -219,11 +223,11 @@ func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
|||
func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
rr, _, err := c.client.Repositories.Get(context.TODO(), owner, reponame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return fromGithubRepo(rr), nil
|
||||
}
|
||||
|
@ -231,28 +235,29 @@ func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
|||
func (c *Client) GetFile(repopath, commit, file string) ([]byte, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
r, err := c.client.Repositories.DownloadContents(context.TODO(), owner, reponame, file, &github.RepositoryContentGetOptions{Ref: commit})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
return ioutil.ReadAll(r)
|
||||
d, err := ioutil.ReadAll(r)
|
||||
return d, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, _, err = c.client.Repositories.CreateKey(context.TODO(), owner, reponame, &github.Key{
|
||||
Title: github.String(title),
|
||||
Key: github.String(pubKey),
|
||||
ReadOnly: github.Bool(readonly),
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -260,7 +265,7 @@ func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// NOTE(sgotti) gitea has a bug where if we delete and remove the same key with
|
||||
// the same value it is correctly readded and the admin must force a
|
||||
|
@ -268,7 +273,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
// when the public key value has changed
|
||||
keys, _, err := c.client.Repositories.ListKeys(context.TODO(), owner, reponame, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
|
@ -277,7 +282,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
return nil
|
||||
}
|
||||
if _, err := c.client.Repositories.DeleteKey(context.TODO(), owner, reponame, *key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,7 +292,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
Key: github.String(pubKey),
|
||||
ReadOnly: github.Bool(readonly),
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -296,17 +301,17 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) DeleteDeployKey(repopath, title string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
keys, _, err := c.client.Repositories.ListKeys(context.TODO(), owner, reponame, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if *key.Title == title {
|
||||
if _, err := c.client.Repositories.DeleteKey(context.TODO(), owner, reponame, *key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +322,7 @@ func (c *Client) DeleteDeployKey(repopath, title string) error {
|
|||
func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
hook := &github.Hook{
|
||||
|
@ -331,7 +336,7 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
}
|
||||
|
||||
if _, _, err = c.client.Repositories.CreateHook(context.TODO(), owner, reponame, hook); err != nil {
|
||||
return errors.Errorf("error creating repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error creating repository webhook")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -340,7 +345,7 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
hooks := []*github.Hook{}
|
||||
|
@ -349,7 +354,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
for {
|
||||
pHooks, resp, err := c.client.Repositories.ListHooks(context.TODO(), owner, reponame, opt)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving repository webhooks: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving repository webhooks")
|
||||
}
|
||||
hooks = append(hooks, pHooks...)
|
||||
if resp.NextPage == 0 {
|
||||
|
@ -363,7 +368,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
for _, hook := range hooks {
|
||||
if hook.Config["url"] == u {
|
||||
if _, err := c.client.Repositories.DeleteHook(context.TODO(), owner, reponame, *hook.ID); err != nil {
|
||||
return errors.Errorf("error deleting existing repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error deleting existing repository webhook")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,7 +379,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource.CommitStatus, targetURL, description, statusContext string) error {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
_, _, err = c.client.Repositories.CreateStatus(context.TODO(), owner, reponame, commitSHA, &github.RepoStatus{
|
||||
State: github.String(fromCommitStatus(status)),
|
||||
|
@ -382,7 +387,7 @@ func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource
|
|||
Description: github.String(description),
|
||||
Context: github.String(statusContext),
|
||||
})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
||||
|
@ -392,7 +397,7 @@ func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
|||
for {
|
||||
pRemoteRepos, resp, err := c.client.Repositories.List(context.TODO(), "", opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
remoteRepos = append(remoteRepos, pRemoteRepos...)
|
||||
if resp.NextPage == 0 {
|
||||
|
@ -429,12 +434,12 @@ func fromGithubRepo(rr *github.Repository) *gitsource.RepoInfo {
|
|||
func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
remoteRef, _, err := c.client.Git.GetRef(context.TODO(), owner, reponame, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return fromGithubRef(remoteRef)
|
||||
|
@ -445,7 +450,7 @@ func fromGithubRef(remoteRef *github.Reference) (*gitsource.Ref, error) {
|
|||
switch t {
|
||||
case "commit":
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported object type: %s", t)
|
||||
return nil, errors.Errorf("unsupported object type: %s", t)
|
||||
}
|
||||
|
||||
return &gitsource.Ref{
|
||||
|
@ -467,19 +472,19 @@ func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
|
|||
return gitsource.RefTypePullRequest, m[1], nil
|
||||
|
||||
default:
|
||||
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
|
||||
return -1, "", errors.Errorf("unsupported ref: %s", ref)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
|
||||
owner, reponame, err := parseRepoPath(repopath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
commit, _, err := c.client.Git.GetCommit(context.TODO(), owner, reponame, commitSHA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &gitsource.Commit{
|
||||
|
|
|
@ -21,10 +21,10 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/types"
|
||||
|
||||
"github.com/google/go-github/v29/github"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -37,12 +37,12 @@ const (
|
|||
func (c *Client) ParseWebhook(r *http.Request, secret string) (*types.WebhookData, error) {
|
||||
payload, err := github.ValidatePayload(r, []byte(secret))
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("wrong webhook signature: %w", err)
|
||||
return nil, errors.Wrapf(err, "wrong webhook signature")
|
||||
}
|
||||
webHookType := github.WebHookType(r)
|
||||
event, err := github.ParseWebHook(webHookType, payload)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to parse webhook: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to parse webhook")
|
||||
}
|
||||
switch event := event.(type) {
|
||||
case *github.PushEvent:
|
||||
|
@ -96,7 +96,7 @@ func webhookDataFromPush(hook *github.PushEvent) (*types.WebhookData, error) {
|
|||
|
||||
default:
|
||||
// ignore received webhook since it doesn't have a ref we're interested in
|
||||
return nil, fmt.Errorf("unsupported webhook ref %q", *hook.Ref)
|
||||
return nil, errors.Errorf("unsupported webhook ref %q", *hook.Ref)
|
||||
}
|
||||
|
||||
return whd, nil
|
||||
|
|
|
@ -26,11 +26,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsource "agola.io/agola/internal/gitsources"
|
||||
|
||||
gitlab "github.com/xanzy/go-gitlab"
|
||||
"golang.org/x/oauth2"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -70,7 +70,7 @@ func fromCommitStatus(status gitsource.CommitStatus) gitlab.BuildStateValue {
|
|||
case gitsource.CommitStatusFailed:
|
||||
return gitlab.Failed
|
||||
default:
|
||||
panic(fmt.Errorf("unknown commit status %q", status))
|
||||
panic(errors.Errorf("unknown commit status %q", status))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ func New(opts Opts) (*Client, error) {
|
|||
|
||||
client := gitlab.NewOAuthClient(httpClient, opts.Token)
|
||||
if err := client.SetBaseURL(opts.APIURL); err != nil {
|
||||
return nil, errors.Errorf("failed to set gitlab client base url: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to set gitlab client base url")
|
||||
}
|
||||
|
||||
return &Client{
|
||||
|
@ -130,7 +130,7 @@ func (c *Client) RequestOauth2Token(callbackURL, code string) (*oauth2.Token, er
|
|||
var config = c.oauth2Config(callbackURL)
|
||||
token, err := config.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot get oauth2 token: %w", err)
|
||||
return nil, errors.Wrapf(err, "cannot get oauth2 token")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
@ -142,13 +142,15 @@ func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error)
|
|||
var config = c.oauth2Config("")
|
||||
token := &oauth2.Token{RefreshToken: refreshToken}
|
||||
ts := config.TokenSource(ctx, token)
|
||||
return ts.Token()
|
||||
ntoken, err := ts.Token()
|
||||
|
||||
return ntoken, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
||||
rr, _, err := c.client.Projects.GetProject(repopath, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return fromGitlabRepo(rr), nil
|
||||
}
|
||||
|
@ -156,7 +158,7 @@ func (c *Client) GetRepoInfo(repopath string) (*gitsource.RepoInfo, error) {
|
|||
func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
||||
user, _, err := c.client.Users.CurrentUser()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return &gitsource.UserInfo{
|
||||
ID: strconv.Itoa(user.ID),
|
||||
|
@ -168,13 +170,13 @@ func (c *Client) GetUserInfo() (*gitsource.UserInfo, error) {
|
|||
func (c *Client) GetFile(repopath, commit, file string) ([]byte, error) {
|
||||
f, _, err := c.client.RepositoryFiles.GetFile(repopath, file, &gitlab.GetFileOptions{Ref: gitlab.String(commit)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
data, err := base64.StdEncoding.DecodeString(f.Content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return data, err
|
||||
return data, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
|
@ -182,7 +184,7 @@ func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
Title: gitlab.String(title),
|
||||
Key: gitlab.String(pubKey),
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -191,7 +193,7 @@ func (c *Client) CreateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool) error {
|
||||
keys, _, err := c.client.DeployKeys.ListProjectDeployKeys(repopath, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
|
@ -200,7 +202,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
return nil
|
||||
}
|
||||
if _, err := c.client.DeployKeys.DeleteDeployKey(repopath, key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +211,7 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
Title: &title,
|
||||
Key: &pubKey,
|
||||
}); err != nil {
|
||||
return errors.Errorf("error creating deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error creating deploy key")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -218,13 +220,13 @@ func (c *Client) UpdateDeployKey(repopath, title, pubKey string, readonly bool)
|
|||
func (c *Client) DeleteDeployKey(repopath, title string) error {
|
||||
keys, _, err := c.client.DeployKeys.ListProjectDeployKeys(repopath, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving existing deploy keys: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving existing deploy keys")
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if key.Title == title {
|
||||
if _, err := c.client.DeployKeys.DeleteDeployKey(repopath, key.ID); err != nil {
|
||||
return errors.Errorf("error removing existing deploy key: %w", err)
|
||||
return errors.Wrapf(err, "error removing existing deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +243,7 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
Token: gitlab.String(secret),
|
||||
}
|
||||
if _, _, err := c.client.Projects.AddProjectHook(repopath, opts); err != nil {
|
||||
return errors.Errorf("error creating repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error creating repository webhook")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -250,7 +252,7 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error {
|
|||
func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
||||
hooks, _, err := c.client.Projects.ListProjectHooks(repopath, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("error retrieving repository webhooks: %w", err)
|
||||
return errors.Wrapf(err, "error retrieving repository webhooks")
|
||||
}
|
||||
|
||||
// match the full url so we can have multiple webhooks for different agola
|
||||
|
@ -258,7 +260,7 @@ func (c *Client) DeleteRepoWebhook(repopath, u string) error {
|
|||
for _, hook := range hooks {
|
||||
if hook.URL == u {
|
||||
if _, err := c.client.Projects.DeleteProjectHook(repopath, hook.ID); err != nil {
|
||||
return errors.Errorf("error deleting existing repository webhook: %w", err)
|
||||
return errors.Wrapf(err, "error deleting existing repository webhook")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +275,7 @@ func (c *Client) CreateCommitStatus(repopath, commitSHA string, status gitsource
|
|||
Description: gitlab.String(description),
|
||||
Context: gitlab.String(context),
|
||||
})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
||||
|
@ -281,7 +283,7 @@ func (c *Client) ListUserRepos() ([]*gitsource.RepoInfo, error) {
|
|||
opts := &gitlab.ListProjectsOptions{MinAccessLevel: gitlab.AccessLevel(gitlab.MaintainerPermissions)}
|
||||
remoteRepos, _, err := c.client.Projects.ListProjects(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
repos := []*gitsource.RepoInfo{}
|
||||
|
@ -311,7 +313,7 @@ func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
|
|||
branch := strings.TrimPrefix(ref, "refs/heads/")
|
||||
remoteBranch, _, err := c.client.Branches.GetBranch(repopath, branch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &gitsource.Ref{
|
||||
|
@ -323,7 +325,7 @@ func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
|
|||
tag := strings.TrimPrefix(ref, "refs/heads/")
|
||||
remoteTag, _, err := c.client.Tags.GetTag(repopath, tag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &gitsource.Ref{
|
||||
|
@ -331,7 +333,7 @@ func (c *Client) GetRef(repopath, ref string) (*gitsource.Ref, error) {
|
|||
CommitSHA: remoteTag.Commit.ID,
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported ref: %s", ref)
|
||||
return nil, errors.Errorf("unsupported ref: %s", ref)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,14 +350,14 @@ func (c *Client) RefType(ref string) (gitsource.RefType, string, error) {
|
|||
return gitsource.RefTypePullRequest, m[1], nil
|
||||
|
||||
default:
|
||||
return -1, "", fmt.Errorf("unsupported ref: %s", ref)
|
||||
return -1, "", errors.Errorf("unsupported ref: %s", ref)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetCommit(repopath, commitSHA string) (*gitsource.Commit, error) {
|
||||
commit, _, err := c.client.Commits.GetCommit(repopath, commitSHA, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &gitsource.Commit{
|
||||
|
|
|
@ -23,9 +23,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/types"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -40,7 +39,7 @@ const (
|
|||
func (c *Client) ParseWebhook(r *http.Request, secret string) (*types.WebhookData, error) {
|
||||
data, err := ioutil.ReadAll(io.LimitReader(r.Body, 10*1024*1024))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// verify token (gitlab doesn't sign the payload but just returns the provided
|
||||
|
@ -68,7 +67,7 @@ func parsePushHook(data []byte) (*types.WebhookData, error) {
|
|||
push := new(pushHook)
|
||||
err := json.Unmarshal(data, push)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// skip push events with 0 commits. i.e. a tag deletion.
|
||||
|
@ -83,7 +82,7 @@ func parsePullRequestHook(data []byte) (*types.WebhookData, error) {
|
|||
prhook := new(pullRequestHook)
|
||||
err := json.Unmarshal(data, prhook)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// TODO(sgotti) skip non open pull requests
|
||||
|
@ -127,7 +126,7 @@ func webhookDataFromPush(hook *pushHook) (*types.WebhookData, error) {
|
|||
whd.Message = fmt.Sprintf("Tag %s", whd.Tag)
|
||||
default:
|
||||
// ignore received webhook since it doesn't have a ref we're interested in
|
||||
return nil, fmt.Errorf("unsupported webhook ref %q", hook.Ref)
|
||||
return nil, errors.Errorf("unsupported webhook ref %q", hook.Ref)
|
||||
}
|
||||
|
||||
return whd, nil
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
package gitsource
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/types"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
// writeFileAtomicFunc atomically writes a file, it achieves this by creating a
|
||||
|
@ -30,7 +32,7 @@ import (
|
|||
func writeFileAtomicFunc(p, baseDir, tmpDir string, perm os.FileMode, persist bool, writeFunc func(f io.Writer) error) error {
|
||||
f, err := ioutil.TempFile(tmpDir, "tmpfile")
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
err = writeFunc(f)
|
||||
if persist && err == nil {
|
||||
|
@ -47,7 +49,7 @@ func writeFileAtomicFunc(p, baseDir, tmpDir string, perm os.FileMode, persist bo
|
|||
}
|
||||
if err != nil {
|
||||
os.Remove(f.Name())
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if !persist {
|
||||
|
@ -80,7 +82,7 @@ func writeFileAtomic(filename, baseDir, tmpDir string, perm os.FileMode, persist
|
|||
return writeFileAtomicFunc(filename, baseDir, tmpDir, perm, persist,
|
||||
func(f io.Writer) error {
|
||||
_, err := f.Write(data)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"io"
|
||||
"time"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
|
@ -36,10 +36,12 @@ type Storage interface {
|
|||
|
||||
type ErrNotExist struct {
|
||||
err error
|
||||
|
||||
*errors.Stack
|
||||
}
|
||||
|
||||
func NewErrNotExist(err error) error {
|
||||
return &ErrNotExist{err: err}
|
||||
return &ErrNotExist{err: err, Stack: errors.Callers(0)}
|
||||
}
|
||||
|
||||
func (e *ErrNotExist) Error() string {
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -36,15 +36,15 @@ type PosixStorage struct {
|
|||
|
||||
func NewPosix(baseDir string) (*PosixStorage, error) {
|
||||
if err := os.MkdirAll(baseDir, 0770); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
dataDir := filepath.Join(baseDir, dataDirName)
|
||||
tmpDir := filepath.Join(baseDir, tmpDirName)
|
||||
if err := os.MkdirAll(dataDir, 0770); err != nil {
|
||||
return nil, errors.Errorf("failed to create data dir: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create data dir")
|
||||
}
|
||||
if err := os.MkdirAll(tmpDir, 0770); err != nil {
|
||||
return nil, errors.Errorf("failed to create tmp dir: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create tmp dir")
|
||||
}
|
||||
return &PosixStorage{
|
||||
dataDir: dataDir,
|
||||
|
@ -59,7 +59,7 @@ func (s *PosixStorage) fsPath(p string) (string, error) {
|
|||
func (s *PosixStorage) Stat(p string) (*ObjectInfo, error) {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(fspath)
|
||||
|
@ -67,7 +67,7 @@ func (s *PosixStorage) Stat(p string) (*ObjectInfo, error) {
|
|||
if os.IsNotExist(err) {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &ObjectInfo{Path: p, LastModified: fi.ModTime(), Size: fi.Size()}, nil
|
||||
|
@ -76,24 +76,24 @@ func (s *PosixStorage) Stat(p string) (*ObjectInfo, error) {
|
|||
func (s *PosixStorage) ReadObject(p string) (ReadSeekCloser, error) {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
f, err := os.Open(fspath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return f, err
|
||||
return f, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *PosixStorage) WriteObject(p string, data io.Reader, size int64, persist bool) error {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(path.Dir(fspath), 0770); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
r := data
|
||||
|
@ -102,21 +102,21 @@ func (s *PosixStorage) WriteObject(p string, data io.Reader, size int64, persist
|
|||
}
|
||||
return writeFileAtomicFunc(fspath, s.dataDir, s.tmpDir, 0660, persist, func(f io.Writer) error {
|
||||
_, err := io.Copy(f, r)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *PosixStorage) DeleteObject(p string) error {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := os.Remove(fspath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// try to remove parent empty dirs
|
||||
|
@ -179,7 +179,7 @@ func (s *PosixStorage) List(prefix, startWith, delimiter string, doneCh <-chan s
|
|||
defer close(objectCh)
|
||||
err := filepath.Walk(root, func(ep string, info os.FileInfo, err error) error {
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
|
@ -191,7 +191,7 @@ func (s *PosixStorage) List(prefix, startWith, delimiter string, doneCh <-chan s
|
|||
|
||||
p, err = filepath.Rel(s.dataDir, p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if !recursive && len(p) > len(prefix) {
|
||||
rel := strings.TrimPrefix(p, prefix)
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -207,15 +207,15 @@ type PosixFlatStorage struct {
|
|||
|
||||
func NewPosixFlat(baseDir string) (*PosixFlatStorage, error) {
|
||||
if err := os.MkdirAll(baseDir, 0770); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
dataDir := filepath.Join(baseDir, dataDirName)
|
||||
tmpDir := filepath.Join(baseDir, tmpDirName)
|
||||
if err := os.MkdirAll(dataDir, 0770); err != nil {
|
||||
return nil, errors.Errorf("failed to create data dir: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create data dir")
|
||||
}
|
||||
if err := os.MkdirAll(tmpDir, 0770); err != nil {
|
||||
return nil, errors.Errorf("failed to create tmp dir: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to create tmp dir")
|
||||
}
|
||||
return &PosixFlatStorage{
|
||||
dataDir: dataDir,
|
||||
|
@ -233,7 +233,7 @@ func (s *PosixFlatStorage) fsPath(p string) (string, error) {
|
|||
func (s *PosixFlatStorage) Stat(p string) (*ObjectInfo, error) {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(fspath)
|
||||
|
@ -241,7 +241,7 @@ func (s *PosixFlatStorage) Stat(p string) (*ObjectInfo, error) {
|
|||
if os.IsNotExist(err) {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &ObjectInfo{Path: p, LastModified: fi.ModTime(), Size: fi.Size()}, nil
|
||||
|
@ -250,24 +250,24 @@ func (s *PosixFlatStorage) Stat(p string) (*ObjectInfo, error) {
|
|||
func (s *PosixFlatStorage) ReadObject(p string) (ReadSeekCloser, error) {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
f, err := os.Open(fspath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return f, err
|
||||
return f, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *PosixFlatStorage) WriteObject(p string, data io.Reader, size int64, persist bool) error {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(path.Dir(fspath), 0770); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
r := data
|
||||
|
@ -276,21 +276,21 @@ func (s *PosixFlatStorage) WriteObject(p string, data io.Reader, size int64, per
|
|||
}
|
||||
return writeFileAtomicFunc(fspath, s.dataDir, s.tmpDir, 0660, persist, func(f io.Writer) error {
|
||||
_, err := io.Copy(f, r)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *PosixFlatStorage) DeleteObject(p string) error {
|
||||
fspath, err := s.fsPath(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err := os.Remove(fspath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// try to remove parent empty dirs
|
||||
|
@ -354,7 +354,7 @@ func (s *PosixFlatStorage) List(prefix, startWith, delimiter string, doneCh <-ch
|
|||
defer close(objectCh)
|
||||
err := filepath.Walk(root, func(ep string, info os.FileInfo, err error) error {
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
|
@ -366,11 +366,11 @@ func (s *PosixFlatStorage) List(prefix, startWith, delimiter string, doneCh <-ch
|
|||
|
||||
p, err = filepath.Rel(s.dataDir, p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
p, _, err = unescape(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if !recursive && len(p) > len(prefix) {
|
||||
rel := strings.TrimPrefix(p, prefix)
|
||||
|
@ -390,7 +390,7 @@ func (s *PosixFlatStorage) List(prefix, startWith, delimiter string, doneCh <-ch
|
|||
hasFile := true
|
||||
_, err = os.Stat(ep + ".f")
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
hasFile = false
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
func TestEscapeUnescape(t *testing.T) {
|
||||
|
|
|
@ -21,8 +21,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
minio "github.com/minio/minio-go/v6"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type S3Storage struct {
|
||||
|
@ -35,21 +35,21 @@ type S3Storage struct {
|
|||
func NewS3(bucket, location, endpoint, accessKeyID, secretAccessKey string, secure bool) (*S3Storage, error) {
|
||||
minioClient, err := minio.New(endpoint, accessKeyID, secretAccessKey, secure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
minioCore, err := minio.NewCore(endpoint, accessKeyID, secretAccessKey, secure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
exists, err := minioClient.BucketExists(bucket)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot check if bucket %q in location %q exits: %w", bucket, location, err)
|
||||
return nil, errors.Wrapf(err, "cannot check if bucket %q in location %q exits", bucket, location)
|
||||
}
|
||||
if !exists {
|
||||
if err := minioClient.MakeBucket(bucket, location); err != nil {
|
||||
return nil, errors.Errorf("cannot create bucket %q in location %q: %w", bucket, location, err)
|
||||
return nil, errors.Wrapf(err, "cannot create bucket %q in location %q", bucket, location)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ func (s *S3Storage) Stat(p string) (*ObjectInfo, error) {
|
|||
if merr.StatusCode == http.StatusNotFound {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", p))
|
||||
}
|
||||
return nil, merr
|
||||
return nil, errors.WithStack(merr)
|
||||
}
|
||||
|
||||
return &ObjectInfo{Path: p, LastModified: oi.LastModified, Size: oi.Size}, nil
|
||||
|
@ -79,9 +79,12 @@ func (s *S3Storage) ReadObject(filepath string) (ReadSeekCloser, error) {
|
|||
if merr.StatusCode == http.StatusNotFound {
|
||||
return nil, NewErrNotExist(errors.Errorf("object %q doesn't exist", filepath))
|
||||
}
|
||||
return nil, merr
|
||||
return nil, errors.WithStack(merr)
|
||||
}
|
||||
return s.minioClient.GetObject(s.bucket, filepath, minio.GetObjectOptions{})
|
||||
|
||||
o, err := s.minioClient.GetObject(s.bucket, filepath, minio.GetObjectOptions{})
|
||||
|
||||
return o, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *S3Storage) WriteObject(filepath string, data io.Reader, size int64, persist bool) error {
|
||||
|
@ -92,30 +95,30 @@ func (s *S3Storage) WriteObject(filepath string, data io.Reader, size int64, per
|
|||
if size >= 0 {
|
||||
lr := io.LimitReader(data, size)
|
||||
_, err := s.minioClient.PutObject(s.bucket, filepath, lr, size, minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// hack to know the real file size or minio will do this in memory with big memory usage since s3 doesn't support real streaming of unknown sizes
|
||||
// TODO(sgotti) wait for minio client to expose an api to provide the max object size so we can remove this
|
||||
tmpfile, err := ioutil.TempFile(os.TempDir(), "s3")
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
defer tmpfile.Close()
|
||||
defer os.Remove(tmpfile.Name())
|
||||
size, err = io.Copy(tmpfile, data)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, err := tmpfile.Seek(0, 0); err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
_, err = s.minioClient.PutObject(s.bucket, filepath, tmpfile, size, minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (s *S3Storage) DeleteObject(filepath string) error {
|
||||
return s.minioClient.RemoveObject(s.bucket, filepath)
|
||||
return errors.WithStack(s.minioClient.RemoveObject(s.bucket, filepath))
|
||||
}
|
||||
|
||||
func (s *S3Storage) List(prefix, startWith, delimiter string, doneCh <-chan struct{}) <-chan ObjectInfo {
|
||||
|
|
|
@ -19,12 +19,11 @@ import (
|
|||
"strings"
|
||||
|
||||
"agola.io/agola/internal/config"
|
||||
"agola.io/agola/internal/errors"
|
||||
itypes "agola.io/agola/internal/services/types"
|
||||
"agola.io/agola/internal/util"
|
||||
rstypes "agola.io/agola/services/runservice/types"
|
||||
"agola.io/agola/services/types"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -192,7 +191,7 @@ fi
|
|||
return rws
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unknown config step type: %s", util.Dump(cs)))
|
||||
panic(errors.Errorf("unknown config step type: %s", util.Dump(cs)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,7 +460,7 @@ func genValue(val config.Value, variables map[string]string) string {
|
|||
case config.ValueTypeFromVariable:
|
||||
return variables[val.Value]
|
||||
default:
|
||||
panic(fmt.Errorf("wrong value type: %q", val.Value))
|
||||
panic(errors.Errorf("wrong value type: %q", val.Value))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ import (
|
|||
"testing"
|
||||
|
||||
"agola.io/agola/internal/config"
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
rstypes "agola.io/agola/services/runservice/types"
|
||||
"agola.io/agola/services/types"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var uuid = &util.TestUUIDGenerator{}
|
||||
|
@ -128,7 +128,7 @@ func TestGenTasksLevels(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("circular dependency detected"),
|
||||
err: errors.Errorf("circular dependency detected"),
|
||||
},
|
||||
{
|
||||
name: "Test circular dependency between 3 tasks: a -> b -> c -> a",
|
||||
|
@ -155,7 +155,7 @@ func TestGenTasksLevels(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("circular dependency detected"),
|
||||
err: errors.Errorf("circular dependency detected"),
|
||||
},
|
||||
{
|
||||
name: "Test circular dependency between 3 tasks: a -> b -> c -> b",
|
||||
|
@ -182,7 +182,7 @@ func TestGenTasksLevels(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("circular dependency detected"),
|
||||
err: errors.Errorf("circular dependency detected"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -23,8 +23,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type Sequence struct {
|
||||
|
@ -55,11 +55,11 @@ func Parse(s string) (*Sequence, error) {
|
|||
}
|
||||
epoch, err := strconv.ParseUint(parts[0], 32, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot parse sequence epoch %q: %w", epoch, err)
|
||||
return nil, errors.Wrapf(err, "cannot parse sequence epoch %q", epoch)
|
||||
}
|
||||
c, err := strconv.ParseUint(parts[1], 32, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("cannot parse sequence count %q: %w", c, err)
|
||||
return nil, errors.Wrapf(err, "cannot parse sequence count %q", c)
|
||||
}
|
||||
return &Sequence{
|
||||
Epoch: epoch,
|
||||
|
@ -74,7 +74,7 @@ func (s *Sequence) EqualEpoch(s2 *Sequence) bool {
|
|||
func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, bool, error) {
|
||||
resp, err := e.Get(ctx, key, 0)
|
||||
if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return nil, false, err
|
||||
return nil, false, errors.WithStack(err)
|
||||
}
|
||||
if errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return nil, false, nil
|
||||
|
@ -84,7 +84,7 @@ func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, boo
|
|||
if !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
kv := resp.Kvs[0]
|
||||
if err := json.Unmarshal(kv.Value, &seq); err != nil {
|
||||
return nil, false, err
|
||||
return nil, false, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
return seq, true, nil
|
||||
|
@ -93,7 +93,7 @@ func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, boo
|
|||
func IncSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, error) {
|
||||
resp, err := e.Get(ctx, key, 0)
|
||||
if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var revision int64
|
||||
|
@ -101,7 +101,7 @@ func IncSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, err
|
|||
if !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
kv := resp.Kvs[0]
|
||||
if err := json.Unmarshal(kv.Value, &seq); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
revision = kv.ModRevision
|
||||
}
|
||||
|
@ -120,12 +120,12 @@ func IncSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, err
|
|||
|
||||
seqj, err := json.Marshal(seq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
_, err = e.AtomicPut(ctx, key, seqj, revision, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return seq, nil
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
package sequence
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
|
|
|
@ -15,43 +15,48 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"agola.io/agola/internal/errors"
|
||||
gitsource "agola.io/agola/internal/gitsources"
|
||||
"agola.io/agola/internal/gitsources/gitea"
|
||||
"agola.io/agola/internal/gitsources/github"
|
||||
"agola.io/agola/internal/gitsources/gitlab"
|
||||
cstypes "agola.io/agola/services/configstore/types"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func newGitea(rs *cstypes.RemoteSource, accessToken string) (*gitea.Client, error) {
|
||||
return gitea.New(gitea.Opts{
|
||||
c, err := gitea.New(gitea.Opts{
|
||||
APIURL: rs.APIURL,
|
||||
SkipVerify: rs.SkipVerify,
|
||||
Token: accessToken,
|
||||
Oauth2ClientID: rs.Oauth2ClientID,
|
||||
Oauth2Secret: rs.Oauth2ClientSecret,
|
||||
})
|
||||
|
||||
return c, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func newGitlab(rs *cstypes.RemoteSource, accessToken string) (*gitlab.Client, error) {
|
||||
return gitlab.New(gitlab.Opts{
|
||||
c, err := gitlab.New(gitlab.Opts{
|
||||
APIURL: rs.APIURL,
|
||||
SkipVerify: rs.SkipVerify,
|
||||
Token: accessToken,
|
||||
Oauth2ClientID: rs.Oauth2ClientID,
|
||||
Oauth2Secret: rs.Oauth2ClientSecret,
|
||||
})
|
||||
|
||||
return c, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func newGithub(rs *cstypes.RemoteSource, accessToken string) (*github.Client, error) {
|
||||
return github.New(github.Opts{
|
||||
c, err := github.New(github.Opts{
|
||||
APIURL: rs.APIURL,
|
||||
SkipVerify: rs.SkipVerify,
|
||||
Token: accessToken,
|
||||
Oauth2ClientID: rs.Oauth2ClientID,
|
||||
Oauth2Secret: rs.Oauth2ClientSecret,
|
||||
})
|
||||
|
||||
return c, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GetAccessToken(rs *cstypes.RemoteSource, userAccessToken, oauth2AccessToken string) (string, error) {
|
||||
|
@ -71,7 +76,7 @@ func GetGitSource(rs *cstypes.RemoteSource, la *cstypes.LinkedAccount) (gitsourc
|
|||
var err error
|
||||
accessToken, err = GetAccessToken(rs, la.UserAccessToken, la.Oauth2AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +93,7 @@ func GetGitSource(rs *cstypes.RemoteSource, la *cstypes.LinkedAccount) (gitsourc
|
|||
return nil, errors.Errorf("remote source %s isn't a valid git source", rs.Name)
|
||||
}
|
||||
|
||||
return gitSource, err
|
||||
return gitSource, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GetUserSource(rs *cstypes.RemoteSource, accessToken string) (gitsource.UserSource, error) {
|
||||
|
@ -103,7 +108,7 @@ func GetUserSource(rs *cstypes.RemoteSource, accessToken string) (gitsource.User
|
|||
return nil, errors.Errorf("unknown remote source auth type")
|
||||
}
|
||||
|
||||
return userSource, err
|
||||
return userSource, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GetOauth2Source(rs *cstypes.RemoteSource, accessToken string) (gitsource.Oauth2Source, error) {
|
||||
|
@ -120,7 +125,7 @@ func GetOauth2Source(rs *cstypes.RemoteSource, accessToken string) (gitsource.Oa
|
|||
return nil, errors.Errorf("remote source %s isn't a valid oauth2 source", rs.Name)
|
||||
}
|
||||
|
||||
return oauth2Source, err
|
||||
return oauth2Source, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GetPasswordSource(rs *cstypes.RemoteSource, accessToken string) (gitsource.PasswordSource, error) {
|
||||
|
@ -133,5 +138,5 @@ func GetPasswordSource(rs *cstypes.RemoteSource, accessToken string) (gitsource.
|
|||
return nil, errors.Errorf("remote source %s isn't a valid oauth2 source", rs.Name)
|
||||
}
|
||||
|
||||
return passwordSource, err
|
||||
return passwordSource, errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type TokenSigningData struct {
|
||||
|
@ -44,13 +44,14 @@ func GenerateGenericJWTToken(sd *TokenSigningData, claims jwt.Claims) (string, e
|
|||
return "", errors.Errorf("unsupported signing method %q", sd.Method.Alg())
|
||||
}
|
||||
// Sign and get the complete encoded token as a string
|
||||
return token.SignedString(key)
|
||||
ts, err := token.SignedString(key)
|
||||
return ts, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func GenerateOauth2JWTToken(sd *TokenSigningData, remoteSourceName, requestType string, request interface{}) (string, error) {
|
||||
requestj, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return GenerateGenericJWTToken(sd, jwt.MapClaims{
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/services/types"
|
||||
"agola.io/agola/internal/util"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type GroupType string
|
||||
|
@ -49,7 +48,7 @@ func WebHookEventToRunRefType(we types.WebhookEvent) types.RunRefType {
|
|||
return types.RunRefTypePullRequest
|
||||
}
|
||||
|
||||
panic(fmt.Errorf("invalid webhook event type: %q", we))
|
||||
panic(errors.Errorf("invalid webhook event type: %q", we))
|
||||
}
|
||||
|
||||
func GenRunGroup(baseGroupType GroupType, baseGroupID string, groupType GroupType, group string) string {
|
||||
|
|
|
@ -18,9 +18,9 @@ import (
|
|||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
|
@ -273,12 +273,12 @@ var defaultConfig = Config{
|
|||
func Parse(configFile string, componentsNames []string) (*Config, error) {
|
||||
configData, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
c := &defaultConfig
|
||||
if err := yaml.Unmarshal(configData, &c); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return c, Validate(c, componentsNames)
|
||||
|
@ -333,7 +333,7 @@ func Validate(c *Config, componentsNames []string) error {
|
|||
return errors.Errorf("gateway runserviceURL is empty")
|
||||
}
|
||||
if err := validateWeb(&c.Gateway.Web); err != nil {
|
||||
return errors.Errorf("gateway web configuration error: %w", err)
|
||||
return errors.Wrapf(err, "gateway web configuration error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ func Validate(c *Config, componentsNames []string) error {
|
|||
return errors.Errorf("configstore dataDir is empty")
|
||||
}
|
||||
if err := validateWeb(&c.Configstore.Web); err != nil {
|
||||
return errors.Errorf("configstore web configuration error: %w", err)
|
||||
return errors.Wrapf(err, "configstore web configuration error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ func Validate(c *Config, componentsNames []string) error {
|
|||
return errors.Errorf("runservice dataDir is empty")
|
||||
}
|
||||
if err := validateWeb(&c.Runservice.Web); err != nil {
|
||||
return errors.Errorf("runservice web configuration error: %w", err)
|
||||
return errors.Wrapf(err, "runservice web configuration error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ func Validate(c *Config, componentsNames []string) error {
|
|||
}
|
||||
|
||||
if err := validateInitImage(&c.Executor.InitImage); err != nil {
|
||||
return errors.Errorf("executor initImage configuration error: %w", err)
|
||||
return errors.Wrapf(err, "executor initImage configuration error")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"path"
|
||||
"testing"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
"agola.io/agola/internal/errors"
|
||||
)
|
||||
|
||||
func TestParseConfig(t *testing.T) {
|
||||
|
|
|
@ -17,13 +17,13 @@ package action
|
|||
import (
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
"agola.io/agola/internal/services/configstore/readdb"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type ActionHandler struct {
|
||||
|
@ -53,7 +53,7 @@ func (h *ActionHandler) ResolveConfigID(tx *db.Tx, configType types.ConfigType,
|
|||
case types.ConfigTypeProjectGroup:
|
||||
group, err := h.readDB.GetProjectGroup(tx, ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if group == nil {
|
||||
return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("group with ref %q doesn't exists", ref))
|
||||
|
@ -63,7 +63,7 @@ func (h *ActionHandler) ResolveConfigID(tx *db.Tx, configType types.ConfigType,
|
|||
case types.ConfigTypeProject:
|
||||
project, err := h.readDB.GetProject(tx, ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if project == nil {
|
||||
return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with ref %q doesn't exists", ref))
|
||||
|
|
|
@ -18,17 +18,16 @@ import (
|
|||
"context"
|
||||
"io"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/etcd"
|
||||
"agola.io/agola/internal/services/configstore/common"
|
||||
"agola.io/agola/internal/util"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error {
|
||||
resp, err := h.e.Get(ctx, common.EtcdMaintenanceKey, 0)
|
||||
if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if enable && len(resp.Kvs) > 0 {
|
||||
|
@ -41,7 +40,7 @@ func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error
|
|||
if enable {
|
||||
txResp, err := h.e.AtomicPut(ctx, common.EtcdMaintenanceKey, []byte{}, 0, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if !txResp.Succeeded {
|
||||
return errors.Errorf("failed to create maintenance mode key due to concurrent update")
|
||||
|
@ -51,7 +50,7 @@ func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error
|
|||
if !enable {
|
||||
txResp, err := h.e.AtomicDelete(ctx, common.EtcdMaintenanceKey, resp.Kvs[0].ModRevision)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if !txResp.Succeeded {
|
||||
return errors.Errorf("failed to delete maintenance mode key due to concurrent update")
|
||||
|
@ -62,12 +61,12 @@ func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error
|
|||
}
|
||||
|
||||
func (h *ActionHandler) Export(ctx context.Context, w io.Writer) error {
|
||||
return h.dm.Export(ctx, w)
|
||||
return errors.WithStack(h.dm.Export(ctx, w))
|
||||
}
|
||||
|
||||
func (h *ActionHandler) Import(ctx context.Context, r io.Reader) error {
|
||||
if !h.maintenanceMode {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("not in maintenance mode"))
|
||||
}
|
||||
return h.dm.Import(ctx, r)
|
||||
return errors.WithStack(h.dm.Import(ctx, r))
|
||||
}
|
||||
|
|
|
@ -22,12 +22,13 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/services/configstore/readdb"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type OrgMemberResponse struct {
|
||||
|
@ -48,17 +49,17 @@ func (h *ActionHandler) GetOrgMembers(ctx context.Context, orgRef string) ([]*Or
|
|||
var err error
|
||||
org, err := h.readDB.GetOrg(tx, orgRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if org == nil {
|
||||
return util.NewAPIError(util.ErrNotExist, errors.Errorf("org %q doesn't exist", orgRef))
|
||||
}
|
||||
|
||||
orgUsers, err = h.readDB.GetOrgUsers(tx, org.ID)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
res := make([]*OrgMemberResponse, len(orgUsers))
|
||||
|
@ -89,13 +90,13 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
var err error
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check duplicate org name
|
||||
o, err := h.readDB.GetOrgByName(tx, org.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if o != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q already exists", o.Name))
|
||||
|
@ -104,7 +105,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
if org.CreatorUserID != "" {
|
||||
user, err := h.readDB.GetUser(tx, org.CreatorUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("creator user %q doesn't exist", org.CreatorUserID))
|
||||
|
@ -114,7 +115,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{}
|
||||
|
@ -123,7 +124,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
org.CreatedAt = time.Now()
|
||||
orgj, err := json.Marshal(org)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal org: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal org")
|
||||
}
|
||||
actions = append(actions, &datamanager.Action{
|
||||
ActionType: datamanager.ActionTypePut,
|
||||
|
@ -142,7 +143,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
}
|
||||
orgmemberj, err := json.Marshal(orgmember)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project group: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project group")
|
||||
}
|
||||
actions = append(actions, &datamanager.Action{
|
||||
ActionType: datamanager.ActionTypePut,
|
||||
|
@ -164,7 +165,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
}
|
||||
pgj, err := json.Marshal(pg)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project group: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project group")
|
||||
}
|
||||
actions = append(actions, &datamanager.Action{
|
||||
ActionType: datamanager.ActionTypePut,
|
||||
|
@ -174,7 +175,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
|
|||
})
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return org, err
|
||||
return org, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
|
||||
|
@ -187,7 +188,7 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
|
|||
// check org existance
|
||||
org, err = h.readDB.GetOrgByName(tx, orgRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if org == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exist", orgRef))
|
||||
|
@ -197,13 +198,13 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
|
|||
cgNames := []string{util.EncodeSha256Hex("orgid-" + org.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// TODO(sgotti) delete all project groups, projects etc...
|
||||
|
@ -216,7 +217,7 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// AddOrgMember add/updates an org member.
|
||||
|
@ -237,7 +238,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
|
|||
// check existing org
|
||||
org, err = h.readDB.GetOrg(tx, orgRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if org == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exists", orgRef))
|
||||
|
@ -245,7 +246,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
|
|||
// check existing user
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exists", userRef))
|
||||
|
@ -254,19 +255,19 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
|
|||
// fetch org member if it already exist
|
||||
orgmember, err = h.readDB.GetOrgMemberByOrgUserID(tx, org.ID, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
cgNames := []string{util.EncodeSha256Hex(fmt.Sprintf("orgmember-%s-%s", org.ID, user.ID))}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// update if role changed
|
||||
|
@ -287,7 +288,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
|
|||
actions := []*datamanager.Action{}
|
||||
orgmemberj, err := json.Marshal(orgmember)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project group: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project group")
|
||||
}
|
||||
actions = append(actions, &datamanager.Action{
|
||||
ActionType: datamanager.ActionTypePut,
|
||||
|
@ -297,7 +298,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
|
|||
})
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return orgmember, err
|
||||
return orgmember, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// RemoveOrgMember removes an org member.
|
||||
|
@ -313,7 +314,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
|
|||
// check existing org
|
||||
org, err = h.readDB.GetOrg(tx, orgRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if org == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exists", orgRef))
|
||||
|
@ -321,7 +322,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
|
|||
// check existing user
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exists", userRef))
|
||||
|
@ -330,7 +331,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
|
|||
// check that org member exists
|
||||
orgmember, err = h.readDB.GetOrgMemberByOrgUserID(tx, org.ID, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if orgmember == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("orgmember for org %q, user %q doesn't exists", orgRef, userRef))
|
||||
|
@ -339,13 +340,13 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
|
|||
cgNames := []string{util.EncodeSha256Hex(fmt.Sprintf("orgmember-%s-%s", org.ID, user.ID))}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{}
|
||||
|
@ -356,5 +357,5 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
|
|||
})
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -21,11 +21,12 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) ValidateProject(ctx context.Context, project *types.Project) error {
|
||||
|
@ -69,10 +70,10 @@ func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*typ
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
var err error
|
||||
project, err = h.readDB.GetProject(tx, projectRef)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if project == nil {
|
||||
|
@ -84,7 +85,7 @@ func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*typ
|
|||
|
||||
func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Project) (*types.Project, error) {
|
||||
if err := h.ValidateProject(ctx, project); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -94,7 +95,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
var err error
|
||||
group, err := h.readDB.GetProjectGroup(tx, project.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if group == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", project.Parent.ID))
|
||||
|
@ -103,7 +104,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
|
||||
groupPath, err := h.readDB.GetProjectGroupPath(tx, group)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
pp := path.Join(groupPath, project.Name)
|
||||
|
||||
|
@ -112,13 +113,13 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
cgNames := []string{util.EncodeSha256Hex("projectpath-" + pp)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check duplicate project name
|
||||
p, err := h.readDB.GetProjectByName(tx, project.Parent.ID, project.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if p != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with name %q, path %q already exists", p.Name, pp))
|
||||
|
@ -128,7 +129,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
// check that the linked account matches the remote source
|
||||
user, err := h.readDB.GetUserByLinkedAccount(tx, project.LinkedAccountID)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get user with linked account id %q: %w", project.LinkedAccountID, err)
|
||||
return errors.Wrapf(err, "failed to get user with linked account id %q", project.LinkedAccountID)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for linked account %q doesn't exist", project.LinkedAccountID))
|
||||
|
@ -145,7 +146,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
project.ID = uuid.Must(uuid.NewV4()).String()
|
||||
|
@ -156,7 +157,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
|
||||
pcj, err := json.Marshal(project)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -168,7 +169,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return project, err
|
||||
return project, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateProjectRequest struct {
|
||||
|
@ -179,7 +180,7 @@ type UpdateProjectRequest struct {
|
|||
|
||||
func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectRequest) (*types.Project, error) {
|
||||
if err := h.ValidateProject(ctx, req.Project); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -190,7 +191,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
// check project exists
|
||||
p, err := h.readDB.GetProject(tx, req.ProjectRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if p == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with ref %q doesn't exist", req.ProjectRef))
|
||||
|
@ -203,7 +204,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
// check parent project group exists
|
||||
group, err := h.readDB.GetProjectGroup(tx, req.Project.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if group == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", req.Project.Parent.ID))
|
||||
|
@ -212,7 +213,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
|
||||
groupPath, err := h.readDB.GetProjectGroupPath(tx, group)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
pp := path.Join(groupPath, req.Project.Name)
|
||||
|
||||
|
@ -220,7 +221,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
// check duplicate project name
|
||||
ap, err := h.readDB.GetProjectByName(tx, req.Project.Parent.ID, req.Project.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if ap != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with name %q, path %q already exists", req.Project.Name, pp))
|
||||
|
@ -236,14 +237,14 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
// get old parent project group
|
||||
curGroup, err := h.readDB.GetProjectGroup(tx, p.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if curGroup == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", p.Parent.ID))
|
||||
}
|
||||
curGroupPath, err := h.readDB.GetProjectGroupPath(tx, curGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
pp := path.Join(curGroupPath, req.Project.Name)
|
||||
|
||||
|
@ -252,14 +253,14 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if req.Project.RemoteRepositoryConfigType == types.RemoteRepositoryConfigTypeRemoteSource {
|
||||
// check that the linked account matches the remote source
|
||||
user, err := h.readDB.GetUserByLinkedAccount(tx, req.Project.LinkedAccountID)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get user with linked account id %q: %w", req.Project.LinkedAccountID, err)
|
||||
return errors.Wrapf(err, "failed to get user with linked account id %q", req.Project.LinkedAccountID)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for linked account %q doesn't exist", req.Project.LinkedAccountID))
|
||||
|
@ -276,12 +277,12 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
pcj, err := json.Marshal(req.Project)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -293,7 +294,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return req.Project, err
|
||||
return req.Project, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) error {
|
||||
|
@ -308,7 +309,7 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
|
|||
// check project existance
|
||||
project, err = h.readDB.GetProject(tx, projectRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if project == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project %q doesn't exist", projectRef))
|
||||
|
@ -318,13 +319,13 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
|
|||
cgNames := []string{util.EncodeSha256Hex(project.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// TODO(sgotti) implement childs garbage collection
|
||||
|
@ -337,5 +338,5 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -22,11 +22,12 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) GetProjectGroup(ctx context.Context, projectGroupRef string) (*types.ProjectGroup, error) {
|
||||
|
@ -34,10 +35,10 @@ func (h *ActionHandler) GetProjectGroup(ctx context.Context, projectGroupRef str
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
var err error
|
||||
projectGroup, err = h.readDB.GetProjectGroup(tx, projectGroupRef)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if projectGroup == nil {
|
||||
|
@ -53,7 +54,7 @@ func (h *ActionHandler) GetProjectGroupSubgroups(ctx context.Context, projectGro
|
|||
var err error
|
||||
projectGroup, err := h.readDB.GetProjectGroup(tx, projectGroupRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if projectGroup == nil {
|
||||
|
@ -61,10 +62,10 @@ func (h *ActionHandler) GetProjectGroupSubgroups(ctx context.Context, projectGro
|
|||
}
|
||||
|
||||
projectGroups, err = h.readDB.GetProjectGroupSubgroups(tx, projectGroup.ID)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return projectGroups, nil
|
||||
|
@ -76,7 +77,7 @@ func (h *ActionHandler) GetProjectGroupProjects(ctx context.Context, projectGrou
|
|||
var err error
|
||||
projectGroup, err := h.readDB.GetProjectGroup(tx, projectGroupRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if projectGroup == nil {
|
||||
|
@ -84,10 +85,10 @@ func (h *ActionHandler) GetProjectGroupProjects(ctx context.Context, projectGrou
|
|||
}
|
||||
|
||||
projects, err = h.readDB.GetProjectGroupProjects(tx, projectGroup.ID)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
@ -125,7 +126,7 @@ func (h *ActionHandler) ValidateProjectGroup(ctx context.Context, projectGroup *
|
|||
|
||||
func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *types.ProjectGroup) (*types.ProjectGroup, error) {
|
||||
if err := h.ValidateProjectGroup(ctx, projectGroup); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if projectGroup.Parent.Type != types.ConfigTypeProjectGroup {
|
||||
|
@ -138,7 +139,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
parentProjectGroup, err := h.readDB.GetProjectGroup(tx, projectGroup.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if parentProjectGroup == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", projectGroup.Parent.ID))
|
||||
|
@ -150,7 +151,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
|
||||
groupPath, err := h.readDB.GetProjectGroupPath(tx, parentProjectGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
pp := path.Join(groupPath, projectGroup.Name)
|
||||
|
||||
|
@ -159,13 +160,13 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
cgNames := []string{util.EncodeSha256Hex("projectpath-" + pp)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check duplicate project group name
|
||||
pg, err := h.readDB.GetProjectGroupByName(tx, projectGroup.Parent.ID, projectGroup.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if pg != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with name %q, path %q already exists", pg.Name, pp))
|
||||
|
@ -173,7 +174,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
projectGroup.ID = uuid.Must(uuid.NewV4()).String()
|
||||
|
@ -181,7 +182,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
|
||||
pgj, err := json.Marshal(projectGroup)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal projectGroup: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal projectGroup")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -193,7 +194,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return projectGroup, err
|
||||
return projectGroup, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateProjectGroupRequest struct {
|
||||
|
@ -204,7 +205,7 @@ type UpdateProjectGroupRequest struct {
|
|||
|
||||
func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProjectGroupRequest) (*types.ProjectGroup, error) {
|
||||
if err := h.ValidateProjectGroup(ctx, req.ProjectGroup); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -215,7 +216,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
// check project exists
|
||||
pg, err := h.readDB.GetProjectGroup(tx, req.ProjectGroupRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if pg == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with ref %q doesn't exist", req.ProjectGroupRef))
|
||||
|
@ -244,7 +245,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
// check parent exists
|
||||
group, err := h.readDB.GetProjectGroup(tx, req.ProjectGroup.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if group == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", req.ProjectGroup.Parent.ID))
|
||||
|
@ -257,13 +258,13 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
|
||||
curPGParentPath, err := h.readDB.GetPath(tx, pg.Parent.Type, pg.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
curPGP := path.Join(curPGParentPath, pg.Name)
|
||||
|
||||
pgParentPath, err := h.readDB.GetPath(tx, req.ProjectGroup.Parent.Type, req.ProjectGroup.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
pgp := path.Join(pgParentPath, req.ProjectGroup.Name)
|
||||
|
||||
|
@ -271,7 +272,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
// check duplicate project group name
|
||||
ap, err := h.readDB.GetProjectGroupByName(tx, req.ProjectGroup.Parent.ID, req.ProjectGroup.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if ap != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with name %q, path %q already exists", req.ProjectGroup.Name, pgp))
|
||||
|
@ -293,18 +294,18 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
pgj, err := json.Marshal(req.ProjectGroup)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -316,7 +317,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return req.ProjectGroup, err
|
||||
return req.ProjectGroup, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectGroupRef string) error {
|
||||
|
@ -331,7 +332,7 @@ func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectGroupRef
|
|||
// check project group existance
|
||||
projectGroup, err = h.readDB.GetProjectGroup(tx, projectGroupRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if projectGroup == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group %q doesn't exist", projectGroupRef))
|
||||
|
@ -347,13 +348,13 @@ func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectGroupRef
|
|||
cgNames := []string{util.EncodeSha256Hex(projectGroup.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// TODO(sgotti) implement childs garbage collection
|
||||
|
@ -366,5 +367,5 @@ func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectGroupRef
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -20,11 +20,12 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) ValidateRemoteSource(ctx context.Context, remoteSource *types.RemoteSource) error {
|
||||
|
@ -66,7 +67,7 @@ func (h *ActionHandler) ValidateRemoteSource(ctx context.Context, remoteSource *
|
|||
|
||||
func (h *ActionHandler) CreateRemoteSource(ctx context.Context, remoteSource *types.RemoteSource) (*types.RemoteSource, error) {
|
||||
if err := h.ValidateRemoteSource(ctx, remoteSource); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -78,13 +79,13 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, remoteSource *ty
|
|||
var err error
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check duplicate remoteSource name
|
||||
u, err := h.readDB.GetRemoteSourceByName(tx, remoteSource.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q already exists", u.Name))
|
||||
|
@ -92,14 +93,14 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, remoteSource *ty
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
remoteSource.ID = uuid.Must(uuid.NewV4()).String()
|
||||
|
||||
rsj, err := json.Marshal(remoteSource)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal remotesource: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal remotesource")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -111,7 +112,7 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, remoteSource *ty
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return remoteSource, err
|
||||
return remoteSource, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateRemoteSourceRequest struct {
|
||||
|
@ -122,7 +123,7 @@ type UpdateRemoteSourceRequest struct {
|
|||
|
||||
func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemoteSourceRequest) (*types.RemoteSource, error) {
|
||||
if err := h.ValidateRemoteSource(ctx, req.RemoteSource); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var curRemoteSource *types.RemoteSource
|
||||
|
@ -135,7 +136,7 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
|
|||
// check remotesource exists
|
||||
curRemoteSource, err = h.readDB.GetRemoteSourceByName(tx, req.RemoteSourceRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if curRemoteSource == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource with ref %q doesn't exist", req.RemoteSourceRef))
|
||||
|
@ -145,7 +146,7 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
|
|||
// check duplicate remoteSource name
|
||||
u, err := h.readDB.GetRemoteSourceByName(tx, req.RemoteSource.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q already exists", u.Name))
|
||||
|
@ -160,17 +161,17 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
|
|||
cgNames := []string{util.EncodeSha256Hex("remotesourcename-" + req.RemoteSource.Name), util.EncodeSha256Hex("remotesourceid-" + req.RemoteSource.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
rsj, err := json.Marshal(req.RemoteSource)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal remotesource: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal remotesource")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -182,7 +183,7 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return req.RemoteSource, err
|
||||
return req.RemoteSource, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, remoteSourceName string) error {
|
||||
|
@ -196,7 +197,7 @@ func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, remoteSourceName
|
|||
// check remoteSource existance
|
||||
remoteSource, err = h.readDB.GetRemoteSourceByName(tx, remoteSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if remoteSource == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q doesn't exist", remoteSourceName))
|
||||
|
@ -206,13 +207,13 @@ func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, remoteSourceName
|
|||
cgNames := []string{util.EncodeSha256Hex("remotesourceid-" + remoteSource.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -225,5 +226,5 @@ func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, remoteSourceName
|
|||
|
||||
// changegroup is all the remotesources
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -20,11 +20,12 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) GetSecret(ctx context.Context, secretID string) (*types.Secret, error) {
|
||||
|
@ -32,10 +33,10 @@ func (h *ActionHandler) GetSecret(ctx context.Context, secretID string) (*types.
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
var err error
|
||||
secret, err = h.readDB.GetSecretByID(tx, secretID)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if secret == nil {
|
||||
|
@ -50,17 +51,17 @@ func (h *ActionHandler) GetSecrets(ctx context.Context, parentType types.ConfigT
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if tree {
|
||||
secrets, err = h.readDB.GetSecretsTree(tx, parentType, parentID)
|
||||
} else {
|
||||
secrets, err = h.readDB.GetSecrets(tx, parentID)
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return secrets, nil
|
||||
|
@ -97,7 +98,7 @@ func (h *ActionHandler) ValidateSecret(ctx context.Context, secret *types.Secret
|
|||
|
||||
func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret) (*types.Secret, error) {
|
||||
if err := h.ValidateSecret(ctx, secret); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -109,19 +110,19 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret)
|
|||
var err error
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
parentID, err := h.ResolveConfigID(tx, secret.Parent.Type, secret.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
secret.Parent.ID = parentID
|
||||
|
||||
// check duplicate secret name
|
||||
s, err := h.readDB.GetSecretByName(tx, secret.Parent.ID, secret.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if s != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q already exists", secret.Name, secret.Parent.Type, secret.Parent.ID))
|
||||
|
@ -130,14 +131,14 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret)
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
secret.ID = uuid.Must(uuid.NewV4()).String()
|
||||
|
||||
secretj, err := json.Marshal(secret)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal secret: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal secret")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -149,7 +150,7 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret)
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return secret, err
|
||||
return secret, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateSecretRequest struct {
|
||||
|
@ -160,7 +161,7 @@ type UpdateSecretRequest struct {
|
|||
|
||||
func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretRequest) (*types.Secret, error) {
|
||||
if err := h.ValidateSecret(ctx, req.Secret); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var curSecret *types.Secret
|
||||
|
@ -173,14 +174,14 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
|
|||
|
||||
parentID, err := h.ResolveConfigID(tx, req.Secret.Parent.Type, req.Secret.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
req.Secret.Parent.ID = parentID
|
||||
|
||||
// check secret exists
|
||||
curSecret, err = h.readDB.GetSecretByName(tx, req.Secret.Parent.ID, req.SecretName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if curSecret == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q doesn't exists", req.SecretName, req.Secret.Parent.Type, req.Secret.Parent.ID))
|
||||
|
@ -190,7 +191,7 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
|
|||
// check duplicate secret name
|
||||
u, err := h.readDB.GetSecretByName(tx, req.Secret.Parent.ID, req.Secret.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q already exists", req.Secret.Name, req.Secret.Parent.Type, req.Secret.Parent.ID))
|
||||
|
@ -206,18 +207,18 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
|
|||
}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
secretj, err := json.Marshal(req.Secret)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal secret: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal secret")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -229,7 +230,7 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return req.Secret, err
|
||||
return req.Secret, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.ConfigType, parentRef, secretName string) error {
|
||||
|
@ -242,13 +243,13 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.Confi
|
|||
var err error
|
||||
parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check secret existance
|
||||
secret, err = h.readDB.GetSecretByName(tx, parentID, secretName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if secret == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q doesn't exist", secretName))
|
||||
|
@ -258,13 +259,13 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.Confi
|
|||
cgNames := []string{util.EncodeSha256Hex("secretid-" + secret.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -276,5 +277,5 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.Confi
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -21,12 +21,13 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/services/configstore/readdb"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type CreateUserRequest struct {
|
||||
|
@ -54,13 +55,13 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
var err error
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check duplicate user name
|
||||
u, err := h.readDB.GetUserByName(tx, req.UserName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user with name %q already exists", u.Name))
|
||||
|
@ -69,14 +70,14 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
if req.CreateUserLARequest != nil {
|
||||
rs, err = h.readDB.GetRemoteSourceByName(tx, req.CreateUserLARequest.RemoteSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if rs == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source %q doesn't exist", req.CreateUserLARequest.RemoteSourceName))
|
||||
}
|
||||
user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.CreateUserLARequest.RemoteUserID, rs.ID)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.CreateUserLARequest.RemoteUserID, rs.ID, err)
|
||||
return errors.Wrapf(err, "failed to get user for remote user id %q and remote source %q", req.CreateUserLARequest.RemoteUserID, rs.ID)
|
||||
}
|
||||
if user != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for remote user id %q for remote source %q already exists", req.CreateUserLARequest.RemoteUserID, req.CreateUserLARequest.RemoteSourceName))
|
||||
|
@ -85,7 +86,7 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
user := &types.User{
|
||||
|
@ -114,7 +115,7 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal user: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
|
||||
// create root user project group
|
||||
|
@ -129,7 +130,7 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
}
|
||||
pgj, err := json.Marshal(pg)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal project group: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal project group")
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -148,7 +149,7 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return user, err
|
||||
return user, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
|
||||
|
@ -162,7 +163,7 @@ func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
|
|||
// check user existance
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
|
||||
|
@ -172,13 +173,13 @@ func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -190,7 +191,7 @@ func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
|
@ -210,7 +211,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, req.UserRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
|
||||
|
@ -218,14 +219,14 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
|
|||
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if req.UserName != "" {
|
||||
// check duplicate user name
|
||||
u, err := h.readDB.GetUserByName(tx, req.UserName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user with name %q already exists", u.Name))
|
||||
|
@ -238,7 +239,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if req.UserName != "" {
|
||||
|
@ -247,7 +248,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal user: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -260,7 +261,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return user, err
|
||||
return user, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type CreateUserLARequest struct {
|
||||
|
@ -293,7 +294,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, req.UserRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
|
||||
|
@ -303,12 +304,12 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
rs, err = h.readDB.GetRemoteSourceByName(tx, req.RemoteSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if rs == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source %q doesn't exist", req.RemoteSourceName))
|
||||
|
@ -316,7 +317,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
|
||||
user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.RemoteUserID, rs.ID)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.RemoteUserID, rs.ID, err)
|
||||
return errors.Wrapf(err, "failed to get user for remote user id %q and remote source %q", req.RemoteUserID, rs.ID)
|
||||
}
|
||||
if user != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for remote user id %q for remote source %q already exists", req.RemoteUserID, req.RemoteSourceName))
|
||||
|
@ -324,7 +325,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if user.LinkedAccounts == nil {
|
||||
|
@ -346,7 +347,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal user: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -358,7 +359,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return la, err
|
||||
return la, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string) error {
|
||||
|
@ -378,7 +379,7 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
|
||||
|
@ -388,13 +389,13 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
_, ok := user.LinkedAccounts[laID]
|
||||
|
@ -406,7 +407,7 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to marshal user: %w", err)
|
||||
return errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -418,7 +419,7 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateUserLARequest struct {
|
||||
|
@ -448,7 +449,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, req.UserRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
|
||||
|
@ -458,7 +459,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
la, ok := user.LinkedAccounts[req.LinkedAccountID]
|
||||
|
@ -468,7 +469,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
|
||||
rs, err = h.readDB.GetRemoteSource(tx, la.RemoteSourceID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if rs == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source with id %q doesn't exist", la.RemoteSourceID))
|
||||
|
@ -476,7 +477,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
la := user.LinkedAccounts[req.LinkedAccountID]
|
||||
|
@ -490,7 +491,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal user: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -502,7 +503,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return la, err
|
||||
return la, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName string) (string, error) {
|
||||
|
@ -522,7 +523,7 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
|
||||
|
@ -532,13 +533,13 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
if user.Tokens != nil {
|
||||
if _, ok := user.Tokens[tokenName]; ok {
|
||||
|
@ -555,7 +556,7 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return "", errors.Errorf("failed to marshal user: %w", err)
|
||||
return "", errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -567,7 +568,7 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return token, err
|
||||
return token, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName string) error {
|
||||
|
@ -587,7 +588,7 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
|
|||
var err error
|
||||
user, err = h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
|
||||
|
@ -597,13 +598,13 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
|
|||
cgNames := []string{util.EncodeSha256Hex("userid-" + user.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
_, ok := user.Tokens[tokenName]
|
||||
|
@ -615,7 +616,7 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
|
|||
|
||||
userj, err := json.Marshal(user)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to marshal user: %w", err)
|
||||
return errors.Wrapf(err, "failed to marshal user")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -627,7 +628,7 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UserOrgsResponse struct {
|
||||
|
@ -648,17 +649,17 @@ func (h *ActionHandler) GetUserOrgs(ctx context.Context, userRef string) ([]*Use
|
|||
var err error
|
||||
user, err := h.readDB.GetUser(tx, userRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if user == nil {
|
||||
return util.NewAPIError(util.ErrNotExist, errors.Errorf("user %q doesn't exist", userRef))
|
||||
}
|
||||
|
||||
userOrgs, err = h.readDB.GetUserOrgs(tx, user.ID)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
res := make([]*UserOrgsResponse, len(userOrgs))
|
||||
|
|
|
@ -20,11 +20,12 @@ import (
|
|||
|
||||
"agola.io/agola/internal/datamanager"
|
||||
"agola.io/agola/internal/db"
|
||||
"agola.io/agola/internal/errors"
|
||||
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func (h *ActionHandler) GetVariables(ctx context.Context, parentType types.ConfigType, parentRef string, tree bool) ([]*types.Variable, error) {
|
||||
|
@ -32,17 +33,17 @@ func (h *ActionHandler) GetVariables(ctx context.Context, parentType types.Confi
|
|||
err := h.readDB.Do(ctx, func(tx *db.Tx) error {
|
||||
parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if tree {
|
||||
variables, err = h.readDB.GetVariablesTree(tx, parentType, parentID)
|
||||
} else {
|
||||
variables, err = h.readDB.GetVariables(tx, parentID)
|
||||
}
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return variables, nil
|
||||
|
@ -73,7 +74,7 @@ func (h *ActionHandler) ValidateVariable(ctx context.Context, variable *types.Va
|
|||
|
||||
func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Variable) (*types.Variable, error) {
|
||||
if err := h.ValidateVariable(ctx, variable); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var cgt *datamanager.ChangeGroupsUpdateToken
|
||||
|
@ -85,19 +86,19 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Vari
|
|||
var err error
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
parentID, err := h.ResolveConfigID(tx, variable.Parent.Type, variable.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
variable.Parent.ID = parentID
|
||||
|
||||
// check duplicate variable name
|
||||
s, err := h.readDB.GetVariableByName(tx, variable.Parent.ID, variable.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if s != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q already exists", variable.Name, variable.Parent.Type, variable.Parent.ID))
|
||||
|
@ -106,14 +107,14 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Vari
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
variable.ID = uuid.Must(uuid.NewV4()).String()
|
||||
|
||||
variablej, err := json.Marshal(variable)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal variable: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal variable")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -125,7 +126,7 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Vari
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return variable, err
|
||||
return variable, errors.WithStack(err)
|
||||
}
|
||||
|
||||
type UpdateVariableRequest struct {
|
||||
|
@ -136,7 +137,7 @@ type UpdateVariableRequest struct {
|
|||
|
||||
func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableRequest) (*types.Variable, error) {
|
||||
if err := h.ValidateVariable(ctx, req.Variable); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var curVariable *types.Variable
|
||||
|
@ -149,14 +150,14 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
|
|||
|
||||
parentID, err := h.ResolveConfigID(tx, req.Variable.Parent.Type, req.Variable.Parent.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
req.Variable.Parent.ID = parentID
|
||||
|
||||
// check variable exists
|
||||
curVariable, err = h.readDB.GetVariableByName(tx, req.Variable.Parent.ID, req.VariableName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if curVariable == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q doesn't exists", req.VariableName, req.Variable.Parent.Type, req.Variable.Parent.ID))
|
||||
|
@ -166,7 +167,7 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
|
|||
// check duplicate variable name
|
||||
u, err := h.readDB.GetVariableByName(tx, req.Variable.Parent.ID, req.Variable.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if u != nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q already exists", req.Variable.Name, req.Variable.Parent.Type, req.Variable.Parent.ID))
|
||||
|
@ -182,18 +183,18 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
|
|||
}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
variablej, err := json.Marshal(req.Variable)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to marshal variable: %w", err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal variable")
|
||||
}
|
||||
actions := []*datamanager.Action{
|
||||
{
|
||||
|
@ -205,7 +206,7 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return req.Variable, err
|
||||
return req.Variable, errors.WithStack(err)
|
||||
}
|
||||
|
||||
func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.ConfigType, parentRef, variableName string) error {
|
||||
|
@ -218,13 +219,13 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.Con
|
|||
var err error
|
||||
parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// check variable existance
|
||||
variable, err = h.readDB.GetVariableByName(tx, parentID, variableName)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if variable == nil {
|
||||
return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q doesn't exist", variableName))
|
||||
|
@ -234,12 +235,12 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.Con
|
|||
cgNames := []string{util.EncodeSha256Hex("variableid-" + variable.ID)}
|
||||
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
actions := []*datamanager.Action{
|
||||
|
@ -251,5 +252,5 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.Con
|
|||
}
|
||||
|
||||
_, err = h.dm.WriteWal(ctx, actions, cgt)
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"agola.io/agola/internal/errors"
|
||||
"agola.io/agola/internal/util"
|
||||
"agola.io/agola/services/configstore/types"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type ErrorResponse struct {
|
||||
|
@ -33,7 +33,7 @@ func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) {
|
|||
vars := mux.Vars(r)
|
||||
projectRef, err := url.PathUnescape(vars["projectref"])
|
||||
if err != nil {
|
||||
return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectref %q: %w", vars["projectref"], err))
|
||||
return "", "", util.NewAPIError(util.ErrBadRequest, errors.Wrapf(err, "wrong projectref %q", vars["projectref"]))
|
||||
}
|
||||
if projectRef != "" {
|
||||
return types.ConfigTypeProject, projectRef, nil
|
||||
|
@ -41,7 +41,7 @@ func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) {
|
|||
|
||||
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
|
||||
if err != nil {
|
||||
return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectgroupref %q: %w", vars["projectgroupref"], err))
|
||||
return "", "", util.NewAPIError(util.ErrBadRequest, errors.Wrapf(err, "wrong projectgroupref %q", vars["projectgroupref"]))
|
||||
}
|
||||
if projectGroupRef != "" {
|
||||
return types.ConfigTypeProjectGroup, projectGroupRef, nil
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue