Skip to content
Closed
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
6 changes: 3 additions & 3 deletions cmd/openshift-install/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func newCreateCmd() *cobra.Command {
}

func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args []string) {
runner := func(directory string) error {
runner := func(fcos bool, directory string) error {
assetStore, err := assetstore.NewStore(directory)
if err != nil {
return errors.Wrap(err, "failed to create asset store")
Expand All @@ -151,7 +151,7 @@ func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args
err = errors.Wrapf(err, "failed to fetch %s", a.Name())
}

if err2 := asset.PersistToFile(a, directory); err2 != nil {
if err2 := asset.PersistToFile(a, directory, fcos); err2 != nil {
err2 = errors.Wrapf(err2, "failed to write asset (%s) to disk", a.Name())
if err != nil {
logrus.Error(err2)
Expand All @@ -171,7 +171,7 @@ func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args
cleanup := setupFileHook(rootOpts.dir)
defer cleanup()

err := runner(rootOpts.dir)
err := runner(rootOpts.fcos, rootOpts.dir)
if err != nil {
logrus.Fatal(err)
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/openshift-install/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var (
rootOpts struct {
dir string
logLevel string
fcos bool
}
)

Expand Down Expand Up @@ -71,6 +72,7 @@ func newRootCmd() *cobra.Command {
}
cmd.PersistentFlags().StringVar(&rootOpts.dir, "dir", ".", "assets directory")
cmd.PersistentFlags().StringVar(&rootOpts.logLevel, "log-level", "info", "log level (e.g. \"debug | info | warn | error\")")
cmd.PersistentFlags().BoolVar(&rootOpts.fcos, "fcos", false, "set to true to generate ignition v3 configs")
return cmd
}

Expand Down
67 changes: 66 additions & 1 deletion pkg/asset/asset.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package asset

import (
"encoding/json"
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"

"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -46,19 +48,82 @@ type File struct {

// PersistToFile writes all of the files of the specified asset into the specified
// directory.
func PersistToFile(asset WritableAsset, directory string) error {
func PersistToFile(asset WritableAsset, directory string, fcos bool) error {
for _, f := range asset.Files() {
path := filepath.Join(directory, f.Filename)
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return errors.Wrap(err, "failed to create dir")
}
if fcos && strings.HasSuffix(f.Filename, ".ign") {
// Run transpiler here
spec3data, err := convertSpec2ToSpec3(f.Data)
if err != nil {
return errors.Wrap(err, "failed to convert spec2 to spec3")
}
f.Data = spec3data
}
if err := ioutil.WriteFile(path, f.Data, 0644); err != nil {
return errors.Wrap(err, "failed to write file")
}
}
return nil
}

func convertSpec2ToSpec3(spec2data []byte) ([]byte, error) {
// Unmarshal
jsonMap := make(map[string]interface{})
err := json.Unmarshal(spec2data, &jsonMap)
if err != nil {
return nil, errors.Wrap(err, "failed to Marshal Ignition config")
}

// Replace ignition.version
ign := jsonMap["ignition"].(map[string]interface{})
ign["version"] = "3.0.0"

// ignition.config.append -> ignition.config.merge
config := ign["config"].(map[string]interface{})
if val, ok := config["append"]; ok {
config["merge"] = val
delete(config, "append")
}
ign["config"] = config
jsonMap["ignition"] = ign

// Delete networkd section
if _, ok := jsonMap["networkd"]; ok {
delete(jsonMap, "networkd")
}

// Remove filesystem in storage.files
if sval, ok := jsonMap["storage"]; ok {
storage := sval.(map[string]interface{})

if fval, ok := storage["files"]; ok {
files := fval.([]interface{})

updatedFiles := make([]interface{}, 0)

for i := range files {
file := files[i].(map[string]interface{})
if _, ok := file["filesystem"]; ok {
delete(file, "filesystem")
}
updatedFiles = append(updatedFiles, file)
}
storage["files"] = updatedFiles
}
jsonMap["storage"] = storage
}

// Convert to bytes
spec3data, err := json.Marshal(jsonMap)
if err != nil {
return nil, errors.Wrap(err, "failed to Marshal Ignition config")
}
return spec3data, nil
}

// DeleteAssetFromDisk removes all the files for asset from disk.
// this is function is not safe for calling concurrently on the same directory.
func DeleteAssetFromDisk(asset WritableAsset, directory string) error {
Expand Down
27 changes: 26 additions & 1 deletion pkg/asset/asset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,47 @@ func TestPersistToFile(t *testing.T) {
cases := []struct {
name string
filenames []string
fcos bool
}{
{
name: "no files",
filenames: []string{},
fcos: false,
},
{
name: "single file",
filenames: []string{"file1"},
fcos: false,
},
{
name: "multiple files",
filenames: []string{"file1", "file2"},
fcos: false,
},
{
name: "new directory",
filenames: []string{"dir1/file1"},
fcos: false,
},
{
name: "no files spec3",
filenames: []string{},
fcos: true,
},
{
name: "single file spec3",
filenames: []string{"file1"},
fcos: true,
},
{
name: "multiple files spec3",
filenames: []string{"file1", "file2"},
fcos: true,
},
{
name: "new directory",
filenames: []string{"dir1/file1"},
fcos: true,
},
}
for _, tc := range cases {
Expand All @@ -79,7 +104,7 @@ func TestPersistToFile(t *testing.T) {
}
expectedFiles[filepath.Join(dir, filename)] = data
}
err = PersistToFile(asset, dir)
err = PersistToFile(asset, dir, tc.fcos)
assert.NoError(t, err, "unexpected error persisting state to file")
verifyFilesCreated(t, dir, expectedFiles)
})
Expand Down
7 changes: 6 additions & 1 deletion pkg/asset/store/assetcreate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,27 @@ func TestCreatedAssetsAreNotDirty(t *testing.T) {
cases := []struct {
name string
targets []asset.WritableAsset
fcos bool
}{
{
name: "install config",
targets: targets.InstallConfig,
fcos: false,
},
{
name: "manifest templates",
targets: targets.ManifestTemplates,
fcos: false,
},
{
name: "manifests",
targets: targets.Manifests,
fcos: false,
},
{
name: "ignition configs",
targets: targets.IgnitionConfigs,
fcos: false,
},
}
for _, tc := range cases {
Expand All @@ -76,7 +81,7 @@ func TestCreatedAssetsAreNotDirty(t *testing.T) {
t.Fatalf("failed to fetch %q: %v", a.Name(), err)
}

if err := asset.PersistToFile(a, tempDir); err != nil {
if err := asset.PersistToFile(a, tempDir, tc.fcos); err != nil {
t.Fatalf("failed to write asset %q to disk: %v", a.Name(), err)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ func TestStoreFetchIdempotency(t *testing.T) {
if !assert.NoError(t, err, "(loop %d) unexpected error fetching asset %q", a.Name()) {
t.Fatal()
}
err = asset.PersistToFile(a, tempDir)
err = asset.PersistToFile(a, tempDir, false)
if !assert.NoError(t, err, "(loop %d) unexpected error persisting asset %q", a.Name()) {
t.Fatal()
}
Expand Down