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

feat: provide more field support for rpms #79

Merged
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fmt:
.PHONY: fmt

lint: check
./bin/golangci-lint run --disable godox --enable-all ./...
./bin/golangci-lint run --disable wsl --disable godox --enable-all ./...
djgilcrease marked this conversation as resolved.
Show resolved Hide resolved
.PHONY: check

ci: build lint test
Expand Down
44 changes: 32 additions & 12 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package acceptance

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
Expand All @@ -21,7 +22,7 @@ var formats = []string{"deb", "rpm"}
func TestSimple(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s", format),
Expand All @@ -30,7 +31,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.dockerfile", format),
})
})
t.Run("i386", func(t *testing.T) {
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_386", format),
Expand All @@ -39,7 +40,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.386.dockerfile", format),
})
})
t.Run("ppc64le", func(t *testing.T) {
t.Run(fmt.Sprintf("ppc64le-%s", format), func(t *testing.T) {
t.Skip("for some reason travis fails to run those")
t.Parallel()
accept(t, acceptParms{
Expand All @@ -49,7 +50,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.ppc64le.dockerfile", format),
})
})
t.Run("arm64", func(t *testing.T) {
t.Run(fmt.Sprintf("arm64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_arm64", format),
Expand All @@ -64,7 +65,7 @@ func TestSimple(t *testing.T) {
func TestComplex(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s", format),
Expand All @@ -73,7 +74,7 @@ func TestComplex(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.complex.dockerfile", format),
})
})
t.Run("i386", func(t *testing.T) {
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s_386", format),
Expand All @@ -85,10 +86,10 @@ func TestComplex(t *testing.T) {
}
}

func TestComplexOverridesDeb(t *testing.T) {
func TestComplexOverrides(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("overrides_%s", format),
Expand All @@ -100,10 +101,10 @@ func TestComplexOverridesDeb(t *testing.T) {
}
}

func TestMinDeb(t *testing.T) {
func TestMin(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("min_%s", format),
Expand Down Expand Up @@ -186,8 +187,27 @@ func accept(t *testing.T, params acceptParms) {
".",
)
cmd.Dir = "./testdata"
stdout, err := cmd.StdoutPipe()
require.NoError(t, err)
stderr, err := cmd.StderrPipe()
require.NoError(t, err)
t.Log("will exec:", cmd.Args)
bts, err := cmd.CombinedOutput()
t.Log("output:", string(bts))
err = cmd.Start()
require.NoError(t, err)

var slurp []byte
slurp, err = ioutil.ReadAll(stderr)
if len(slurp) > 0 {
t.Log("stderr:", string(slurp))
djgilcrease marked this conversation as resolved.
Show resolved Hide resolved
}
require.NoError(t, err)

slurp, err = ioutil.ReadAll(stdout)
if len(slurp) > 0 {
t.Log("stdout:", string(slurp))
}
require.NoError(t, err)

err = cmd.Wait()
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b
github.com/stretchr/testify v1.4.0
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 // indirect
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.2.4
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4A
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4=
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
129 changes: 105 additions & 24 deletions rpm/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,24 @@ func ensureValidArch(info nfpm.Info) nfpm.Info {

// Package writes a new RPM package to the given writer using the given info
func (*RPM) Package(info nfpm.Info, w io.Writer) error {
var (
err error
meta *rpmpack.RPMMetaData
rpm *rpmpack.RPM
)
info = ensureValidArch(info)
err := nfpm.Validate(info)
if err != nil {
if err = nfpm.Validate(info); err != nil {
return err
}

vInfo := strings.SplitN(info.Version, "-", 1)
vInfo = append(vInfo, "")
rpm, err := rpmpack.NewRPM(rpmpack.RPMMetaData{
Name: info.Name,
Version: vInfo[0],
Release: vInfo[1],
Arch: info.Arch,
})
if err != nil {
if meta, err = buildRPMMeta(info); err != nil {
return err
}
if rpm, err = rpmpack.NewRPM(*meta); err != nil {
return err
}

addEmptyDirsRPM(info, rpm)
if err = createFilesInsideRPM(info, rpm); err != nil {
return err
}
Expand All @@ -75,6 +75,65 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
return nil
}

func buildRPMMeta(info nfpm.Info) (*rpmpack.RPMMetaData, error) {
var (
err error
provides,
depends,
replaces,
suggests,
conflicts rpmpack.Relations
)
vInfo := strings.SplitN(info.Version, "-", 2)
vInfo = append(vInfo, info.RPM.Release)

if provides, err = toRelation(info.Provides); err != nil {
return nil, err
}
if depends, err = toRelation(info.Depends); err != nil {
return nil, err
}
if replaces, err = toRelation(info.Replaces); err != nil {
return nil, err
}
if suggests, err = toRelation(info.Suggests); err != nil {
return nil, err
}
if conflicts, err = toRelation(info.Conflicts); err != nil {
return nil, err
}

return &rpmpack.RPMMetaData{
Name: info.Name,
Description: info.Description,
Version: vInfo[0],
Release: vInfo[1],
Arch: info.Arch,
OS: info.Platform,
Licence: info.License,
URL: info.Homepage,
Vendor: info.Vendor,
Packager: info.Maintainer,
Provides: provides,
Requires: depends,
Obsoletes: replaces,
Suggests: suggests,
Conflicts: conflicts,
Compressor: info.RPM.Compression,
}, nil
}

func toRelation(items []string) (rpmpack.Relations, error) {
relations := make(rpmpack.Relations, 0)
for idx := range items {
if err := relations.Set(items[idx]); err != nil {
return nil, err
}
}

return relations, nil
}

func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
if info.Scripts.PreInstall != "" {
data, err := ioutil.ReadFile(info.Scripts.PreInstall)
Expand All @@ -101,7 +160,7 @@ func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
}

if info.Scripts.PostRemove != "" {
data, err := ioutil.ReadFile(info.Scripts.PostInstall)
data, err := ioutil.ReadFile(info.Scripts.PostRemove)
if err != nil {
return err
}
Expand All @@ -111,28 +170,45 @@ func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
return nil
}

func addEmptyDirsRPM(info nfpm.Info, rpm *rpmpack.RPM) {
for _, dir := range info.EmptyFolders {
rpm.AddFile(
rpmpack.RPMFile{
Name: dir,
Mode: uint(1 | 040000),
})
}
}

func createFilesInsideRPM(info nfpm.Info, rpm *rpmpack.RPM) error {
for _, files := range []map[string]string{
info.Files,
info.ConfigFiles,
} {
copy := func(files map[string]string, config bool) error {
for srcglob, dstroot := range files {
globbed, err := glob.Glob(srcglob, dstroot)
if err != nil {
return err
}
for src, dst := range globbed {
err := copyToRPM(rpm, src, dst)
err := copyToRPM(rpm, src, dst, config)
if err != nil {
return err
}
}
}

return nil
}
err := copy(info.Files, false)
if err != nil {
return err
}
err = copy(info.ConfigFiles, true)
if err != nil {
return err
}
return nil
}

func copyToRPM(rpm *rpmpack.RPM, src, dst string) error {
func copyToRPM(rpm *rpmpack.RPM, src, dst string, config bool) error {
file, err := os.OpenFile(src, os.O_RDONLY, 0600) //nolint:gosec
if err != nil {
return errors.Wrap(err, "could not add file to the archive")
Expand All @@ -152,12 +228,17 @@ func copyToRPM(rpm *rpmpack.RPM, src, dst string) error {
return err
}

rpm.AddFile(
rpmpack.RPMFile{
Name: dst,
Body: data,
Mode: uint(info.Mode()),
})
rpmFile := rpmpack.RPMFile{
Name: dst,
Body: data,
Mode: uint(info.Mode()),
}

if config {
rpmFile.Type = rpmpack.ConfigFile
}

rpm.AddFile(rpmFile)

return nil
}