Skip to content

Commit

Permalink
Merge pull request #178 from gustavosbarreto/limit_reader
Browse files Browse the repository at this point in the history
installifdifferent: use limit reader if object has explicit size
  • Loading branch information
otavio authored Nov 21, 2017
2 parents 5a88505 + f9c8979 commit 2bbf3c8
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 5 deletions.
13 changes: 11 additions & 2 deletions installifdifferent/installifdifferent.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package installifdifferent

import (
"fmt"
"io"
"os"

"github.com/OSSystems/pkg/log"
Expand Down Expand Up @@ -70,7 +71,15 @@ func (iid *DefaultImpl) Proceed(o metadata.Object) (bool, error) {
case map[string]interface{}:
log.Info("checking pattern")
// is object, so is a Pattern
return installIfDifferentPattern(iid.FileSystemBackend, target, value)
var rs io.ReadSeeker

if o.GetObjectMetadata().Size > 0 {
rs = utils.LimitReader(target, o.GetObjectMetadata().Size)
} else {
rs = target
}

return installIfDifferentPattern(iid.FileSystemBackend, rs, value)
}

finalErr := fmt.Errorf("unknown install-if-different format")
Expand All @@ -95,7 +104,7 @@ func installIfDifferentSha256Sum(fsb afero.Fs, target afero.File, sha256sum stri
return true, nil
}

func installIfDifferentPattern(fsb afero.Fs, target afero.File, pattern map[string]interface{}) (bool, error) {
func installIfDifferentPattern(fsb afero.Fs, target io.ReadSeeker, pattern map[string]interface{}) (bool, error) {
p, err := NewPatternFromInstallIfDifferentObject(fsb, pattern)
if err != nil {
finalErr := fmt.Errorf("failed to parse install-if-different object: %s", err)
Expand Down
4 changes: 2 additions & 2 deletions installifdifferent/kernelfileinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type KernelFileInfo struct {
FileSystemBackend afero.Fs
}

func NewKernelFileInfo(fsb afero.Fs, file afero.File) *KernelFileInfo {
func NewKernelFileInfo(fsb afero.Fs, file io.ReadSeeker) *KernelFileInfo {
kfi := &KernelFileInfo{FileSystemBackend: fsb}

if isARMzImage(file) {
Expand Down Expand Up @@ -195,7 +195,7 @@ func (kfi *KernelFileInfo) captureVersion(fsh utils.FileSystemHelper, file io.Re
return ""
}

func CaptureTextFromBinaryFile(file afero.File, regularExpression string) string {
func CaptureTextFromBinaryFile(file io.ReadSeeker, regularExpression string) string {
trailing := make([]byte, 4)
bytesRead := make([]byte, 1)
index := 0
Expand Down
2 changes: 1 addition & 1 deletion installifdifferent/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (p *Pattern) IsValid() bool {
return false
}

func (p *Pattern) Capture(target afero.File) (string, error) {
func (p *Pattern) Capture(target io.ReadSeeker) (string, error) {
switch p.Type {
case LinuxKernelPattern:
kfi := NewKernelFileInfo(p.FileSystemBackend, target)
Expand Down
1 change: 1 addition & 0 deletions metadata/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type ObjectMetadata struct {

Sha256sum string `json:"sha256sum"`
Mode string `json:"mode"`
Size int64 `json:"size"`
Compressed bool `json:"bool"`
InstallIfDifferent interface{} `json:"install-if-different,omitempty"`
}
Expand Down
35 changes: 35 additions & 0 deletions utils/limitedreader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package utils

import (
"io"
"reflect"
)

type LimitedReader struct {
R io.ReadSeeker
N int64
}

func (l *LimitedReader) Read(p []byte) (n int, err error) {
if l.N <= 0 {
return 0, io.EOF
}

if int64(len(p)) > l.N {
p = p[0:l.N]
}

n, err = l.R.Read(p)
l.N -= int64(n)

return
}

func (l *LimitedReader) Seek(offset int64, whence int) (int64, error) {
l.N = reflect.ValueOf(l.R).Elem().FieldByName("i").Int()
return l.R.Seek(offset, whence)
}

func LimitReader(r io.ReadSeeker, n int64) io.ReadSeeker {
return &LimitedReader{R: r, N: n}
}
65 changes: 65 additions & 0 deletions utils/limitedreader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package utils

import (
"bytes"
"io"
"io/ioutil"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLimitReader(t *testing.T) {
n := int64(3)
rd := bytes.NewReader([]byte("bytes"))
lr := LimitReader(rd, n)

assert.Equal(t, rd, lr.(*LimitedReader).R)
assert.Equal(t, n, lr.(*LimitedReader).N)
}

func TestLimitReaderRead(t *testing.T) {
n := int64(3)
rd := bytes.NewReader([]byte("bytes"))
lr := LimitReader(rd, n)

limitedBytes, err := ioutil.ReadAll(lr)
assert.NoError(t, err)

bytes := make([]byte, n)

rd.Seek(0, io.SeekStart)

_, err = rd.Read(bytes)

assert.NoError(t, err)
assert.Equal(t, int64(0), lr.(*LimitedReader).N)
assert.Equal(t, bytes, limitedBytes)
}

func TestLimitReaderSeek(t *testing.T) {
n := int64(3)
skip := int64(1)
rd := bytes.NewReader([]byte("bytes"))
lr := LimitReader(rd, n)

_, err := ioutil.ReadAll(lr)
assert.NoError(t, err)

lr.Seek(skip, io.SeekStart)

assert.Equal(t, n, lr.(*LimitedReader).N)

limitedBytes, err := ioutil.ReadAll(lr)
assert.NoError(t, err)

bytes := make([]byte, n)

rd.Seek(skip, io.SeekStart)

_, err = rd.Read(bytes)

assert.NoError(t, err)
assert.Equal(t, int64(0), lr.(*LimitedReader).N)
assert.Equal(t, bytes, limitedBytes)
}

0 comments on commit 2bbf3c8

Please sign in to comment.