Skip to content
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
4 changes: 2 additions & 2 deletions docs/design/assetgeneration.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ type File struct {
// to read specific file(s) from disk.
type FileFetcher interface {
// FetchByName returns the file with the given name.
FetchByName(string) *File
// FetchByPattern returns the files whose name match the given regexp.
FetchByName(string) (*File, error)
// FetchByPattern returns the files whose name match the given glob.
FetchByPattern(*regexp.Regexp) ([]*File, error)
}
```
Expand Down
11 changes: 8 additions & 3 deletions pkg/asset/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,13 @@ func (c *Cluster) Files() []*asset.File {
// Load returns error if the tfstate file is already on-disk, because we want to
// prevent user from accidentally re-launching the cluster.
func (c *Cluster) Load(f asset.FileFetcher) (found bool, err error) {
if f.FetchByName(stateFileName) != nil {
return true, fmt.Errorf("%q already exisits", stateFileName)
_, err = f.FetchByName(stateFileName)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
return false, nil

return true, fmt.Errorf("%q already exisits. There may already be a running cluster", stateFileName)
}
11 changes: 8 additions & 3 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cluster

import (
"os"

"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/ignition/bootstrap"
"github.com/openshift/installer/pkg/asset/ignition/machine"
Expand Down Expand Up @@ -77,9 +79,12 @@ func (t *TerraformVariables) Files() []*asset.File {

// Load reads the terraform.tfvars from disk.
func (t *TerraformVariables) Load(f asset.FileFetcher) (found bool, err error) {
file := f.FetchByName(tfvarsFilename)
if file == nil {
return false, nil
file, err := f.FetchByName(tfvarsFilename)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

t.File = file
Expand Down
83 changes: 28 additions & 55 deletions pkg/asset/filefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,56 @@ package asset

import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"sort"
)

// FileFetcher fetches the asset files from disk.
type FileFetcher interface {
// FetchByName returns the file with the given name.
FetchByName(string) *File
// FetchByPattern returns the files whose name match the given regexp.
FetchByPattern(*regexp.Regexp) []*File
FetchByName(string) (*File, error)
// FetchByPattern returns the files whose name match the given glob.
FetchByPattern(pattern string) ([]*File, error)
}

type fileFetcher struct {
onDiskAssets map[string][]byte
directory string
}

func newFileFetcher(clusterDir string) (*fileFetcher, error) {
fileMap := make(map[string][]byte)

// Don't bother if the clusterDir is not created yet because that
// means there's no assets generated yet.
_, err := os.Stat(clusterDir)
if err != nil && os.IsNotExist(err) {
return &fileFetcher{}, nil
// FetchByName returns the file with the given name.
func (f *fileFetcher) FetchByName(name string) (*File, error) {
data, err := ioutil.ReadFile(filepath.Join(f.directory, name))
if err != nil {
return nil, err
}
return &File{Filename: name, Data: data}, nil
}

if err := filepath.Walk(clusterDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}
// FetchByPattern returns the files whose name match the given regexp.
func (f *fileFetcher) FetchByPattern(pattern string) (files []*File, err error) {
matches, err := filepath.Glob(filepath.Join(f.directory, pattern))
if err != nil {
return nil, err
}

filename, err := filepath.Rel(clusterDir, path)
files = make([]*File, 0, len(matches))
for _, path := range matches {
data, err := ioutil.ReadFile(path)
if err != nil {
return err
return nil, err
}

data, err := ioutil.ReadFile(path)
filename, err := filepath.Rel(f.directory, path)
if err != nil {
return err
return nil, err
}

fileMap[filename] = data
return nil
}); err != nil {
return nil, err
}
return &fileFetcher{onDiskAssets: fileMap}, nil
}

// FetchByName returns the file with the given name.
func (f *fileFetcher) FetchByName(name string) *File {
data, ok := f.onDiskAssets[name]
if !ok {
return nil
}
return &File{Filename: name, Data: data}
}

// FetchByPattern returns the files whose name match the given regexp.
func (f *fileFetcher) FetchByPattern(re *regexp.Regexp) []*File {
var files []*File

for filename, data := range f.onDiskAssets {
if re.MatchString(filename) {
files = append(files, &File{
Filename: filename,
Data: data,
})
}
files = append(files, &File{
Filename: filename,
Data: data,
})
}

sort.Slice(files, func(i, j int) bool { return files[i].Filename < files[j].Filename })
return files
return files, nil
}
137 changes: 82 additions & 55 deletions pkg/asset/filefetcher_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package asset

import (
"fmt"
"regexp"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -15,18 +16,6 @@ func TestFetchByName(t *testing.T) {
input string
expectFile *File
}{
{
name: "only dirs",
files: nil,
input: "",
expectFile: nil,
},
{
name: "input empty",
files: map[string][]byte{"foo.bar": []byte("some data")},
input: "",
expectFile: nil,
},
{
name: "input doesn't match",
files: map[string][]byte{"foo.bar": []byte("some data")},
Expand Down Expand Up @@ -55,43 +44,89 @@ func TestFetchByName(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &fileFetcher{onDiskAssets: tt.files}
file := f.FetchByName(tt.input)
tempDir, err := ioutil.TempDir("", "openshift-install-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)

for filename, data := range tt.files {
err = ioutil.WriteFile(filepath.Join(tempDir, filename), data, 0666)
if err != nil {
t.Fatal(err)
}
}

f := &fileFetcher{directory: tempDir}
file, err := f.FetchByName(tt.input)
if err != nil {
if os.IsNotExist(err) && tt.expectFile == nil {
return
}
t.Fatal(err)
}

assert.Equal(t, tt.expectFile, file)
})
}
}

func TestFetchByPattern(t *testing.T) {
tempDir, err := ioutil.TempDir("", "openshift-install-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)

files := map[string][]byte{
"master-0.ign": []byte("some data 0"),
"master-1.ign": []byte("some data 1"),
"master-2.ign": []byte("some data 2"),
"master-10.ign": []byte("some data 3"),
"master-20.ign": []byte("some data 4"),
"master-00.ign": []byte("some data 5"),
"master-01.ign": []byte("some data 6"),
"amaster-0.ign": []byte("some data 7"),
"master-.ign": []byte("some data 8"),
"master-.igni": []byte("some data 9"),
"master-.ignign": []byte("some data 10"),
"manifests/0": []byte("some data 11"),
"manifests/some": []byte("some data 12"),
"amanifests/a": []byte("some data 13"),
}

for path, data := range files {
dir := filepath.Dir(path)
if dir != "." {
err := os.MkdirAll(filepath.Join(tempDir, dir), 0777)
if err != nil {
t.Fatal(err)
}
}
err = ioutil.WriteFile(filepath.Join(tempDir, path), data, 0666)
if err != nil {
t.Fatal(err)
}
}
tests := []struct {
name string
files map[string][]byte
input *regexp.Regexp
input string
expectFiles []*File
}{
{
name: "match master configs",
files: map[string][]byte{
"master-0.ign": []byte("some data 0"),
"master-1.ign": []byte("some data 1"),
"master-2.ign": []byte("some data 2"),
"master-10.ign": []byte("some data 3"),
"master-20.ign": []byte("some data 4"),
"master-00.ign": []byte("some data 5"),
"master-01.ign": []byte("some data 6"),
"master-0x.ign": []byte("some data 7"),
"master-1x.ign": []byte("some data 8"),
"amaster-0.ign": []byte("some data 9"),
"master-.ign": []byte("some data 10"),
"master-.igni": []byte("some data 11"),
"master-.ignign": []byte("some data 12"),
},
input: regexp.MustCompile(`^(master-(0|([1-9]\d*))\.ign)$`),
input: "master-[0-9]*.ign",
expectFiles: []*File{
{
Filename: "master-0.ign",
Data: []byte("some data 0"),
},
{
Filename: "master-00.ign",
Data: []byte("some data 5"),
},
{
Filename: "master-01.ign",
Data: []byte("some data 6"),
},
{
Filename: "master-1.ign",
Data: []byte("some data 1"),
Expand All @@ -111,37 +146,29 @@ func TestFetchByPattern(t *testing.T) {
},
},
{
name: "match directory",
files: map[string][]byte{
"manifests/": []byte("some data 0"),
"manifests/0": []byte("some data 1"),
"manifests/some": []byte("some data 2"),
"manifest/": []byte("some data 3"),
"manifests": []byte("some data 4"),
"amanifests/a": []byte("some data 5"),
},
input: regexp.MustCompile(fmt.Sprintf(`^%s\%c.*`, "manifests", '/')),
input: filepath.Join("manifests", "*"),
expectFiles: []*File{
{
Filename: "manifests/",
Data: []byte("some data 0"),
},
{
Filename: "manifests/0",
Data: []byte("some data 1"),
Data: []byte("some data 11"),
},
{
Filename: "manifests/some",
Data: []byte("some data 2"),
Data: []byte("some data 12"),
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &fileFetcher{onDiskAssets: tt.files}
assert.Equal(t, tt.expectFiles, f.FetchByPattern(tt.input))
t.Run(tt.input, func(t *testing.T) {
f := &fileFetcher{directory: tempDir}
files, err := f.FetchByPattern(tt.input)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, tt.expectFiles, files)
})
}
}
9 changes: 6 additions & 3 deletions pkg/asset/ignition/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,12 @@ func applyTemplateData(template *template.Template, templateData interface{}) st

// Load returns the bootstrap ignition from disk.
func (a *Bootstrap) Load(f asset.FileFetcher) (found bool, err error) {
file := f.FetchByName(bootstrapIgnFilename)
if file == nil {
return false, nil
file, err := f.FetchByName(bootstrapIgnFilename)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

config := &igntypes.Config{}
Expand Down
6 changes: 4 additions & 2 deletions pkg/asset/ignition/machine/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package machine
import (
"encoding/json"
"fmt"
"regexp"

igntypes "github.com/coreos/ignition/config/v2_2/types"
"github.com/pkg/errors"
Expand Down Expand Up @@ -67,7 +66,10 @@ func (a *Master) Files() []*asset.File {

// Load returns the master ignitions from disk.
func (a *Master) Load(f asset.FileFetcher) (found bool, err error) {
fileList := f.FetchByPattern(regexp.MustCompile(`^(master-(0|([1-9]\d*))\.ign)$`))
fileList, err := f.FetchByPattern("master-[0-9]*.ign")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a discussion that this matches more than we need, e.g. it matches master-0a.ign, but I guess that's fine.

Copy link
Member Author

@wking wking Oct 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a discussion that this matches more than we need, e.g. it matches master-0a.ign...

Yeah, I waved my hands around that at the end of the edcd705 commit message ;).

if err != nil {
return false, nil
}
if len(fileList) == 0 {
return false, nil
}
Expand Down
Loading