7 Commits

Author SHA1 Message Date
Massimo Lusetti
a6aa7ff81a Merge 92216a10ba into 2513a698f3 2024-12-01 13:16:58 -08:00
Michael Eischer
2513a698f3 Merge pull request #302 from restic/dependabot/go_modules/golang.org/x/crypto-0.27.0
Some checks failed
test / Go ${{ matrix.go }} (1.18.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.19.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.20.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.21.x) (push) Has been cancelled
test / lint (push) Has been cancelled
Bump golang.org/x/crypto from 0.25.0 to 0.27.0
2024-12-01 17:59:35 +01:00
Massimo Lusetti
92216a10ba Add group-accessible-repos option
The group-accessible-repos option will let filesystem group id
be able to access files and dir within the restic repo
Default stick with old behaviour to be owner restricted
While here make dirMode and fileMode within Options struct
private
2024-11-02 11:08:29 +01:00
dependabot[bot]
bdfb047edf Bump golang.org/x/crypto from 0.25.0 to 0.27.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.27.0.
- [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 19:18:23 +00:00
Michael Eischer
e35c6e39d9 Merge pull request #295 from restic/append-only-status
Some checks failed
test / Go ${{ matrix.go }} (1.18.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.19.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.20.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.21.x) (push) Has been cancelled
test / lint (push) Has been cancelled
Output status of append only mode on startup
2024-07-29 19:36:59 +02:00
Leo R. Lundgren
da5bb66030 Output status of append only mode on startup 2024-07-29 01:20:10 +02:00
Alexander Neumann
664d997006 Fix goreleaser config
Some checks failed
test / Go ${{ matrix.go }} (1.18.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.19.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.20.x) (push) Has been cancelled
test / Go ${{ matrix.go }} (1.21.x) (push) Has been cancelled
test / lint (push) Has been cancelled
2024-07-26 14:55:06 +02:00
7 changed files with 82 additions and 47 deletions

View File

@@ -79,13 +79,13 @@ archives:
# add these files to all archives
files:
- src: LICENSE
dst: .
dst: LICENSE
info: *archive_file_info
- src: README.md
dst: .
dst: README.md
info: *archive_file_info
- src: CHANGELOG.md
dst: .
dst: CHANGELOG.md
info: *archive_file_info
# also build an archive of the source code

View File

@@ -0,0 +1,5 @@
Enhancement: Output status of append only mode on startup
Rest-server now outputs whether append only mode has been enabled on startup.
https://github.com/restic/rest-server/pull/295

View File

@@ -69,6 +69,7 @@ func newRestServerApp() *restServerApp {
flags.BoolVar(&rv.Server.PrivateRepos, "private-repos", rv.Server.PrivateRepos, "users can only access their private repo")
flags.BoolVar(&rv.Server.Prometheus, "prometheus", rv.Server.Prometheus, "enable Prometheus metrics")
flags.BoolVar(&rv.Server.PrometheusNoAuth, "prometheus-no-auth", rv.Server.PrometheusNoAuth, "disable auth for Prometheus /metrics endpoint")
flags.BoolVar(&rv.Server.GroupAccessibleRepos, "group-accessible-repos", rv.Server.GroupAccessibleRepos, "let filesystem group be able to read repo files")
return rv
}
@@ -135,12 +136,24 @@ func (app *restServerApp) runRoot(cmd *cobra.Command, args []string) error {
log.Fatalf("error: %v", err)
}
if app.Server.AppendOnly {
log.Println("Append only mode enabled")
} else {
log.Println("Append only mode disabled")
}
if app.Server.PrivateRepos {
log.Println("Private repositories enabled")
} else {
log.Println("Private repositories disabled")
}
if app.Server.GroupAccessibleRepos {
log.Println("Group accessible repos enabled")
} else {
log.Println("Group accessible repos disabled")
}
enabledTLS, privateKey, publicKey, err := app.tlsSettings()
if err != nil {
return err

4
go.mod
View File

@@ -9,7 +9,7 @@ require (
github.com/miolini/datacounter v1.0.3
github.com/prometheus/client_golang v1.18.0
github.com/spf13/cobra v1.8.1
golang.org/x/crypto v0.25.0
golang.org/x/crypto v0.27.0
)
require (
@@ -23,6 +23,6 @@ require (
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sys v0.25.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)

8
go.sum
View File

@@ -35,11 +35,11 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -15,23 +15,24 @@ import (
// Server encapsulates the rest-server's settings and repo management logic
type Server struct {
Path string
HtpasswdPath string
Listen string
Log string
CPUProfile string
TLSKey string
TLSCert string
TLS bool
NoAuth bool
AppendOnly bool
PrivateRepos bool
Prometheus bool
PrometheusNoAuth bool
Debug bool
MaxRepoSize int64
PanicOnError bool
NoVerifyUpload bool
Path string
HtpasswdPath string
Listen string
Log string
CPUProfile string
TLSKey string
TLSCert string
TLS bool
NoAuth bool
AppendOnly bool
PrivateRepos bool
Prometheus bool
PrometheusNoAuth bool
Debug bool
MaxRepoSize int64
PanicOnError bool
NoVerifyUpload bool
GroupAccessibleRepos bool
htpasswdFile *HtpasswdFile
quotaManager *quota.Manager
@@ -88,12 +89,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Pass the request to the repo.Handler
opt := repo.Options{
AppendOnly: s.AppendOnly,
Debug: s.Debug,
QuotaManager: s.quotaManager, // may be nil
PanicOnError: s.PanicOnError,
NoVerifyUpload: s.NoVerifyUpload,
FsyncWarning: &s.fsyncWarning,
AppendOnly: s.AppendOnly,
Debug: s.Debug,
QuotaManager: s.quotaManager, // may be nil
PanicOnError: s.PanicOnError,
NoVerifyUpload: s.NoVerifyUpload,
FsyncWarning: &s.fsyncWarning,
GroupAccessible: s.GroupAccessibleRepos,
}
if s.Prometheus {
opt.BlobMetricFunc = makeBlobMetricFunc(username, folderPath)
@@ -158,7 +160,8 @@ func join(base string, names ...string) (string, error) {
// splitURLPath splits the URL path into a folderPath of the subrepo, and
// a remainder that can be passed to repo.Handler.
// Example: /foo/bar/locks/0123... will be split into:
// ["foo", "bar"] and "/locks/0123..."
//
// ["foo", "bar"] and "/locks/0123..."
func splitURLPath(urlPath string, maxDepth int) (folderPath []string, remainder string) {
if !strings.HasPrefix(urlPath, "/") {
// Really should start with "/"

View File

@@ -29,8 +29,6 @@ import (
type Options struct {
AppendOnly bool // if set, delete actions are not allowed
Debug bool
DirMode os.FileMode
FileMode os.FileMode
NoVerifyUpload bool
// If set, we will panic when an internal server error happens. This
@@ -40,6 +38,13 @@ type Options struct {
BlobMetricFunc BlobMetricFunc
QuotaManager *quota.Manager
FsyncWarning *sync.Once
// If set makes files group accessible
GroupAccessible bool
// Defaults dir and file mode
dirMode os.FileMode
fileMode os.FileMode
}
// DefaultDirMode is the file mode used for directory creation if not
@@ -50,6 +55,12 @@ const DefaultDirMode os.FileMode = 0700
// overridden in the Options
const DefaultFileMode os.FileMode = 0600
// File mode used for directory creation when group access is enabled
const GroupAccessibleDirMode os.FileMode = 0770
// File mode used for file creation when group access is enabled
const GroupAccessibleFileMode os.FileMode = 0660
// New creates a new Handler for a single Restic backup repo.
// path is the full filesystem path to this repo directory.
// opt is a set of options.
@@ -57,12 +68,15 @@ func New(path string, opt Options) (*Handler, error) {
if path == "" {
return nil, fmt.Errorf("path is required")
}
if opt.DirMode == 0 {
opt.DirMode = DefaultDirMode
}
if opt.FileMode == 0 {
opt.FileMode = DefaultFileMode
opt.dirMode = DefaultDirMode
opt.fileMode = DefaultFileMode
if opt.GroupAccessible {
opt.dirMode = GroupAccessibleDirMode
opt.fileMode = GroupAccessibleFileMode
}
h := Handler{
path: path,
opt: opt,
@@ -289,7 +303,7 @@ func (h *Handler) saveConfig(w http.ResponseWriter, r *http.Request) {
}
cfg := h.getSubPath("config")
f, err := os.OpenFile(cfg, os.O_CREATE|os.O_WRONLY|os.O_EXCL, h.opt.FileMode)
f, err := os.OpenFile(cfg, os.O_CREATE|os.O_WRONLY|os.O_EXCL, h.opt.fileMode)
if err != nil && os.IsExist(err) {
if h.opt.Debug {
log.Print(err)
@@ -545,15 +559,15 @@ func (h *Handler) saveBlob(w http.ResponseWriter, r *http.Request) {
}
tmpFn := filepath.Join(filepath.Dir(path), objectID+".rest-server-temp")
tf, err := tempFile(tmpFn, h.opt.FileMode)
tf, err := tempFile(tmpFn, h.opt.fileMode)
if os.IsNotExist(err) {
// the error is caused by a missing directory, create it and retry
mkdirErr := os.MkdirAll(filepath.Dir(path), h.opt.DirMode)
mkdirErr := os.MkdirAll(filepath.Dir(path), h.opt.dirMode)
if mkdirErr != nil {
log.Print(mkdirErr)
} else {
// try again
tf, err = tempFile(tmpFn, h.opt.FileMode)
tf, err = tempFile(tmpFn, h.opt.fileMode)
}
}
if err != nil {
@@ -750,13 +764,13 @@ func (h *Handler) createRepo(w http.ResponseWriter, r *http.Request) {
log.Printf("Creating repository directories in %s\n", h.path)
if err := os.MkdirAll(h.path, h.opt.DirMode); err != nil {
if err := os.MkdirAll(h.path, h.opt.dirMode); err != nil {
h.internalServerError(w, err)
return
}
for _, d := range ObjectTypes {
if err := os.Mkdir(filepath.Join(h.path, d), h.opt.DirMode); err != nil && !os.IsExist(err) {
if err := os.Mkdir(filepath.Join(h.path, d), h.opt.dirMode); err != nil && !os.IsExist(err) {
h.internalServerError(w, err)
return
}
@@ -764,7 +778,7 @@ func (h *Handler) createRepo(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 256; i++ {
dirPath := filepath.Join(h.path, "data", fmt.Sprintf("%02x", i))
if err := os.Mkdir(dirPath, h.opt.DirMode); err != nil && !os.IsExist(err) {
if err := os.Mkdir(dirPath, h.opt.dirMode); err != nil && !os.IsExist(err) {
h.internalServerError(w, err)
return
}