Skip to content
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

Refactor siftool Package #27

Merged
merged 3 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cmd/siftool/info.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Copyright (c) 2021, Sylabs Inc. All rights reserved.
// Copyright (c) 2018, Divya Cote <divya.cote@gmail.com> 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
Expand Down Expand Up @@ -41,7 +42,7 @@ func cmdInfo(args []string) error {
return fmt.Errorf("while converting input descriptor id: %s", err)
}

return siftool.Info(id, args[1])
return siftool.Info(args[1], uint32(id))
}

// cmdDump extracts and output a data object from a SIF file to stdout.
Expand All @@ -55,5 +56,5 @@ func cmdDump(args []string) error {
return fmt.Errorf("while converting input descriptor id: %s", err)
}

return siftool.Dump(id, args[1])
return siftool.Dump(args[1], uint32(id))
}
115 changes: 95 additions & 20 deletions cmd/siftool/modif.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@
package main

import (
"errors"
"flag"
"fmt"
"os"
"strconv"

"github.com/sylabs/sif/internal/app/siftool"
"github.com/sylabs/sif/pkg/sif"
)

var (
datatype = flag.Int64("datatype", -1, "")
parttype = flag.Int64("parttype", -1, "")
partfs = flag.Int64("partfs", -1, "")
partarch = flag.Int64("partarch", -1, "")
signhash = flag.Int64("signhash", -1, "")
datatype = flag.Int("datatype", 0, "")
parttype = flag.Int("parttype", 0, "")
partfs = flag.Int("partfs", 0, "")
partarch = flag.Int("partarch", 0, "")
signhash = flag.Int("signhash", 0, "")
signentity = flag.String("signentity", "", "")
groupid = flag.Int64("groupid", sif.DescrUnusedGroup, "")
link = flag.Int64("link", sif.DescrUnusedLink, "")
groupid = flag.Int("groupid", 0, "")
link = flag.Int("link", 0, "")
alignment = flag.Int("alignment", 0, "")
filename = flag.String("filename", "", "")
)
Expand All @@ -41,19 +43,92 @@ func cmdAdd(args []string) error {
}

opts := siftool.AddOptions{
Datatype: datatype,
Parttype: parttype,
Partfs: partfs,
Partarch: partarch,
Signhash: signhash,
Signentity: signentity,
Groupid: groupid,
Link: link,
Alignment: alignment,
Filename: filename,
Groupid: uint32(*groupid),
Link: uint32(*link),
Alignment: *alignment,
Filename: *filename,
Fp: os.Stdin,
}

return siftool.Add(args[0], args[1], opts)
switch *datatype {
case 1:
opts.Datatype = sif.DataDeffile
case 2:
opts.Datatype = sif.DataEnvVar
case 3:
opts.Datatype = sif.DataLabels
case 4:
opts.Datatype = sif.DataPartition
case 5:
opts.Datatype = sif.DataSignature
case 6:
opts.Datatype = sif.DataGenericJSON
case 7:
opts.Datatype = sif.DataGeneric
case 8:
opts.Datatype = sif.DataCryptoMessage
default:
return errors.New("-datatype flag is required with a valid range")
}

if opts.Datatype == sif.DataPartition {
if *partfs == 0 || *parttype == 0 || *partarch == 0 {
return errors.New("with partition datatype, -partfs, -parttype and -partarch must be passed")
}

opts.Parttype = sif.Parttype(*parttype)
opts.Partfs = sif.Fstype(*partfs)

switch *partarch {
case 1:
opts.Partarch = sif.HdrArch386
case 2:
opts.Partarch = sif.HdrArchAMD64
case 3:
opts.Partarch = sif.HdrArchARM
case 4:
opts.Partarch = sif.HdrArchARM64
case 5:
opts.Partarch = sif.HdrArchPPC64
case 6:
opts.Partarch = sif.HdrArchPPC64le
case 7:
opts.Partarch = sif.HdrArchMIPS
case 8:
opts.Partarch = sif.HdrArchMIPSle
case 9:
opts.Partarch = sif.HdrArchMIPS64
case 10:
opts.Partarch = sif.HdrArchMIPS64le
case 11:
opts.Partarch = sif.HdrArchS390x
default:
return errors.New("-partarch flag is required with a valid range")
}
} else if opts.Datatype == sif.DataSignature {
if *signhash == 0 || *signentity == "" {
return errors.New("with signature datatype, -signhash and -signentity must be passed")
}

opts.Signhash = sif.Hashtype(*signhash)
opts.Signentity = *signentity
}

if dataFile := args[1]; dataFile != "-" {
fp, err := os.Open(dataFile)
if err != nil {
return err
}
defer fp.Close()

opts.Fp = fp

if opts.Filename == "" {
opts.Filename = dataFile
}
}

return siftool.Add(args[0], opts)
}

func cmdDel(args []string) error {
Expand All @@ -66,7 +141,7 @@ func cmdDel(args []string) error {
return fmt.Errorf("while converting input descriptor id: %s", err)
}

return siftool.Del(id, args[1])
return siftool.Del(args[1], uint32(id))
}

func cmdSetPrim(args []string) error {
Expand All @@ -79,5 +154,5 @@ func cmdSetPrim(args []string) error {
return fmt.Errorf("while converting input descriptor id: %s", err)
}

return siftool.Setprim(id, args[0])
return siftool.Setprim(args[0], uint32(id))
}
4 changes: 2 additions & 2 deletions cmd/siftool/siftool.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func main() {
-signentity the entity that signs (with -datatype 5-Signature)
[NEEDED, no default]:
example: 433FE984155206BD962725E20E8713472A879943
-groupid set groupid [default: DescrUnusedGroup]
-link set link pointer [default: DescrUnusedLink]
-groupid set groupid [default: 0]
-link set link pointer [default: 0]
-alignment set alignment constraint [default: aligned on page size]
-filename set logical filename/handle [default: input filename]
`},
Expand Down
25 changes: 25 additions & 0 deletions internal/app/siftool/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2021, 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/sylabs/sif/pkg/sif"
)

// withFileImage calls fn with a FileImage loaded from path.
func withFileImage(path string, writable bool, fn func(*sif.FileImage) error) (err error) {
f, err := sif.LoadContainer(path, !writable)
if err != nil {
return err
}
defer func() {
if uerr := f.UnloadContainer(); uerr != nil && err == nil {
err = uerr
}
}()

return fn(&f)
}
103 changes: 29 additions & 74 deletions internal/app/siftool/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,100 +11,55 @@ package siftool
import (
"fmt"
"io"
"log"
"os"
"time"

"github.com/sylabs/sif/pkg/sif"
)

// Header displays a SIF file global header.
func Header(file string) error {
fimg, err := sif.LoadContainer(file, true)
if err != nil {
func Header(path string) error {
return withFileImage(path, true, func(f *sif.FileImage) error {
//nolint:staticcheck // In use until v2 API to avoid code duplication
_, err := fmt.Print(f.FmtHeader())
return err
}
defer func() {
if err := fimg.UnloadContainer(); err != nil {
log.Printf("Error unloading container: %v", err)
}
}()

//nolint:staticcheck // In use until v2 API to avoid code duplication
fmt.Print(fimg.FmtHeader())

return nil
})
}

// List displays a list of all active descriptors from a SIF file.
func List(file string) error {
fimg, err := sif.LoadContainer(file, true)
if err != nil {
return err
}
defer func() {
if err := fimg.UnloadContainer(); err != nil {
log.Printf("Error unloading container: %v", err)
}
}()

fmt.Println("Container id:", fimg.Header.ID)
fmt.Println("Created on: ", time.Unix(fimg.Header.Ctime, 0).UTC())
fmt.Println("Modified on: ", time.Unix(fimg.Header.Mtime, 0).UTC())
fmt.Println("----------------------------------------------------")
func List(path string) error {
return withFileImage(path, false, func(f *sif.FileImage) error {
fmt.Println("Container id:", f.Header.ID)
fmt.Println("Created on: ", time.Unix(f.Header.Ctime, 0).UTC())
fmt.Println("Modified on: ", time.Unix(f.Header.Mtime, 0).UTC())
fmt.Println("----------------------------------------------------")

fmt.Println("Descriptor list:")
fmt.Println("Descriptor list:")

//nolint:staticcheck // In use until v2 API to avoid code duplication
fmt.Print(fimg.FmtDescrList())

return nil
//nolint:staticcheck // In use until v2 API to avoid code duplication
_, err := fmt.Print(f.FmtDescrList())
return err
})
}

// Info displays detailed info about a descriptor from a SIF file.
func Info(descr uint64, file string) error {
fimg, err := sif.LoadContainer(file, true)
if err != nil {
func Info(path string, id uint32) error {
return withFileImage(path, false, func(f *sif.FileImage) error {
//nolint:staticcheck // In use until v2 API to avoid code duplication
_, err := fmt.Print(f.FmtDescrInfo(id))
return err
}
defer func() {
if err := fimg.UnloadContainer(); err != nil {
log.Printf("Error unloading container: %v", err)
}
}()

//nolint:staticcheck // In use until v2 API to avoid code duplication
fmt.Print(fimg.FmtDescrInfo(uint32(descr)))

return nil
})
}

// Dump extracts and outputs a data object from a SIF file.
func Dump(descr uint64, file string) error {
fimg, err := sif.LoadContainer(file, true)
if err != nil {
return err
}
defer func() {
if err := fimg.UnloadContainer(); err != nil {
log.Printf("Error unloading container: %v", err)
func Dump(path string, id uint32) error {
return withFileImage(path, false, func(f *sif.FileImage) error {
d, _, err := f.GetFromDescrID(id)
if err != nil {
return err
}
}()

for _, v := range fimg.DescrArr {
if !v.Used {
continue
}
if v.ID == uint32(descr) {
if _, err := fimg.Fp.Seek(v.Fileoff, 0); err != nil {
return fmt.Errorf("while seeking to data object: %s", err)
}
if _, err := io.CopyN(os.Stdout, fimg.Fp, v.Filelen); err != nil {
return fmt.Errorf("while copying data object to stdout: %s", err)
}
return nil
}
}

return fmt.Errorf("descriptor not in range or currently unused")
_, err = io.CopyN(os.Stdout, d.GetReader(f), d.Filelen)
return err
})
}
Loading