Skip to content
Open
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
46 changes: 41 additions & 5 deletions cmd/tar2rpm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ const (
DashStdinStdout = "-"
)

type argSlice []string

func (s *argSlice) String() string {
return fmt.Sprintf("%v", *s)
}

func (s *argSlice) Set(value string) error {
*s = append(*s, value)
return nil
}

var (
provides,
obsoletes,
Expand All @@ -57,10 +68,16 @@ var (
url = flag.String("url", "", "the rpm url")
licence = flag.String("licence", "", "the rpm licence name")

prein = flag.String("prein", "", "prein scriptlet contents (not filename)")
postin = flag.String("postin", "", "postin scriptlet contents (not filename)")
preun = flag.String("preun", "", "preun scriptlet contents (not filename)")
postun = flag.String("postun", "", "postun scriptlet contents (not filename)")
prein = flag.String("prein", "", "prein scriptlet contents (not filename).")
postin = flag.String("postin", "", "postin scriptlet contents (not filename).")
preun = flag.String("preun", "", "preun scriptlet contents (not filename)")
postun = flag.String("postun", "", "postun scriptlet contents (not filename)")
pretrans = flag.String("pretrans", "", "pretrans scriptlet contents (not filename, lua code [+])")
posttrans = flag.String("posttrans", "", "posttrans scriptlet contents (not filename, lua code [+])")
verify = flag.String("verifyscript", "", "verifyscript scriptlet contents (not filename)")

interpreter = flag.String("interpreter", rpmpack.DefaultScriptletInterpreter, "interpreter (scriptlet program) to run scriptlets with")
interpreterFor argSlice

useDirAllowlist = flag.Bool("use_dir_allowlist", false, "Only include dirs in the explicit allow list")
dirAllowlistFile = flag.String("dir_allowlist_file", "", "A file with one directory per line to include from the tar to the rpm")
Expand All @@ -86,6 +103,9 @@ func main() {
flag.Var(&recommends, "recommends", "rpm recommends values, can be just name or in the form of name=version (eg. bla=1.2.3)")
flag.Var(&requires, "requires", "rpm requires values, can be just name or in the form of name=version (eg. bla=1.2.3)")
flag.Var(&conflicts, "conflicts", "rpm provides values, can be just name or in the form of name=version (eg. bla=1.2.3)")
flag.Var(&interpreterFor, "interpreter_for", "override interpreter for a scriptlet, format `NAME:INTERPRETER`, where NAME is one of\n"+
"prein postin preun postun verifyscript, e.g. prein:/bin/bash\n"+
"[+]: pretrans and posttrans use '<lua>' by default, which is not changed by -interpreter")
flag.Usage = usage
flag.Parse()
if *name == "" || *version == "" {
Expand Down Expand Up @@ -137,7 +157,7 @@ func main() {
defer f.Close()
w = f
} else {
// Only print notice if no explicit '-' is given, merge with tar notice:
// Only print notice if no explicit '-' is given, merge with tar notice:
if noticeStdinStdout != "" {
noticeStdinStdout += ", "
}
Expand Down Expand Up @@ -178,6 +198,19 @@ func main() {
fmt.Fprintf(os.Stderr, "tar2rpm error: %v\n", err)
os.Exit(1)
}

r.SetDefaultScriptletInterpreter(*interpreter)
for _, arg := range interpreterFor {
parts := strings.SplitN(arg, ":", 2)
if len(parts) != 2 {
fmt.Fprintf(os.Stderr, "invalid -interpreter_for argument %q: must contain ':'\n", arg)
os.Exit(1)
}
if err := r.SetScriptletInterpreterFor(parts[0], parts[1]); err != nil {
fmt.Fprintf(os.Stderr, "invalid -interpreter_for argument %q: %v\n", arg, err)
os.Exit(1)
}
}
if *useDirAllowlist {
al := map[string]bool{}
if *dirAllowlistFile != "" {
Expand All @@ -195,10 +228,13 @@ func main() {
r.AllowListDirs(al)
}

r.AddPretrans(*pretrans)
r.AddPrein(*prein)
r.AddPostin(*postin)
r.AddPreun(*preun)
r.AddPostun(*postun)
r.AddPosttrans(*posttrans)
r.AddVerifyScript(*verify)

if err := r.Write(w); err != nil {
fmt.Fprintf(os.Stderr, "rpm write error: %v\n", err)
Expand Down
225 changes: 225 additions & 0 deletions interpreter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package rpmpack

import (
"testing"
)

var (
binTest = "/bin/test"
binother = "/bin/other"
echo = "echo"
i1 = "i = 1"
)

func EnsureSetScriptletIs(
t *testing.T,
scriptlets explicitScriptlets,
interpreter string,
expectedInterpreter string,
expectedContent string) int {

haveInterpreter := scriptlets.scriptlets[interpreter].interpreter
haveContent := scriptlets.scriptlets[interpreter].content

if haveInterpreter != "" {
if haveInterpreter != expectedInterpreter {
t.Errorf("%s interpreter should be %q, got %q", interpreter, expectedInterpreter, haveInterpreter)
}
if expectedContent != haveContent {
t.Errorf("%s content should be %q, got %q", interpreter, expectedContent, haveContent)
}
return 1
} else {
return 0
}
}
func EnsureSetInterpretersAreAll(
r *RPM,
t *testing.T,
expectedInterpreter string,
expectedContent string,
expectedTotal int) {

scriptlets := r.implicitToExplicitScriptlets()
total := 0
for _, interpreter := range []string{
"prein",
"postin",
"preun",
"postun",
"verifyscript",
} {
total += EnsureSetScriptletIs(t, scriptlets, interpreter, expectedInterpreter, expectedContent)
}

if total != expectedTotal {
t.Errorf("Saw %d interpreters, but expected %d", total, expectedTotal)
}
}

func EnsureSetLuaInterpretersAreAll(r *RPM, t *testing.T, expectedInterpreter string, expectedContent string, expectedTotal int) {
scriptlets := r.implicitToExplicitScriptlets()
total := 0
for _, interpreter := range []string{
"pretrans",
"posttrans",
} {
total += EnsureSetScriptletIs(t, scriptlets, interpreter, expectedInterpreter, expectedContent)
}
if total != expectedTotal {
t.Errorf("Saw %d interpreters, but expected %d", total, expectedTotal)
}
}

func TestDefault(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

EnsureSetInterpretersAreAll(r, t, DefaultScriptletInterpreter, "", 0)
EnsureSetLuaInterpretersAreAll(r, t, MagicLuaMarker, "", 0)
}

func TestDefaultScriptletInterpreterWithoutContent(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.SetDefaultScriptletInterpreter(binTest)
EnsureSetInterpretersAreAll(r, t, binTest, "", 0)
EnsureSetLuaInterpretersAreAll(r, t, "", "", 0)
}

func TestAllAdds(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.AddPretrans(i1)
r.AddPrein(echo)
r.AddPostin(echo)
r.AddPreun(echo)
r.AddPostun(echo)
r.AddPosttrans(i1)
r.AddVerifyScript(echo)

EnsureSetInterpretersAreAll(r, t, DefaultScriptletInterpreter, echo, 5)
EnsureSetLuaInterpretersAreAll(r, t, MagicLuaMarker, i1, 2)
r.SetDefaultScriptletInterpreter(binTest)
EnsureSetInterpretersAreAll(r, t, binTest, echo, 5)
}

func TestAllSetInterpreterFor(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.AddPretrans(i1)
r.AddPrein(echo)
r.AddPostin(echo)
r.AddPreun(echo)
r.AddPostun(echo)
r.AddPosttrans(i1)
r.AddVerifyScript(echo)

for _, name := range []string{
"pretrans",
"prein",
"postin",
"preun",
"postun",
"posttrans",
"verifyscript",
} {
r.SetScriptletInterpreterFor(name, binTest)
}

EnsureSetInterpretersAreAll(r, t, binTest, echo, 5)
EnsureSetLuaInterpretersAreAll(r, t, binTest, i1, 2)
}

func TestDefaultScriptletInterpreter(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.SetDefaultScriptletInterpreter(binTest)
r.AddPostun(echo)
r.AddPrein(echo)
r.AddPretrans(i1)
// Only set for non-lua scriptlets
EnsureSetInterpretersAreAll(r, t, binTest, echo, 2)
EnsureSetLuaInterpretersAreAll(r, t, "<lua>", i1, 1)
}

func TestDefaultScriptletInterpreterDoesNotResetSetScriptletInterpreterFor(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.SetDefaultScriptletInterpreter(binTest)
r.AddPrein(echo)
r.SetScriptletInterpreterFor("prein", binother)
r.SetDefaultScriptletInterpreter(binTest)
r.AddPosttrans(i1)
// The SetDefaultScriptletInterpreter does not undo the more specific SetScriptletInterpreterFor
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "prein", binother, echo)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "posttrans", MagicLuaMarker, i1)
}

func TestOverrideLuaInterpreter(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

r.AddPosttrans(i1)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "posttrans", MagicLuaMarker, i1)
r.SetScriptletInterpreterFor("posttrans", binTest)
// Explicit setting of the interpreter for a lua scriptlet:
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "posttrans", binTest, i1)
r.SetDefaultScriptletInterpreter("/foo/bar")
// But not changed again by setting the default interpreter:
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "posttrans", binTest, i1)
}

func TestResetToDefaultInterpreter(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

// verify: change this around
r.AddVerifyScript(echo)
// prein: only modify via SetDefaultScriptletInterpreter. Check that it obeys these settings.
r.AddPrein(echo)
r.SetDefaultScriptletInterpreter(binTest)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "verifyscript", binTest, echo)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "prein", binTest, echo)
r.SetDefaultScriptletInterpreter("")
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "verifyscript", DefaultScriptletInterpreter, echo)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "prein", DefaultScriptletInterpreter, echo)
r.SetScriptletInterpreterFor("verifyscript", binTest)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "verifyscript", binTest, echo)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "prein", DefaultScriptletInterpreter, echo)
r.SetDefaultScriptletInterpreter("")
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "verifyscript", binTest, echo)
EnsureSetScriptletIs(t, r.implicitToExplicitScriptlets(), "prein", DefaultScriptletInterpreter, echo)
}

func TestInvalidInterpreter(t *testing.T) {
r, err := NewRPM(RPMMetaData{})
if err != nil {
t.Fatalf("NewRPM returned error %v", err)
}

if err := r.SetScriptletInterpreterFor("mistake", binTest); err == nil {
t.Fatalf("SetScriptletInterpreterFor with invalid name should return an error")
}
}
Loading