-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Kopia storage helpers #2655
Changes from 28 commits
680e782
72011e7
0f635ad
d0a6dd1
ca853c1
9850f4a
246e1c1
419652c
24707e5
c029fc1
cff7220
550d124
fc918a0
9530c91
75fb036
9fdf94b
2c6cb6e
1a3ee2d
386e7e9
b815f63
bcafabb
6d61bb4
e6ddb8f
4e7ffd7
f16aea7
dcd6425
d3dfb31
d2ac987
b093421
6e71143
de3a52b
722b279
44c133e
1897a1e
33b1342
83292af
516a14c
cd03d1e
8cf36c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package args | ||
|
||
// Cache provides the cache arguments for Kopia CLI. | ||
type Cache struct { | ||
CacheDirectory string // the directory where cache is stored. Default is "/tmp/kopia-cache". | ||
ContentCacheSizeLimitMB int // the maximum size of the content cache in MB. | ||
MetadataCacheSizeLimitMB int // the maximum size of the metadata cache in MB. | ||
|
||
// unused? | ||
ContentCacheSizeMB int // the size of the content cache in MB. | ||
MetadataCacheSizeMB int // the size of the metadata cache in MB. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package args | ||
|
||
// Common provides the common arguments for Kopia CLI. | ||
type Common struct { | ||
ConfigFilePath string // the path to the config file. | ||
LogDirectory string // the directory where logs are stored. | ||
LogLevel string // the level of logging. Default is "error". | ||
RepoPassword string // the password for the repository. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package cli | ||
|
||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
import ( | ||
_ "github.com/kanisterio/safecli" | ||
) | ||
|
||
// This package contains the implementation of the Kopia CLI using github.com/kanisterio/safecli. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package cli | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// Common errors | ||
var ( | ||
// ErrInvalidID is returned when the ID is empty. | ||
ErrInvalidID = errors.New("invalid ID") | ||
) | ||
|
||
// storage errors | ||
var ( | ||
// ErrUnsupportedStorage is returned when the storage is not supported. | ||
ErrUnsupportedStorage = errors.New("unsupported storage") | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package args | ||
|
||
import ( | ||
"github.com/kanisterio/kanister/pkg/kopia/cli" | ||
"github.com/kanisterio/safecli/command" | ||
) | ||
|
||
// ID creates a new ID argument. | ||
func ID(id string) command.Applier { | ||
if id == "" { | ||
return command.NewErrorArgument(cli.ErrInvalidID) | ||
} | ||
return command.NewArgument(id) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package args_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/kanisterio/kanister/pkg/kopia/cli" | ||
"github.com/kanisterio/kanister/pkg/kopia/cli/internal/args" | ||
"github.com/kanisterio/safecli/test" | ||
"gopkg.in/check.v1" | ||
) | ||
|
||
func TestArgs(t *testing.T) { check.TestingT(t) } | ||
|
||
var _ = check.Suite(&test.ArgumentSuite{Cmd: "cmd", Arguments: []test.ArgumentTest{ | ||
{ | ||
Name: "Invalid ID", | ||
Argument: args.ID(""), | ||
ExpectedErr: cli.ErrInvalidID, | ||
}, | ||
{ | ||
Name: "ID", | ||
Argument: args.ID("id12345"), | ||
ExpectedCLI: []string{"cmd", "id12345"}, | ||
}, | ||
}}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package internal | ||
|
||
import ( | ||
"strconv" | ||
"strings" | ||
|
||
rs "github.com/kanisterio/kanister/pkg/secrets/repositoryserver" | ||
) | ||
|
||
// Location is a map of key-value pairs that represent different storage properties. | ||
type Location map[string][]byte | ||
|
||
// Type returns the location type. | ||
func (l Location) Type() rs.LocType { | ||
return rs.LocType(string(l[rs.TypeKey])) | ||
} | ||
|
||
// Region returns the location region. | ||
func (l Location) Region() string { | ||
return string(l[rs.RegionKey]) | ||
} | ||
|
||
// BucketName returns the location bucket name. | ||
func (l Location) BucketName() string { | ||
return string(l[rs.BucketKey]) | ||
} | ||
|
||
// Endpoint returns the location endpoint. | ||
func (l Location) Endpoint() string { | ||
return string(l[rs.EndpointKey]) | ||
} | ||
|
||
// Prefix returns the location prefix. | ||
func (l Location) Prefix() string { | ||
return string(l[rs.PrefixKey]) | ||
} | ||
|
||
// IsInsecureEndpoint returns true if the location endpoint is insecure/http. | ||
func (l Location) IsInsecureEndpoint() bool { | ||
return strings.HasPrefix(l.Endpoint(), "http:") | ||
} | ||
|
||
// HasSkipSSLVerify returns true if the location has skip SSL verification. | ||
func (l Location) HasSkipSSLVerify() bool { | ||
v, _ := strconv.ParseBool(string(l[rs.SkipSSLVerifyKey])) | ||
return v | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package internal_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/kanisterio/kanister/pkg/kopia/cli/internal" | ||
rs "github.com/kanisterio/kanister/pkg/secrets/repositoryserver" | ||
"gopkg.in/check.v1" | ||
plar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
func TestLocation(t *testing.T) { check.TestingT(t) } | ||
|
||
type LocationSuite struct{} | ||
|
||
var _ = check.Suite(&LocationSuite{}) | ||
|
||
func (s *LocationSuite) TestLocation(c *check.C) { | ||
type expected struct { | ||
Type rs.LocType | ||
Region string | ||
BucketName string | ||
Endpoint string | ||
Prefix string | ||
IsInsecure bool | ||
HasSkipSSLVerify bool | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
location internal.Location | ||
expected expected | ||
}{ | ||
{ | ||
name: "Test with no fields", | ||
location: internal.Location{}, | ||
expected: expected{}, | ||
}, | ||
{ | ||
name: "Test with all fields", | ||
location: internal.Location{ | ||
rs.TypeKey: []byte("Type1"), | ||
rs.RegionKey: []byte("Region1"), | ||
rs.BucketKey: []byte("Bucket1"), | ||
rs.EndpointKey: []byte("http://Endpoint1"), | ||
rs.PrefixKey: []byte("Prefix1"), | ||
rs.SkipSSLVerifyKey: []byte("true"), | ||
}, | ||
expected: expected{ | ||
Type: "Type1", | ||
Region: "Region1", | ||
BucketName: "Bucket1", | ||
Endpoint: "http://Endpoint1", | ||
Prefix: "Prefix1", | ||
IsInsecure: true, | ||
HasSkipSSLVerify: true, | ||
}, | ||
}, | ||
} | ||
for _, test := range tests { | ||
c.Check(test.location.Type(), check.Equals, test.expected.Type) | ||
c.Check(test.location.Region(), check.Equals, test.expected.Region) | ||
c.Check(test.location.BucketName(), check.Equals, test.expected.BucketName) | ||
c.Check(test.location.Endpoint(), check.Equals, test.expected.Endpoint) | ||
c.Check(test.location.Prefix(), check.Equals, test.expected.Prefix) | ||
c.Check(test.location.IsInsecureEndpoint(), check.Equals, test.expected.IsInsecure) | ||
c.Check(test.location.HasSkipSSLVerify(), check.Equals, test.expected.HasSkipSSLVerify) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2024 The Kanister Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package storage | ||
|
||
import ( | ||
"context" | ||
"io" | ||
|
||
"github.com/kanisterio/kanister/pkg/field" | ||
"github.com/kanisterio/kanister/pkg/log" | ||
) | ||
|
||
// NopLogger is a logger that does nothing. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This Nop logger is used inside s3 storage as a default logger if no logger is provided. You don't need to write something like below:
and can simply use:
|
||
// TODO: Move to log package | ||
hairyhum marked this conversation as resolved.
Show resolved
Hide resolved
|
||
type NopLogger struct{} | ||
|
||
// Print does nothing. | ||
func (NopLogger) Print(msg string, fields ...field.M) { | ||
} | ||
|
||
// PrintTo does nothing. | ||
func (NopLogger) PrintTo(w io.Writer, msg string, fields ...field.M) { | ||
} | ||
|
||
// WithContext does nothing. | ||
func (NopLogger) WithContext(ctx context.Context) log.Logger { | ||
return &NopLogger{} | ||
} | ||
|
||
// WithError does nothing. | ||
func (NopLogger) WithError(err error) log.Logger { | ||
return &NopLogger{} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we handle error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented the same logic as it is in the current implementation:
strconv.ParseBool
returnsfalse
in the case of error.