diff --git a/cmd/trx/lock.go b/cmd/trx/lock.go deleted file mode 100644 index 757d97e..0000000 --- a/cmd/trx/lock.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "fmt" - "log" - "os" - - "github.com/spf13/cobra" - - "trx/internal/config" - "trx/internal/lock" - "trx/internal/storage" -) - -func forceUnlockCmd() *cobra.Command { - return &cobra.Command{ - Use: "force-unlock", - Short: "Removes execution lock", - Long: "This command removes execution lock. It can be used to unlock the execution in case of an error.", - RunE: func(cmd *cobra.Command, args []string) error { - return removeLock() - }, - } -} - -func removeLock() error { - log.SetFlags(0) - log.SetOutput(os.Stdout) - log.Println("Removing trx lock") - cfg, err := config.NewConfig(configPath) - if err != nil { - return fmt.Errorf("config error: %w", err) - } - - storage, err := storage.NewStorage(&storage.StorageOpts{ - Config: cfg, - }) - if err != nil { - return fmt.Errorf("init storage error: %w", err) - } - - locker := lock.NewLocker(storage, false) - - if err := locker.ForceUnlock(); err != nil { - return fmt.Errorf("failed to force remove lock: %w", err) - } - - log.Println("Lock removed successfully") - return nil -} diff --git a/cmd/trx/main.go b/cmd/trx/main.go index 82bac14..fa8d148 100644 --- a/cmd/trx/main.go +++ b/cmd/trx/main.go @@ -36,8 +36,6 @@ By default, it uses the ./trx.yaml configuration file, but you can specify a dif rootCmd.Flags().BoolVarP(&force, "force", "f", false, "Force execution if no new version found") rootCmd.Flags().BoolVarP(&disableLock, "disable-lock", "", false, "Disable execution locking") - rootCmd.AddCommand(forceUnlockCmd()) - if err := rootCmd.Execute(); err != nil { log.Fatal(err) } diff --git a/cmd/trx/run.go b/cmd/trx/run.go index f23f404..18e4b7f 100644 --- a/cmd/trx/run.go +++ b/cmd/trx/run.go @@ -48,28 +48,12 @@ func run(opts runOptions) error { return fmt.Errorf("init storage error: %w", err) } - if !disableLock { - locker := lock.NewLocker(storage, disableLock) - if err := locker.CheckLock(); err != nil { - var locked *lock.ErrLocked - if errors.As(err, &locked) { - log.Printf("Execution is locked by %s at %s\n", locked.User, locked.CreatedAt) - return nil - } - return fmt.Errorf("check lock error: %w", err) - } - err := locker.Lock() - if err != nil { - return fmt.Errorf("lock error: %w", err) - } - log.Println("Excution lock acquired") - defer func() { - err := locker.Unlock() - if err != nil { - log.Println("Unlock error: %w", err) - } - log.Println("Execution lock released") - }() + locker := lock.NewManager(lock.NewLocalLocker(disableLock)) + if err := locker.Acquire(cfg.Repo.Url); err != nil { + return fmt.Errorf("lock acquire error: %w", err) + } + if disableLock { + log.Println("Processing without execution lock") } gitClient, err := git.NewGitClient(cfg.Repo) diff --git a/go.mod b/go.mod index e196d60..c7079da 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/go-hclog v1.6.3 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 - golang.org/x/sync v0.12.0 + golang.org/x/sync v0.10.0 ) require ( @@ -30,10 +30,12 @@ require ( github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gookit/color v1.5.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0 // indirect @@ -55,11 +57,10 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect - github.com/onsi/ginkgo/v2 v2.23.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -67,15 +68,16 @@ require ( github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.0 // indirect - github.com/werf/logboek v0.5.5 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/werf/logboek v0.6.1 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect - golang.org/x/crypto v0.33.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/term v0.29.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/term v0.28.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/grpc v1.66.3 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) @@ -86,7 +88,6 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 - github.com/onsi/gomega v1.36.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -96,12 +97,14 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/werf/trdl/server v0.0.0-20250121125358-ad0ef5178f9b + github.com/werf/common-go v0.0.0-20250317135621-3a6772a9f88d + github.com/werf/lockgate v0.1.1 + github.com/werf/trdl/server v0.0.0-20250314141720-5f76cb564636 go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 53a96e5..7c6e763 100644 --- a/go.sum +++ b/go.sum @@ -90,10 +90,11 @@ github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -109,10 +110,14 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -195,6 +200,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -203,6 +210,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -210,10 +219,10 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/onsi/ginkgo/v2 v2.23.0 h1:FA1xjp8ieYDzlgS5ABTpdUDB7wtngggONc8a7ku2NqQ= -github.com/onsi/ginkgo/v2 v2.23.0/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= -github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= -github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4= github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= @@ -262,6 +271,8 @@ github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0 github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -292,14 +303,24 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/werf/common-go v0.0.0-20250317135621-3a6772a9f88d h1:u+0+ivCKL6E/OLGScAhxbbDtkk6BY6OGaB8BhiHpnjQ= +github.com/werf/common-go v0.0.0-20250317135621-3a6772a9f88d/go.mod h1:7pkHNfgZ2wvdwcMWCuDjdkY7iR3mIX5snYwbd1Iu7T4= +github.com/werf/lockgate v0.1.1 h1:S400JFYjtWfE4i4LY9FA8zx0fMdfui9DPrBiTciCrx4= +github.com/werf/lockgate v0.1.1/go.mod h1:0yIFSLq9ausy6ejNxF5uUBf/Ib6daMAfXuCaTMZJzIE= github.com/werf/logboek v0.5.5 h1:RmtTejHJOyw0fub4pIfKsb7OTzD90ZOUyuBAXqYqJpU= github.com/werf/logboek v0.5.5/go.mod h1:Gez5J4bxekyr6MxTmIJyId1F61rpO+0/V4vjCIEIZmk= +github.com/werf/logboek v0.6.1 h1:oEe6FkmlKg0z0n80oZjLplj6sXcBeLleCkjfOOZEL2g= +github.com/werf/logboek v0.6.1/go.mod h1:Gez5J4bxekyr6MxTmIJyId1F61rpO+0/V4vjCIEIZmk= github.com/werf/trdl/server v0.0.0-20250121125358-ad0ef5178f9b h1:C4UDzx32nm688clMejq1h/k5Bo+xYeZFcKiajfK9Kj8= github.com/werf/trdl/server v0.0.0-20250121125358-ad0ef5178f9b/go.mod h1:Kyj5iTcO6PnVpCikFDWoo1FPTQ4Cd1TQOhq+jCY1IwA= +github.com/werf/trdl/server v0.0.0-20250314141720-5f76cb564636 h1:rbtK4PmXVHCH7N9kZHywj3OLCH2eO4aDwvHBFKVpATY= +github.com/werf/trdl/server v0.0.0-20250314141720-5f76cb564636/go.mod h1:Kyj5iTcO6PnVpCikFDWoo1FPTQ4Cd1TQOhq+jCY1IwA= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= @@ -307,20 +328,20 @@ go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTV golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -341,25 +362,25 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.66.3 h1:TWlsh8Mv0QI/1sIbs1W36lqRclxrmF+eFJ4DbI0fuhA= google.golang.org/grpc v1.66.3/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/lock/local.go b/internal/lock/local.go new file mode 100644 index 0000000..83187c3 --- /dev/null +++ b/internal/lock/local.go @@ -0,0 +1,22 @@ +package lock + +import ( + lock "github.com/werf/common-go/pkg/lock" + "github.com/werf/lockgate" +) + +type Local struct { + locker Locker + disabled bool +} + +func NewLocalLocker(disabled bool) *Local { + locker, _ := lock.HostLocker() + return &Local{locker: locker, disabled: disabled} +} + +func (l *Local) Acquire(lockName string, opts lockgate.AcquireOptions) (bool, lockgate.LockHandle, error) { + return l.locker.Acquire(lockName, lockgate.AcquireOptions{ + NonBlocking: l.disabled, + }) +} diff --git a/internal/lock/lock.go b/internal/lock/lock.go index 9f2db4e..b4265fd 100644 --- a/internal/lock/lock.go +++ b/internal/lock/lock.go @@ -1,55 +1,21 @@ package lock import ( - "fmt" + "github.com/werf/lockgate" ) -type Locker struct { - storage Storage - lockingDisbaled bool +type Locker interface { + Acquire(lockName string, opts lockgate.AcquireOptions) (bool, lockgate.LockHandle, error) } - -type Storage interface { - StoreLockInfo() error - RemoveLockInfo() error - CheckLock() error - ForceRemoveLockInfo() error -} - -type ErrLocked struct { - User string - CreatedAt string -} - -func (e *ErrLocked) Error() string { - return fmt.Sprintf("locked by: %s at %s", e.User, e.CreatedAt) -} - -func NewLocker(storage Storage, lockingDisbaled bool) *Locker { - return &Locker{ - storage: storage, - lockingDisbaled: lockingDisbaled, - } -} - -func (l *Locker) CheckLock() error { - return l.storage.CheckLock() -} - -func (l *Locker) Lock() error { - if l.lockingDisbaled { - return nil - } - return l.storage.StoreLockInfo() +type Manager struct { + locker Locker } -func (l *Locker) Unlock() error { - if l.lockingDisbaled { - return nil - } - return l.storage.RemoveLockInfo() +func NewManager(locker Locker) *Manager { + return &Manager{locker: locker} } -func (l *Locker) ForceUnlock() error { - return l.storage.ForceRemoveLockInfo() +func (m *Manager) Acquire(lockName string) error { + _, _, err := m.locker.Acquire(lockName, lockgate.AcquireOptions{}) + return err } diff --git a/internal/storage/local/local.go b/internal/storage/local/local.go index ecb173b..4424ac0 100644 --- a/internal/storage/local/local.go +++ b/internal/storage/local/local.go @@ -18,8 +18,7 @@ const ( ) type Local struct { - path string - lockFile *os.File + path string } func NewLocalStorage(repoUrl string) *Local { diff --git a/internal/storage/local/lock.go b/internal/storage/local/lock.go deleted file mode 100644 index aee5bee..0000000 --- a/internal/storage/local/lock.go +++ /dev/null @@ -1,126 +0,0 @@ -package storage - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "os/user" - "path/filepath" - "time" - - "trx/internal/lock" -) - -const ( - lockFileName = ".lock" -) - -type LockFileInfo struct { - User string `json:"user"` - CreatedAt string `json:"created_at"` -} - -func (s *Local) CheckLock() error { - filePath := lockfilePath(s.path) - - _, err := os.Stat(filePath) - if err == nil { - lockInfo, readErr := readLockFile(filePath) - if readErr != nil { - return fmt.Errorf("error reading lock file: %w", readErr) - } - return &lock.ErrLocked{User: lockInfo.User, CreatedAt: lockInfo.CreatedAt} - } else if errors.Is(err, os.ErrNotExist) { - return nil - } - return fmt.Errorf("error checking lock file: %w", err) -} - -func (s *Local) StoreLockInfo() error { - filePath := lockfilePath(s.path) - f, err := createLockFile(filePath) - if err != nil { - return fmt.Errorf("error creating lock file: %w", err) - } - s.lockFile = f - return nil -} - -func (s *Local) RemoveLockInfo() error { - if s.lockFile == nil { - return nil - } - s.lockFile.Close() - return os.Remove(s.lockFile.Name()) -} - -func (s *Local) ForceRemoveLockInfo() error { - f, err := tryGetLockFile(s.path) - if err != nil { - return err - } - f.Close() - return os.Remove(f.Name()) -} - -func lockfilePath(s string) string { - return filepath.Join(s, lockFileName) -} - -func createLockFile(path string) (*os.File, error) { - usr, err := user.Current() - if err != nil { - return nil, fmt.Errorf("failed to get current user: %w", err) - } - - lockInfo := LockFileInfo{ - User: usr.Username, - CreatedAt: time.Now().Format(time.RFC3339), - } - - data, err := json.Marshal(lockInfo) - if err != nil { - return nil, fmt.Errorf("failed to marshal lock info: %w", err) - } - - if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { - return nil, fmt.Errorf("failed to create lock file directory: %w", err) - } - - file, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o644) - if err != nil { - return nil, fmt.Errorf("failed to create lock file: %w", err) - } - - _, writeErr := file.Write(data) - if writeErr != nil { - file.Close() - os.Remove(path) - return nil, fmt.Errorf("failed to write lock file: %w", writeErr) - } - - return file, nil -} - -func readLockFile(path string) (*LockFileInfo, error) { - data, err := os.ReadFile(path) - if err != nil { - return nil, err - } - - var lockInfo LockFileInfo - if err := json.Unmarshal(data, &lockInfo); err != nil { - return nil, fmt.Errorf("failed to unmarshal lock file: %w", err) - } - - return &lockInfo, nil -} - -func tryGetLockFile(path string) (*os.File, error) { - file, err := os.Open(lockfilePath(path)) - if err != nil { - return nil, fmt.Errorf("failed to open lock file: %w", err) - } - return file, nil -} diff --git a/internal/storage/storage.go b/internal/storage/storage.go index b3995df..beb3bb1 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -8,10 +8,6 @@ import ( type Storage interface { CheckLastSucceedTag() (string, error) StoreSucceedTag(commit string) error - StoreLockInfo() error - RemoveLockInfo() error - CheckLock() error - ForceRemoveLockInfo() error } type StorageService struct { @@ -39,19 +35,3 @@ func (s *StorageService) CheckLastSucceedTag() (string, error) { func (s *StorageService) StoreSucceedTag(commit string) error { return s.storage.StoreSucceedTag(commit) } - -func (s *StorageService) StoreLockInfo() error { - return s.storage.StoreLockInfo() -} - -func (s *StorageService) RemoveLockInfo() error { - return s.storage.RemoveLockInfo() -} - -func (s *StorageService) CheckLock() error { - return s.storage.CheckLock() -} - -func (s *StorageService) ForceRemoveLockInfo() error { - return s.storage.ForceRemoveLockInfo() -}