2021-11-15 18:01:48 +00:00
|
|
|
//go:build darwin || linux
|
|
|
|
// +build darwin linux
|
|
|
|
|
2021-08-09 17:31:04 +00:00
|
|
|
package eefleetctl
|
|
|
|
|
|
|
|
import (
|
2022-03-15 19:04:12 +00:00
|
|
|
"archive/tar"
|
|
|
|
"compress/gzip"
|
2021-08-09 17:31:04 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-03-15 19:04:12 +00:00
|
|
|
"io"
|
2021-08-09 17:31:04 +00:00
|
|
|
"io/ioutil"
|
2021-11-15 18:01:48 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2021-08-09 17:31:04 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
2021-11-15 18:01:48 +00:00
|
|
|
"time"
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2022-03-15 19:04:12 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/orbit/pkg/constant"
|
2021-11-15 18:01:48 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/orbit/pkg/update"
|
|
|
|
"github.com/fleetdm/fleet/v4/orbit/pkg/update/filestore"
|
2022-03-15 19:04:12 +00:00
|
|
|
"github.com/fleetdm/fleet/v4/pkg/secure"
|
2021-08-09 17:31:04 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPassphraseHandlerEnvironment(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
testCases := []struct {
|
|
|
|
role string
|
|
|
|
passphrase string
|
|
|
|
}{
|
|
|
|
{role: "root", passphrase: "rootpassphrase"},
|
|
|
|
{role: "timestamp", passphrase: "timestamp5#$#@"},
|
|
|
|
{role: "snapshot", passphrase: "snapshot$#@"},
|
|
|
|
{role: "targets", passphrase: "$#^#$@targets"},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range testCases {
|
|
|
|
t.Run(tt.role, func(t *testing.T) {
|
|
|
|
tt := tt
|
|
|
|
|
|
|
|
handler := newPassphraseHandler()
|
|
|
|
envKey := fmt.Sprintf("FLEET_%s_PASSPHRASE", strings.ToUpper(tt.role))
|
2022-07-18 17:22:28 +00:00
|
|
|
t.Setenv(envKey, tt.passphrase)
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2022-02-10 16:16:36 +00:00
|
|
|
passphrase, err := handler.getPassphrase(tt.role, false, false)
|
2021-08-09 17:31:04 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.passphrase, string(passphrase))
|
|
|
|
|
|
|
|
// Should work second time with cache
|
2022-02-10 16:16:36 +00:00
|
|
|
passphrase, err = handler.getPassphrase(tt.role, false, false)
|
2021-08-09 17:31:04 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.passphrase, string(passphrase))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPassphraseHandlerEmpty(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
handler := newPassphraseHandler()
|
2022-07-18 17:22:28 +00:00
|
|
|
t.Setenv("FLEET_ROOT_PASSPHRASE", "")
|
2022-02-10 16:16:36 +00:00
|
|
|
_, err := handler.getPassphrase("root", false, false)
|
2021-08-09 17:31:04 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func setPassphrases(t *testing.T) {
|
|
|
|
t.Helper()
|
2022-07-18 17:22:28 +00:00
|
|
|
t.Setenv("FLEET_ROOT_PASSPHRASE", "root")
|
|
|
|
t.Setenv("FLEET_TIMESTAMP_PASSPHRASE", "timestamp")
|
|
|
|
t.Setenv("FLEET_TARGETS_PASSPHRASE", "targets")
|
|
|
|
t.Setenv("FLEET_SNAPSHOT_PASSPHRASE", "snapshot")
|
2021-08-09 17:31:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func runUpdatesCommand(args ...string) error {
|
|
|
|
app := cli.NewApp()
|
|
|
|
app.Commands = []*cli.Command{UpdatesCommand()}
|
|
|
|
return app.Run(append([]string{os.Args[0], "updates"}, args...))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpdatesInit(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
|
|
|
|
// Should fail with already initialized
|
|
|
|
require.Error(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
}
|
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
func TestUpdatesErrorInvalidPassphrase(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
|
|
|
|
// Should not be able to add with invalid passphrase
|
2022-07-18 17:22:28 +00:00
|
|
|
t.Setenv("FLEET_SNAPSHOT_PASSPHRASE", "invalid")
|
2021-11-15 18:01:48 +00:00
|
|
|
// Reset the cache that already has correct passwords stored
|
|
|
|
passHandler = newPassphraseHandler()
|
|
|
|
require.Error(t, runUpdatesCommand("add", "--path", tmpDir, "--target", "anything", "--platform", "windows", "--name", "test", "--version", "1.3.4.7"))
|
|
|
|
}
|
|
|
|
|
2021-08-09 17:31:04 +00:00
|
|
|
func TestUpdatesInitKeysInitializedError(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
// Create an empty "keys" directory
|
|
|
|
require.NoError(t, os.Mkdir(filepath.Join(tmpDir, "keys"), os.ModePerm|os.ModeDir))
|
|
|
|
// Should fail with already initialized
|
|
|
|
require.Error(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
}
|
|
|
|
|
|
|
|
func assertFileExists(t *testing.T, path string) {
|
|
|
|
t.Helper()
|
|
|
|
st, err := os.Stat(path)
|
|
|
|
require.NoError(t, err, "stat should succeed")
|
|
|
|
assert.True(t, st.Mode().IsRegular(), "should be regular file: %s", path)
|
|
|
|
}
|
|
|
|
|
2022-05-26 23:44:49 +00:00
|
|
|
func assertVersion(t *testing.T, expected int64, versionFunc func() (int64, error)) {
|
2021-11-15 18:01:48 +00:00
|
|
|
t.Helper()
|
|
|
|
actual, err := versionFunc()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, expected, actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Capture stdout while running the updates roots command
|
|
|
|
func getRoots(t *testing.T, tmpDir string) string {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
stdout := os.Stdout
|
|
|
|
defer func() { os.Stdout = stdout }()
|
|
|
|
|
|
|
|
r, w, err := os.Pipe()
|
|
|
|
require.NoError(t, err)
|
|
|
|
os.Stdout = w
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("roots", "--path", tmpDir))
|
|
|
|
require.NoError(t, w.Close())
|
|
|
|
|
|
|
|
out, err := ioutil.ReadAll(r)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-10-07 20:03:39 +00:00
|
|
|
// Check output contains the root.json
|
|
|
|
var keys map[string]interface{}
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, json.Unmarshal(out, &keys))
|
2022-10-07 20:03:39 +00:00
|
|
|
signed_ := keys["signed"]
|
|
|
|
require.NotNil(t, signed_)
|
|
|
|
signed, ok := signed_.(map[string]interface{})
|
|
|
|
require.True(t, ok)
|
|
|
|
keys_ := signed["keys"]
|
|
|
|
require.NotNil(t, keys_)
|
|
|
|
require.NotEmpty(t, signed["keys"])
|
|
|
|
keys, ok = keys_.(map[string]interface{})
|
|
|
|
require.True(t, ok)
|
|
|
|
require.NotEmpty(t, keys)
|
|
|
|
// Get first key (map key is the identifier of the key).
|
|
|
|
var key map[string]interface{}
|
|
|
|
for _, key_ := range keys {
|
|
|
|
key, ok = key_.(map[string]interface{})
|
|
|
|
require.True(t, ok)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
require.NotEmpty(t, key)
|
|
|
|
require.Equal(t, "ed25519", key["scheme"])
|
|
|
|
require.Equal(t, "ed25519", key["keytype"])
|
|
|
|
keyval_, ok := key["keyval"].(map[string]interface{})
|
|
|
|
require.True(t, ok)
|
|
|
|
require.NotEmpty(t, keyval_["public"]) // keyval_["public"] contains the public key.
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
return string(out)
|
|
|
|
}
|
|
|
|
|
2022-03-15 19:04:12 +00:00
|
|
|
func compressSingleFile(t *testing.T, filePath, outFilePath string) {
|
|
|
|
outf, err := secure.OpenFile(outFilePath, os.O_CREATE|os.O_WRONLY, constant.DefaultFileMode)
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer outf.Close()
|
|
|
|
gw := gzip.NewWriter(outf)
|
|
|
|
defer gw.Close()
|
|
|
|
tw := tar.NewWriter(gw)
|
|
|
|
defer tw.Close()
|
|
|
|
inf, err := os.Open(filePath)
|
|
|
|
require.NoError(t, err)
|
|
|
|
infi, err := inf.Stat()
|
|
|
|
require.NoError(t, err)
|
|
|
|
err = tw.WriteHeader(
|
|
|
|
&tar.Header{
|
|
|
|
Name: filepath.Base(filePath),
|
|
|
|
Size: infi.Size(),
|
|
|
|
Mode: 0o777,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
_, err = io.Copy(tw, inf)
|
|
|
|
require.NoError(t, err)
|
|
|
|
err = tw.Close()
|
|
|
|
require.NoError(t, err)
|
|
|
|
err = gw.Close()
|
|
|
|
require.NoError(t, err)
|
|
|
|
err = outf.Close()
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2021-08-09 17:31:04 +00:00
|
|
|
func TestUpdatesIntegration(t *testing.T) {
|
|
|
|
// Not t.Parallel() due to modifications to environment.
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
// Run an HTTP server to serve the update metadata
|
|
|
|
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Join(tmpDir, "repository"))))
|
2022-03-15 19:04:12 +00:00
|
|
|
t.Cleanup(server.Close)
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
roots := getRoots(t, tmpDir)
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2022-03-15 19:04:12 +00:00
|
|
|
// Use the current binary as target for this test so that it is a binary that
|
|
|
|
// is valid for execution on the current system.
|
|
|
|
testPath, err := os.Executable()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
tarGzFilePath := filepath.Join(filepath.Dir(testPath), "other.app.tar.gz")
|
|
|
|
compressSingleFile(t, testPath, tarGzFilePath)
|
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
// Initialize an update client
|
|
|
|
localStore, err := filestore.New(filepath.Join(tmpDir, "tuf-metadata.json"))
|
|
|
|
require.NoError(t, err)
|
2022-06-01 17:47:04 +00:00
|
|
|
updater, err := update.NewUpdater(update.Options{
|
2022-03-15 19:04:12 +00:00
|
|
|
RootDirectory: tmpDir,
|
|
|
|
ServerURL: server.URL,
|
|
|
|
RootKeys: roots,
|
|
|
|
LocalStore: localStore,
|
|
|
|
Targets: update.Targets{
|
|
|
|
"test": update.TargetInfo{
|
|
|
|
Platform: "macos",
|
|
|
|
Channel: "1.3.3.7",
|
|
|
|
TargetFile: "test",
|
|
|
|
},
|
|
|
|
"other": update.TargetInfo{
|
|
|
|
Platform: "macos-app",
|
|
|
|
Channel: "1.3.3.8",
|
|
|
|
TargetFile: "other.app.tar.gz",
|
|
|
|
ExtractedExecSubPath: []string{filepath.Base(testPath)},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-15 19:04:12 +00:00
|
|
|
require.NoError(t, updater.UpdateMetadata())
|
|
|
|
_, err = updater.Lookup("any")
|
2021-11-15 18:01:48 +00:00
|
|
|
require.Error(t, err, "lookup should fail before targets added")
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
repo, err := openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 1, repo.RootVersion)
|
|
|
|
assertVersion(t, 1, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 1, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 1, repo.TimestampVersion)
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
// Add some targets
|
2021-08-09 17:31:04 +00:00
|
|
|
require.NoError(t, runUpdatesCommand("add", "--path", tmpDir, "--target", testPath, "--platform", "linux", "--name", "test", "--version", "1.3.3.7"))
|
|
|
|
require.NoError(t, runUpdatesCommand("add", "--path", tmpDir, "--target", testPath, "--platform", "macos", "--name", "test", "--version", "1.3.3.7"))
|
|
|
|
require.NoError(t, runUpdatesCommand("add", "--path", tmpDir, "--target", testPath, "--platform", "windows", "--name", "test", "--version", "1.3.3.7"))
|
2022-03-15 19:04:12 +00:00
|
|
|
require.NoError(t, runUpdatesCommand("add", "--path", tmpDir, "--target", tarGzFilePath, "--platform", "macos-app", "--name", "other", "--version", "1.3.3.8"))
|
2021-08-09 17:31:04 +00:00
|
|
|
assertFileExists(t, filepath.Join(tmpDir, "repository", "targets", "test", "linux", "1.3.3.7", "test"))
|
|
|
|
assertFileExists(t, filepath.Join(tmpDir, "repository", "targets", "test", "macos", "1.3.3.7", "test"))
|
|
|
|
assertFileExists(t, filepath.Join(tmpDir, "repository", "targets", "test", "windows", "1.3.3.7", "test"))
|
2022-03-15 19:04:12 +00:00
|
|
|
assertFileExists(t, filepath.Join(tmpDir, "repository", "targets", "other", "macos-app", "1.3.3.8", "other.app.tar.gz"))
|
2021-08-09 17:31:04 +00:00
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
// Verify the client can look up and download the updates
|
2022-03-15 19:04:12 +00:00
|
|
|
require.NoError(t, updater.UpdateMetadata())
|
|
|
|
targets, err := updater.Targets()
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-15 19:04:12 +00:00
|
|
|
assert.Len(t, targets, 4)
|
|
|
|
_, err = updater.Get("test")
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-15 19:04:12 +00:00
|
|
|
other, err := updater.Get("other")
|
|
|
|
require.NoError(t, err)
|
2022-03-21 17:53:53 +00:00
|
|
|
require.Equal(t, filepath.Base(other.ExecPath), filepath.Base(testPath))
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 1, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 5, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 5, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 5, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
2021-08-09 17:31:04 +00:00
|
|
|
require.NoError(t, runUpdatesCommand("timestamp", "--path", tmpDir))
|
|
|
|
|
2021-11-15 18:01:48 +00:00
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 1, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 5, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 5, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 6, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
// Rotate root
|
|
|
|
require.NoError(t, runUpdatesCommand("rotate", "--path", tmpDir, "root"))
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 2, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 6, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 6, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 7, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
// Rotate targets
|
|
|
|
require.NoError(t, runUpdatesCommand("rotate", "--path", tmpDir, "targets"))
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 3, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 7, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 7, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 8, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
// Rotate snapshot
|
|
|
|
require.NoError(t, runUpdatesCommand("rotate", "--path", tmpDir, "snapshot"))
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 4, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 8, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 8, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 9, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
// Rotate timestamp
|
|
|
|
require.NoError(t, runUpdatesCommand("rotate", "--path", tmpDir, "timestamp"))
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assertVersion(t, 5, repo.RootVersion)
|
2022-03-15 19:04:12 +00:00
|
|
|
assertVersion(t, 9, repo.TargetsVersion)
|
|
|
|
assertVersion(t, 9, repo.SnapshotVersion)
|
|
|
|
assertVersion(t, 10, repo.TimestampVersion)
|
2021-11-15 18:01:48 +00:00
|
|
|
|
|
|
|
// Should still be able to add after rotations
|
|
|
|
require.NoError(t, runUpdatesCommand("add", "--path", tmpDir, "--target", testPath, "--platform", "windows", "--name", "test", "--version", "1.3.3.7"))
|
|
|
|
|
|
|
|
// Root key should have changed
|
|
|
|
newRoots := getRoots(t, tmpDir)
|
|
|
|
assert.NotEqual(t, roots, newRoots)
|
|
|
|
|
|
|
|
// Should still be able to retrieve an update after rotations
|
2022-03-15 19:04:12 +00:00
|
|
|
require.NoError(t, updater.UpdateMetadata())
|
|
|
|
targets, err = updater.Targets()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, targets, 4)
|
|
|
|
// Remove the old test copy first
|
|
|
|
p, err := updater.ExecutableLocalPath("test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, os.RemoveAll(p))
|
|
|
|
_, err = updater.Get("test")
|
|
|
|
require.NoError(t, err)
|
|
|
|
// Remove the old other copy first
|
|
|
|
o, err := updater.Get("other")
|
|
|
|
require.NoError(t, err)
|
2022-03-21 17:53:53 +00:00
|
|
|
require.NoError(t, os.RemoveAll(filepath.Join(filepath.Dir(o.ExecPath), "other.app.tar.gz")))
|
|
|
|
require.NoError(t, os.RemoveAll(filepath.Join(filepath.Dir(o.ExecPath), filepath.Base(testPath))))
|
2022-03-15 19:04:12 +00:00
|
|
|
o2, err := updater.Get("other")
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-15 19:04:12 +00:00
|
|
|
require.Equal(t, o, o2)
|
2022-03-21 17:53:53 +00:00
|
|
|
_, err = os.Stat(o2.ExecPath)
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Update client should be able to initialize with new root
|
|
|
|
tmpDir = t.TempDir()
|
|
|
|
localStore, err = filestore.New(filepath.Join(tmpDir, "tuf-metadata.json"))
|
|
|
|
require.NoError(t, err)
|
2022-06-01 17:47:04 +00:00
|
|
|
updater, err = update.NewUpdater(update.Options{RootDirectory: tmpDir, ServerURL: server.URL, RootKeys: roots, LocalStore: localStore})
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-03-15 19:04:12 +00:00
|
|
|
require.NoError(t, updater.UpdateMetadata())
|
2021-11-15 18:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCommit(t *testing.T) {
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
|
|
|
|
initialEntries, err := os.ReadDir(filepath.Join(tmpDir, "repository"))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
initialRoots := getRoots(t, tmpDir)
|
|
|
|
|
2021-11-15 20:54:31 +00:00
|
|
|
commit, _, err := startRotatePseudoTx(tmpDir)
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
repo, err := openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Make rotations that change repo
|
|
|
|
require.NoError(t, updatesGenKey(repo, "root"))
|
|
|
|
require.NoError(t, repo.Sign("root.json"))
|
|
|
|
require.NoError(t, repo.SnapshotWithExpires(time.Now().Add(snapshotExpirationDuration)))
|
|
|
|
require.NoError(t, repo.TimestampWithExpires(time.Now().Add(timestampExpirationDuration)))
|
|
|
|
require.NoError(t, repo.Commit())
|
|
|
|
|
|
|
|
// Assert directory has changed after commit.
|
|
|
|
require.NoError(t, commit())
|
|
|
|
entries, err := os.ReadDir(filepath.Join(tmpDir, "repository"))
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.NotEqual(t, initialEntries, entries)
|
|
|
|
|
|
|
|
_, err = os.Stat(filepath.Join(tmpDir, "repository", ".backup"))
|
|
|
|
assert.True(t, os.IsNotExist(err))
|
|
|
|
|
|
|
|
// Roots should have changed.
|
|
|
|
roots := getRoots(t, tmpDir)
|
|
|
|
assert.NotEqual(t, initialRoots, roots)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRollback(t *testing.T) {
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
setPassphrases(t)
|
|
|
|
|
|
|
|
require.NoError(t, runUpdatesCommand("init", "--path", tmpDir))
|
|
|
|
|
|
|
|
initialEntries, err := os.ReadDir(filepath.Join(tmpDir, "repository"))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
initialRoots := getRoots(t, tmpDir)
|
|
|
|
|
2021-11-15 20:54:31 +00:00
|
|
|
_, rollback, err := startRotatePseudoTx(tmpDir)
|
2021-11-15 18:01:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
repo, err := openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Make rotations that change repo
|
|
|
|
require.NoError(t, updatesGenKey(repo, "root"))
|
|
|
|
require.NoError(t, repo.Sign("root.json"))
|
|
|
|
require.NoError(t, repo.SnapshotWithExpires(time.Now().Add(snapshotExpirationDuration)))
|
|
|
|
require.NoError(t, repo.TimestampWithExpires(time.Now().Add(timestampExpirationDuration)))
|
|
|
|
require.NoError(t, repo.Commit())
|
|
|
|
|
|
|
|
// Assert directory has NOT changed after rollback.
|
|
|
|
require.NoError(t, rollback())
|
|
|
|
entries, err := os.ReadDir(filepath.Join(tmpDir, "repository"))
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, initialEntries, entries)
|
|
|
|
|
|
|
|
_, err = os.Stat(filepath.Join(tmpDir, "repository", ".backup"))
|
|
|
|
assert.True(t, os.IsNotExist(err))
|
|
|
|
|
|
|
|
// Roots should NOT have changed.
|
|
|
|
repo, err = openRepo(tmpDir)
|
|
|
|
require.NoError(t, err)
|
|
|
|
roots := getRoots(t, tmpDir)
|
|
|
|
assert.Equal(t, initialRoots, roots)
|
2021-08-09 17:31:04 +00:00
|
|
|
}
|