summaryrefslogtreecommitdiff
path: root/pkg/siftool
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/siftool')
-rw-r--r--pkg/siftool/add.go65
-rw-r--r--pkg/siftool/add_test.go4
-rw-r--r--pkg/siftool/del_test.go4
-rw-r--r--pkg/siftool/dump_test.go4
-rw-r--r--pkg/siftool/header_test.go4
-rw-r--r--pkg/siftool/info_test.go4
-rw-r--r--pkg/siftool/list_test.go4
-rw-r--r--pkg/siftool/mount.go27
-rw-r--r--pkg/siftool/mount_test.go61
-rw-r--r--pkg/siftool/new_test.go4
-rw-r--r--pkg/siftool/setprim_test.go4
-rw-r--r--pkg/siftool/siftool.go19
-rw-r--r--pkg/siftool/siftool_test.go21
-rw-r--r--pkg/siftool/testdata/TestAddCommands/Add/out.golden14
-rw-r--r--pkg/siftool/testdata/TestAddCommands/Mount/err.golden0
-rw-r--r--pkg/siftool/testdata/TestAddCommands/Mount/out.golden10
-rw-r--r--pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden0
-rw-r--r--pkg/siftool/testdata/TestAddCommands/SifToolExperimental/out.golden19
-rw-r--r--pkg/siftool/testdata/Test_command_getDump/Three/out.golden18
-rw-r--r--pkg/siftool/testdata/Test_command_getDump/Two/out.goldenbin4 -> 4096 bytes
-rw-r--r--pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSigned/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getInfo/Two/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getList/OneGroupSigned/out.golden2
-rw-r--r--pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden4
-rw-r--r--pkg/siftool/testdata/Test_command_getList/TwoGroupsSigned/out.golden8
-rw-r--r--pkg/siftool/testdata/Test_command_getMount/Empty/err.golden1
-rw-r--r--pkg/siftool/testdata/Test_command_getMount/Empty/out.golden9
-rw-r--r--pkg/siftool/testdata/Test_command_getMount/OneGroup/err.golden0
-rw-r--r--pkg/siftool/testdata/Test_command_getMount/OneGroup/out.golden0
-rw-r--r--pkg/siftool/testdata/Test_command_getUnmount/err.golden0
-rw-r--r--pkg/siftool/testdata/Test_command_getUnmount/out.golden0
-rw-r--r--pkg/siftool/unmount.go27
-rw-r--r--pkg/siftool/unmount_test.go42
36 files changed, 331 insertions, 58 deletions
diff --git a/pkg/siftool/add.go b/pkg/siftool/add.go
index 941f9b0..75f11df 100644
--- a/pkg/siftool/add.go
+++ b/pkg/siftool/add.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2019-2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2019-2022, Sylabs Inc. All rights reserved.
// Copyright (c) 2017, SingularityWare, LLC. All rights reserved.
// Copyright (c) 2017, Yannick Cote <yhcote@gmail.com> All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
@@ -27,6 +27,7 @@ var (
partArch *int32
signHash *int32
signEntity *string
+ sbomFormat *string
groupID *uint32
linkID *uint32
alignment *int
@@ -50,9 +51,9 @@ func getAddExamples(rootPath string) string {
func addFlags(fs *pflag.FlagSet) {
dataType = fs.Int("datatype", 0, `the type of data to add
[NEEDED, no default]:
- 1-Deffile, 2-EnvVar, 3-Labels,
- 4-Partition, 5-Signature, 6-GenericJSON,
- 7-Generic, 8-CryptoMessage`)
+ 1-Deffile, 2-EnvVar, 3-Labels,
+ 4-Partition, 5-Signature, 6-GenericJSON,
+ 7-Generic, 8-CryptoMessage, 9-SBOM`)
partType = fs.Int32("parttype", 0, `the type of partition (with -datatype 4-Partition)
[NEEDED, no default]:
1-System, 2-PrimSys, 3-Data,
@@ -66,7 +67,7 @@ func addFlags(fs *pflag.FlagSet) {
1-386, 2-amd64, 3-arm,
4-arm64, 5-ppc64, 6-ppc64le,
7-mips, 8-mipsle, 9-mips64,
- 10-mips64le, 11-s390x`)
+ 10-mips64le, 11-s390x, 12-riscv64`)
signHash = fs.Int32("signhash", 0, `the signature hash used (with -datatype 5-Signature)
[NEEDED, no default]:
1-SHA256, 2-SHA384, 3-SHA512,
@@ -74,9 +75,13 @@ func addFlags(fs *pflag.FlagSet) {
signEntity = fs.String("signentity", "", `the entity that signs (with -datatype 5-Signature)
[NEEDED, no default]:
example: 433FE984155206BD962725E20E8713472A879943`)
+ sbomFormat = fs.String("sbomformat", "", `the SBOM format (with -datatype 9-sbom):
+ cyclonedx-json, cyclonedx-xml, github-json,
+ spdx-json, spdx-rdf, spdx-tag-value,
+ spdx-yaml, syft-json`)
groupID = fs.Uint32("groupid", 0, "set groupid [default: 0]")
linkID = fs.Uint32("link", 0, "set link pointer [default: 0]")
- alignment = fs.Int("alignment", 0, "set alignment constraint [default: aligned on page size]")
+ alignment = fs.Int("alignment", 0, "set alignment [default: 4096 with -datatype 4-Partition, 0 otherwise]")
name = fs.String("filename", "", "set logical filename/handle [default: input filename]")
}
@@ -101,6 +106,8 @@ func getDataType() (sif.DataType, error) {
return sif.DataGeneric, nil
case 8:
return sif.DataCryptoMessage, nil
+ case 9:
+ return sif.DataSBOM, nil
default:
return 0, errDataTypeRequired
}
@@ -130,6 +137,8 @@ func getArch() string {
return "mips64le"
case 11:
return "s390x"
+ case 12:
+ return "riscv64"
default:
return "unknown"
}
@@ -154,9 +163,35 @@ func getHashType() (crypto.Hash, error) {
}
}
+var errInvalidSBOMFormat = errors.New("invalid SBOM format")
+
+func getSBOMFormat() (sif.SBOMFormat, error) {
+ switch *sbomFormat {
+ case "cyclonedx-json":
+ return sif.SBOMFormatCycloneDXJSON, nil
+ case "cyclonedx-xml":
+ return sif.SBOMFormatCycloneDXXML, nil
+ case "github", "github-json":
+ return sif.SBOMFormatGitHubJSON, nil
+ case "spdx-json":
+ return sif.SBOMFormatSPDXJSON, nil
+ case "spdx-rdf":
+ return sif.SBOMFormatSPDXRDF, nil
+ case "spdx-tag-value":
+ return sif.SBOMFormatSPDXTagValue, nil
+ case "spdx-yaml":
+ return sif.SBOMFormatSPDXYAML, nil
+ case "syft-json":
+ return sif.SBOMFormatSyftJSON, nil
+ default:
+ return 0, fmt.Errorf("%w: %v", errInvalidSBOMFormat, *sbomFormat)
+ }
+}
+
var (
errPartitionArgs = errors.New("with partition datatype, -partfs, -parttype and -partarch must be passed")
errInvalidFingerprintLength = errors.New("invalid signing entity fingerprint length")
+ errSBOMArgs = errors.New("with SBOM datatype, -sbomformat must be passed")
)
func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, error) {
@@ -180,7 +215,8 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e
opts = append(opts, sif.OptObjectName(*name))
}
- if dt == sif.DataPartition {
+ switch dt {
+ case sif.DataPartition:
if *partType == 0 || *partFS == 0 || *partArch == 0 {
return nil, errPartitionArgs
}
@@ -188,9 +224,8 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e
opts = append(opts,
sif.OptPartitionMetadata(sif.FSType(*partFS), sif.PartType(*partType), getArch()),
)
- }
- if dt == sif.DataSignature {
+ case sif.DataSignature:
b, err := hex.DecodeString(*signEntity)
if err != nil {
return nil, fmt.Errorf("failed to decode signing entity fingerprint: %w", err)
@@ -208,6 +243,18 @@ func getOptions(dt sif.DataType, fs *pflag.FlagSet) ([]sif.DescriptorInputOpt, e
copy(fp, b)
opts = append(opts, sif.OptSignatureMetadata(ht, fp))
+
+ case sif.DataSBOM:
+ if *sbomFormat == "" {
+ return nil, errSBOMArgs
+ }
+
+ f, err := getSBOMFormat()
+ if err != nil {
+ return nil, err
+ }
+
+ opts = append(opts, sif.OptSBOMMetadata(f))
}
return opts, nil
diff --git a/pkg/siftool/add_test.go b/pkg/siftool/add_test.go
index 6d51a33..ccbb5b3 100644
--- a/pkg/siftool/add_test.go
+++ b/pkg/siftool/add_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -46,7 +46,7 @@ func Test_command_getAdd(t *testing.T) {
}
args = append(args, tt.flags...)
- runCommand(t, cmd, args)
+ runCommand(t, cmd, args, nil)
})
}
}
diff --git a/pkg/siftool/del_test.go b/pkg/siftool/del_test.go
index 13fad07..070d609 100644
--- a/pkg/siftool/del_test.go
+++ b/pkg/siftool/del_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -24,7 +24,7 @@ func Test_command_getDel(t *testing.T) {
cmd := c.getDel()
- runCommand(t, cmd, []string{"1", makeTestSIF(t, true)})
+ runCommand(t, cmd, []string{"1", makeTestSIF(t, true)}, nil)
})
}
}
diff --git a/pkg/siftool/dump_test.go b/pkg/siftool/dump_test.go
index 20362b8..fb13eb4 100644
--- a/pkg/siftool/dump_test.go
+++ b/pkg/siftool/dump_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -39,7 +39,7 @@ func Test_command_getDump(t *testing.T) {
cmd := c.getDump()
- runCommand(t, cmd, []string{tt.id, tt.path})
+ runCommand(t, cmd, []string{tt.id, tt.path}, nil)
})
}
}
diff --git a/pkg/siftool/header_test.go b/pkg/siftool/header_test.go
index 5c19498..7aeb615 100644
--- a/pkg/siftool/header_test.go
+++ b/pkg/siftool/header_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -68,7 +68,7 @@ func Test_command_getHeader(t *testing.T) {
cmd := c.getHeader()
- runCommand(t, cmd, []string{tt.path})
+ runCommand(t, cmd, []string{tt.path}, nil)
})
}
}
diff --git a/pkg/siftool/info_test.go b/pkg/siftool/info_test.go
index 87f3a46..963b00a 100644
--- a/pkg/siftool/info_test.go
+++ b/pkg/siftool/info_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -39,7 +39,7 @@ func Test_command_getInfo(t *testing.T) {
cmd := c.getInfo()
- runCommand(t, cmd, []string{tt.id, tt.path})
+ runCommand(t, cmd, []string{tt.id, tt.path}, nil)
})
}
}
diff --git a/pkg/siftool/list_test.go b/pkg/siftool/list_test.go
index b7c1d32..5a4a47b 100644
--- a/pkg/siftool/list_test.go
+++ b/pkg/siftool/list_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -68,7 +68,7 @@ func Test_command_getList(t *testing.T) {
cmd := c.getList()
- runCommand(t, cmd, []string{tt.path})
+ runCommand(t, cmd, []string{tt.path}, nil)
})
}
}
diff --git a/pkg/siftool/mount.go b/pkg/siftool/mount.go
new file mode 100644
index 0000000..6b59557
--- /dev/null
+++ b/pkg/siftool/mount.go
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, Sylabs Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+package siftool
+
+import (
+ "github.com/spf13/cobra"
+)
+
+// getMount returns a command that mounts the primary system partition of a SIF image.
+func (c *command) getMount() *cobra.Command {
+ return &cobra.Command{
+ Use: "mount <sif_path> <mount_path>",
+ Short: "Mount primary system partition",
+ Long: "Mount the primary system partition of a SIF image",
+ Example: c.opts.rootPath + " mount image.sif path/",
+ Args: cobra.ExactArgs(2),
+ PreRunE: c.initApp,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return c.app.Mount(cmd.Context(), args[0], args[1])
+ },
+ DisableFlagsInUseLine: true,
+ Hidden: true, // hide while command is experimental
+ }
+}
diff --git a/pkg/siftool/mount_test.go b/pkg/siftool/mount_test.go
new file mode 100644
index 0000000..3b2848e
--- /dev/null
+++ b/pkg/siftool/mount_test.go
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, Sylabs Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+package siftool
+
+import (
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+
+ "github.com/sylabs/sif/v2/pkg/sif"
+)
+
+func Test_command_getMount(t *testing.T) {
+ if _, err := exec.LookPath("squashfuse"); err != nil {
+ t.Skip("squashfuse not found, skipping mount tests")
+ }
+
+ tests := []struct {
+ name string
+ opts commandOpts
+ path string
+ wantErr error
+ }{
+ {
+ name: "Empty",
+ path: filepath.Join(corpus, "empty.sif"),
+ wantErr: sif.ErrNoObjects,
+ },
+ {
+ name: "OneGroup",
+ path: filepath.Join(corpus, "one-group.sif"),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ path, err := os.MkdirTemp("", "siftool-mount-*")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ cmd := exec.Command("fusermount", "-u", path)
+
+ if err := cmd.Run(); err != nil {
+ t.Log(err)
+ }
+
+ os.RemoveAll(path)
+ })
+
+ c := &command{opts: tt.opts}
+
+ cmd := c.getMount()
+
+ runCommand(t, cmd, []string{tt.path, path}, tt.wantErr)
+ })
+ }
+}
diff --git a/pkg/siftool/new_test.go b/pkg/siftool/new_test.go
index af4cd75..81bcd58 100644
--- a/pkg/siftool/new_test.go
+++ b/pkg/siftool/new_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -32,7 +32,7 @@ func Test_command_getNew(t *testing.T) {
cmd := c.getNew()
- runCommand(t, cmd, []string{tf.Name()})
+ runCommand(t, cmd, []string{tf.Name()}, nil)
})
}
}
diff --git a/pkg/siftool/setprim_test.go b/pkg/siftool/setprim_test.go
index e37b240..13cd0e3 100644
--- a/pkg/siftool/setprim_test.go
+++ b/pkg/siftool/setprim_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -24,7 +24,7 @@ func Test_command_getSetPrim(t *testing.T) {
cmd := c.getSetPrim()
- runCommand(t, cmd, []string{"1", makeTestSIF(t, true)})
+ runCommand(t, cmd, []string{"1", makeTestSIF(t, true)}, nil)
})
}
}
diff --git a/pkg/siftool/siftool.go b/pkg/siftool/siftool.go
index 4e624f1..aa59f61 100644
--- a/pkg/siftool/siftool.go
+++ b/pkg/siftool/siftool.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2018-2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved.
// Copyright (c) 2017, SingularityWare, LLC. All rights reserved.
// Copyright (c) 2017, Yannick Cote <yhcote@gmail.com> All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
@@ -23,6 +23,7 @@ type command struct {
func (c *command) initApp(cmd *cobra.Command, args []string) error {
app, err := siftool.New(
siftool.OptAppOutput(cmd.OutOrStdout()),
+ siftool.OptAppError(cmd.ErrOrStderr()),
)
c.app = app
@@ -31,12 +32,21 @@ func (c *command) initApp(cmd *cobra.Command, args []string) error {
// commandOpts contains configured options.
type commandOpts struct {
- rootPath string
+ rootPath string
+ experimental bool
}
// CommandOpt are used to configure optional command behavior.
type CommandOpt func(*commandOpts) error
+// OptWithExperimental enables/disables experimental commands.
+func OptWithExperimental(b bool) CommandOpt {
+ return func(co *commandOpts) error {
+ co.experimental = b
+ return nil
+ }
+}
+
// AddCommands adds siftool commands to cmd according to opts.
//
// A set of commands are provided to display elements such as the SIF global
@@ -66,5 +76,10 @@ func AddCommands(cmd *cobra.Command, opts ...CommandOpt) error {
c.getSetPrim(),
)
+ if c.opts.experimental {
+ cmd.AddCommand(c.getMount())
+ cmd.AddCommand(c.getUnmount())
+ }
+
return nil
}
diff --git a/pkg/siftool/siftool_test.go b/pkg/siftool/siftool_test.go
index 5236254..606d6eb 100644
--- a/pkg/siftool/siftool_test.go
+++ b/pkg/siftool/siftool_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, Sylabs Inc. All rights reserved.
+// Copyright (c) 2021-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.
@@ -6,6 +6,7 @@ package siftool
import (
"bytes"
+ "errors"
"os"
"path/filepath"
"testing"
@@ -47,7 +48,7 @@ func makeTestSIF(t *testing.T, withDataObject bool) string {
return tf.Name()
}
-func runCommand(t *testing.T, cmd *cobra.Command, args []string) {
+func runCommand(t *testing.T, cmd *cobra.Command, args []string, wantErr error) {
t.Helper()
var out, err bytes.Buffer
@@ -56,8 +57,8 @@ func runCommand(t *testing.T, cmd *cobra.Command, args []string) {
cmd.SetArgs(args)
- if err := cmd.Execute(); err != nil {
- t.Fatal(err)
+ if got, want := cmd.Execute(), wantErr; !errors.Is(got, want) {
+ t.Fatalf("got error %v, want %v", got, want)
}
g := goldie.New(t,
@@ -79,6 +80,11 @@ func TestAddCommands(t *testing.T) {
args: []string{"help"},
},
{
+ name: "SifToolExperimental",
+ opts: []CommandOpt{OptWithExperimental(true)},
+ args: []string{"help"},
+ },
+ {
name: "Add",
args: []string{"help", "add"},
},
@@ -110,6 +116,11 @@ func TestAddCommands(t *testing.T) {
name: "SetPrim",
args: []string{"help", "setprim"},
},
+ {
+ name: "Mount",
+ opts: []CommandOpt{OptWithExperimental(true)},
+ args: []string{"help", "mount"},
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -121,7 +132,7 @@ func TestAddCommands(t *testing.T) {
t.Fatal(err)
}
- runCommand(t, cmd, tt.args)
+ runCommand(t, cmd, tt.args, nil)
})
}
}
diff --git a/pkg/siftool/testdata/TestAddCommands/Add/out.golden b/pkg/siftool/testdata/TestAddCommands/Add/out.golden
index 16c47e5..3f39697 100644
--- a/pkg/siftool/testdata/TestAddCommands/Add/out.golden
+++ b/pkg/siftool/testdata/TestAddCommands/Add/out.golden
@@ -9,12 +9,12 @@ siftool add image.sif rootfs.squashfs --datatype 4 --parttype 1 --partfs 1 ----p
siftool add image.sif signature.bin -datatype 5 --signentity 433FE984155206BD962725E20E8713472A879943 --signhash 1
Flags:
- --alignment int set alignment constraint [default: aligned on page size]
+ --alignment int set alignment [default: 4096 with -datatype 4-Partition, 0 otherwise]
--datatype int the type of data to add
[NEEDED, no default]:
- 1-Deffile, 2-EnvVar, 3-Labels,
- 4-Partition, 5-Signature, 6-GenericJSON,
- 7-Generic, 8-CryptoMessage
+ 1-Deffile, 2-EnvVar, 3-Labels,
+ 4-Partition, 5-Signature, 6-GenericJSON,
+ 7-Generic, 8-CryptoMessage, 9-SBOM
--filename string set logical filename/handle [default: input filename]
--groupid uint32 set groupid [default: 0]
-h, --help help for add
@@ -24,7 +24,7 @@ Flags:
1-386, 2-amd64, 3-arm,
4-arm64, 5-ppc64, 6-ppc64le,
7-mips, 8-mipsle, 9-mips64,
- 10-mips64le, 11-s390x
+ 10-mips64le, 11-s390x, 12-riscv64
--partfs int32 the filesystem used (with -datatype 4-Partition)
[NEEDED, no default]:
1-Squash, 2-Ext3, 3-ImmuObj,
@@ -33,6 +33,10 @@ Flags:
[NEEDED, no default]:
1-System, 2-PrimSys, 3-Data,
4-Overlay
+ --sbomformat string the SBOM format (with -datatype 9-sbom):
+ cyclonedx-json, cyclonedx-xml, github-json,
+ spdx-json, spdx-rdf, spdx-tag-value,
+ spdx-yaml, syft-json
--signentity string the entity that signs (with -datatype 5-Signature)
[NEEDED, no default]:
example: 433FE984155206BD962725E20E8713472A879943
diff --git a/pkg/siftool/testdata/TestAddCommands/Mount/err.golden b/pkg/siftool/testdata/TestAddCommands/Mount/err.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/TestAddCommands/Mount/err.golden
diff --git a/pkg/siftool/testdata/TestAddCommands/Mount/out.golden b/pkg/siftool/testdata/TestAddCommands/Mount/out.golden
new file mode 100644
index 0000000..3df015d
--- /dev/null
+++ b/pkg/siftool/testdata/TestAddCommands/Mount/out.golden
@@ -0,0 +1,10 @@
+Mount the primary system partition of a SIF image
+
+Usage:
+ siftool mount <sif_path> <mount_path>
+
+Examples:
+siftool mount image.sif path/
+
+Flags:
+ -h, --help help for mount
diff --git a/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden b/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/err.golden
diff --git a/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/out.golden b/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/out.golden
new file mode 100644
index 0000000..2d8532f
--- /dev/null
+++ b/pkg/siftool/testdata/TestAddCommands/SifToolExperimental/out.golden
@@ -0,0 +1,19 @@
+Usage:
+ siftool [command]
+
+Available Commands:
+ add Add data object
+ completion Generate the autocompletion script for the specified shell
+ del Delete data object
+ dump Dump data object
+ header Display global header
+ help Help about any command
+ info Display data object info
+ list List data objects
+ new Create SIF image
+ setprim Set primary system partition
+
+Flags:
+ -h, --help help for siftool
+
+Use "siftool [command] --help" for more information about a command.
diff --git a/pkg/siftool/testdata/Test_command_getDump/Three/out.golden b/pkg/siftool/testdata/Test_command_getDump/Three/out.golden
index 0299536..4e354d9 100644
--- a/pkg/siftool/testdata/Test_command_getDump/Three/out.golden
+++ b/pkg/siftool/testdata/Test_command_getDump/Three/out.golden
@@ -1,15 +1,15 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
-{"version":1,"header":{"digest":"sha256:635fa0a14a8ef0c0351ed3e985799ed1d4f75ce973dea3cc76c99710795cc3f1"},"objects":[{"relativeId":0,"descriptorDigest":"sha256:3634ad01db0dd5482ecf685267b53d6201690438ca27c3d7ea91c971a1f41f92","objectDigest":"sha256:004dfc8da678c309de28b5386a1e9efd57f536b150c40d29b31506aa0fb17ec2"},{"relativeId":1,"descriptorDigest":"sha256:db74cb63348414def73535c9f0f83e8ad7df61229ed2806f4da8b69d6d7464d6","objectDigest":"sha256:5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953"}]}
+{"version":1,"header":{"digest":"sha256:635fa0a14a8ef0c0351ed3e985799ed1d4f75ce973dea3cc76c99710795cc3f1"},"objects":[{"relativeId":0,"descriptorDigest":"sha256:3634ad01db0dd5482ecf685267b53d6201690438ca27c3d7ea91c971a1f41f92","objectDigest":"sha256:004dfc8da678c309de28b5386a1e9efd57f536b150c40d29b31506aa0fb17ec2"},{"relativeId":1,"descriptorDigest":"sha256:04b5f87c9692a54f80d10fb6af00c779763aeca29d610348854bd97cd8bf66fd","objectDigest":"sha256:9f9c4e5e131934969b4ac8f495691c70b8c6c8e3f489c2c9ab5f1af82bce0604"}]}
-----BEGIN PGP SIGNATURE-----
-wsBzBAEBCAAnBQJe+oD0CZCiDCfuf/e6hBahBBIEXIwLEATQWN5L7aIMJ+5/97qE
-AABQ4QgAkWcLNLcghZ96VnJ9+67qbsdwp51rfERCKN0dZLBTHKN5Qjn1BWM/XbPj
-Qnl0F6D6YBId7c/KO0sbb3EHUdpmMEQlouQYFOTHWtdyvwO6spRLBx5EQA7Iv0rF
-jREz/jC7GaREK94u+hXRr94+FH5gEnHUL+Vg7pW/+cGiwLY1ddoL8ELgYhxqxd9J
-sET+vU1E4GJ3TyYFhVFsMsNeW7dQauqjQSJxMLTwXNphxTH19ePbJ2uDE2UJ3fn7
-up5ruugRyEe5qgRICGxRSDp8/INGRvoDUi32T9uLORzS+umRX5YW0b6RWD+5R72V
-0ewbMTJIx2lpfQGPMWROwcF7nkLdWQ==
-=WWGX
+wsBzBAEBCAAnBQJe+oD0CZCiDCfuf/e6hBYhBBIEXIwLEATQWN5L7aIMJ+5/97qE
+AAC46gf/VXyzZ649nttrX13JkM5kRVPlAIblBQxfoUxA1xwIXdRoM5ceDY0Em+YD
+8b6Xl1w2sDTqo0R15cJSh8sf0ClFOvYpDQRNCwKx17k1Wd0gHcW4QVu6gJnlbNvN
+o/EJdEN2TkbCM2aFvj34DAIfErRBIEsCeDDvJ/6WUSySWbnydfNU2pCsnK4A7l2H
+KOXFzSaPijG9L/pU3O3vNZ+fXPffqHL9JVhs5Mt/Yo3oeoEnoVaKvJLGx/fyl+Gj
+7qsfWFyHWzRCww9VFg/TCBeUku0CYRfXhxOgo4OuHNr8oo82rKDZU6+l3UZ2Sw8T
++kLe/zUkaILocGOvhvKdi630OGGb/Q==
+=3Jq2
-----END PGP SIGNATURE----- \ No newline at end of file
diff --git a/pkg/siftool/testdata/Test_command_getDump/Two/out.golden b/pkg/siftool/testdata/Test_command_getDump/Two/out.golden
index 7d174b1..cf6539a 100644
--- a/pkg/siftool/testdata/Test_command_getDump/Two/out.golden
+++ b/pkg/siftool/testdata/Test_command_getDump/Two/out.golden
Binary files differ
diff --git a/pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden b/pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden
index bc631d6..a2941c1 100644
--- a/pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden
+++ b/pkg/siftool/testdata/Test_command_getHeader/OneGroup/out.golden
@@ -5,4 +5,4 @@ Descriptors Total: 48
Descriptors Offset: 4096
Descriptors Size: 27 KiB
Data Offset: 32176
-Data Size: 5 KiB
+Data Size: 9 KiB
diff --git a/pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden b/pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden
index 0db18f0..c16ef18 100644
--- a/pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden
+++ b/pkg/siftool/testdata/Test_command_getHeader/TwoGroups/out.golden
@@ -5,4 +5,4 @@ Descriptors Total: 48
Descriptors Offset: 4096
Descriptors Size: 27 KiB
Data Offset: 32176
-Data Size: 9 KiB
+Data Size: 265 KiB
diff --git a/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSigned/out.golden b/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSigned/out.golden
index acf8b17..44854c9 100644
--- a/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSigned/out.golden
+++ b/pkg/siftool/testdata/Test_command_getHeader/TwoGroupsSigned/out.golden
@@ -5,4 +5,4 @@ Descriptors Total: 48
Descriptors Offset: 4096
Descriptors Size: 27 KiB
Data Offset: 32176
-Data Size: 17 KiB
+Data Size: 266 KiB
diff --git a/pkg/siftool/testdata/Test_command_getInfo/Two/out.golden b/pkg/siftool/testdata/Test_command_getInfo/Two/out.golden
index f34651f..f49a554 100644
--- a/pkg/siftool/testdata/Test_command_getInfo/Two/out.golden
+++ b/pkg/siftool/testdata/Test_command_getInfo/Two/out.golden
@@ -3,7 +3,7 @@
Group ID: 1
Linked ID: NONE
Offset: 36864
- Size: 4
+ Size: 4096
Filesystem Type: Squashfs
Partition Type: *System
Architecture: 386
diff --git a/pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden b/pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden
index fe78f62..01400f9 100644
--- a/pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden
+++ b/pkg/siftool/testdata/Test_command_getList/OneGroup/out.golden
@@ -2,4 +2,4 @@
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
-2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386)
+2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
diff --git a/pkg/siftool/testdata/Test_command_getList/OneGroupSigned/out.golden b/pkg/siftool/testdata/Test_command_getList/OneGroupSigned/out.golden
index 98030e3..5b663d3 100644
--- a/pkg/siftool/testdata/Test_command_getList/OneGroupSigned/out.golden
+++ b/pkg/siftool/testdata/Test_command_getList/OneGroupSigned/out.golden
@@ -2,5 +2,5 @@
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
-2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386)
+2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
3 |NONE |1 (G) |40960-42014 |Signature (SHA-256)
diff --git a/pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden b/pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden
index 648c280..1eca2ab 100644
--- a/pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden
+++ b/pkg/siftool/testdata/Test_command_getList/TwoGroups/out.golden
@@ -2,5 +2,5 @@
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
-2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386)
-3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64)
+2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
+3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64)
diff --git a/pkg/siftool/testdata/Test_command_getList/TwoGroupsSigned/out.golden b/pkg/siftool/testdata/Test_command_getList/TwoGroupsSigned/out.golden
index f21bf6d..17240ba 100644
--- a/pkg/siftool/testdata/Test_command_getList/TwoGroupsSigned/out.golden
+++ b/pkg/siftool/testdata/Test_command_getList/TwoGroupsSigned/out.golden
@@ -2,7 +2,7 @@
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32768-32772 |FS (Raw/System/386)
-2 |1 |NONE |36864-36868 |FS (Squashfs/*System/386)
-3 |2 |NONE |40960-40964 |FS (Ext3/System/amd64)
-4 |NONE |1 (G) |45056-46110 |Signature (SHA-256)
-5 |NONE |2 (G) |49152-50007 |Signature (SHA-256)
+2 |1 |NONE |36864-40960 |FS (Squashfs/*System/386)
+3 |2 |NONE |40960-303104 |FS (Ext3/System/amd64)
+4 |NONE |1 (G) |303104-304158 |Signature (SHA-256)
+5 |NONE |2 (G) |304158-305013 |Signature (SHA-256)
diff --git a/pkg/siftool/testdata/Test_command_getMount/Empty/err.golden b/pkg/siftool/testdata/Test_command_getMount/Empty/err.golden
new file mode 100644
index 0000000..cd860b8
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getMount/Empty/err.golden
@@ -0,0 +1 @@
+Error: failed to get partition descriptor: no objects in image
diff --git a/pkg/siftool/testdata/Test_command_getMount/Empty/out.golden b/pkg/siftool/testdata/Test_command_getMount/Empty/out.golden
new file mode 100644
index 0000000..f22522a
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getMount/Empty/out.golden
@@ -0,0 +1,9 @@
+Usage:
+ mount <sif_path> <mount_path>
+
+Examples:
+ mount image.sif path/
+
+Flags:
+ -h, --help help for mount
+
diff --git a/pkg/siftool/testdata/Test_command_getMount/OneGroup/err.golden b/pkg/siftool/testdata/Test_command_getMount/OneGroup/err.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getMount/OneGroup/err.golden
diff --git a/pkg/siftool/testdata/Test_command_getMount/OneGroup/out.golden b/pkg/siftool/testdata/Test_command_getMount/OneGroup/out.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getMount/OneGroup/out.golden
diff --git a/pkg/siftool/testdata/Test_command_getUnmount/err.golden b/pkg/siftool/testdata/Test_command_getUnmount/err.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getUnmount/err.golden
diff --git a/pkg/siftool/testdata/Test_command_getUnmount/out.golden b/pkg/siftool/testdata/Test_command_getUnmount/out.golden
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/siftool/testdata/Test_command_getUnmount/out.golden
diff --git a/pkg/siftool/unmount.go b/pkg/siftool/unmount.go
new file mode 100644
index 0000000..8814182
--- /dev/null
+++ b/pkg/siftool/unmount.go
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, Sylabs Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+package siftool
+
+import (
+ "github.com/spf13/cobra"
+)
+
+// getUnmount returns a command that unmounts the primary system partition of a SIF image.
+func (c *command) getUnmount() *cobra.Command {
+ return &cobra.Command{
+ Use: "unmount <mount_path>",
+ Short: "Unmount primary system partition",
+ Long: "Unmount a primary system partition of a SIF image",
+ Example: c.opts.rootPath + " unmount path/",
+ Args: cobra.ExactArgs(1),
+ PreRunE: c.initApp,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return c.app.Unmount(cmd.Context(), args[0])
+ },
+ DisableFlagsInUseLine: true,
+ Hidden: true, // hide while command is experimental
+ }
+}
diff --git a/pkg/siftool/unmount_test.go b/pkg/siftool/unmount_test.go
new file mode 100644
index 0000000..2cf8160
--- /dev/null
+++ b/pkg/siftool/unmount_test.go
@@ -0,0 +1,42 @@
+// Copyright (c) 2022, Sylabs Inc. All rights reserved.
+// This software is licensed under a 3-clause BSD license. Please consult the
+// LICENSE file distributed with the sources of this project regarding your
+// rights to use or distribute this software.
+
+package siftool
+
+import (
+ "context"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+
+ "github.com/sylabs/sif/v2/pkg/user"
+)
+
+func Test_command_getUnmount(t *testing.T) {
+ if _, err := exec.LookPath("squashfuse"); err != nil {
+ t.Skip(" not found, skipping unmount tests")
+ }
+ if _, err := exec.LookPath("fusermount"); err != nil {
+ t.Skip(" not found, skipping unmount tests")
+ }
+
+ path, err := os.MkdirTemp("", "siftool-unmount-*")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ os.RemoveAll(path)
+ })
+
+ testSIF := filepath.Join(corpus, "one-group.sif")
+ if err := user.Mount(context.Background(), testSIF, path); err != nil {
+ t.Fatal(err)
+ }
+
+ c := &command{}
+ cmd := c.getUnmount()
+ runCommand(t, cmd, []string{path}, nil)
+}