You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/03/09 21:23:23 UTC

[08/50] incubator-mynewt-newt git commit: Move image creation under target.

Move image creation under target.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/b1c09ba2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/b1c09ba2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/b1c09ba2

Branch: refs/heads/develop
Commit: b1c09ba2b7e44cc93c9b97c08379997b655322bb
Parents: 88fe565
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Mar 8 08:03:05 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Mar 8 08:03:05 2016 -0800

----------------------------------------------------------------------
 newt/image/cmds.go   |  73 ----------
 newt/image/image.go  | 329 ----------------------------------------------
 newt/newt.go         |   2 -
 newt/target/cmds.go  |  41 ++++++
 newt/target/image.go | 328 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 369 insertions(+), 404 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b1c09ba2/newt/image/cmds.go
----------------------------------------------------------------------
diff --git a/newt/image/cmds.go b/newt/image/cmds.go
deleted file mode 100644
index 3a10713..0000000
--- a/newt/image/cmds.go
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package image
-
-import (
-	"fmt"
-
-        "github.com/spf13/cobra"
-        "mynewt.apache.org/newt/newt/cli"
-        "mynewt.apache.org/newt/newt/target"
-        "mynewt.apache.org/newt/util"
-)
-
-func createImageRunCmd(cmd *cobra.Command, args []string) {
-	if len(args) < 2 {
-		cli.NewtUsage(cmd, util.NewNewtError("Must specify target and version"))
-	}
-
-	targetName := args[0]
-	t := target.GetTargets()[targetName]
-	if t == nil {
-		cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
-	}
-
-	image, err := NewImage(t)
-	if err != nil {
-		fmt.Println(err)
-	}
-	err = image.SetVersion(args[1])
-	if err != nil {
-		cli.NewtUsage(cmd, err)
-	}
-	err = image.Generate()
-	if err != nil {
-		fmt.Println(err)
-	}
-}
-
-func AddCommands(cmd *cobra.Command) {
-        createImageHelpText := "Create image by adding image header to created "+
-                "binary file for <target-name>. Version number in the header is set "+
-		"to be <version>."
-        createImageHelpEx := "  newt create-image <target-name> <version>\n"
-        createImageHelpEx += "  newt create-image my_target1 1.2.0\n"
-        createImageHelpEx += "  newt create-image my_target1 1.2.0.3\n"
-
-        createImageCmd := &cobra.Command{
-                Use:     "create-image",
-                Short:   "Add image header to target binary",
-                Long:    createImageHelpText,
-                Example: createImageHelpEx,
-                Run:     createImageRunCmd,
-        }
-        cmd.AddCommand(createImageCmd)
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b1c09ba2/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
deleted file mode 100644
index edd3bfd..0000000
--- a/newt/image/image.go
+++ /dev/null
@@ -1,329 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package image
-
-import (
-	"bytes"
-	"crypto/sha256"
-	"encoding/binary"
-	"encoding/json"
-	"fmt"
-	"io"
-	"log"
-	"os"
-	"path/filepath"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"mynewt.apache.org/newt/newt/target"
-	"mynewt.apache.org/newt/util"
-)
-
-type ImageVersion struct {
-	Major    uint8
-	Minor    uint8
-	Rev      uint16
-	BuildNum uint32
-}
-
-type Image struct {
-	target       *target.Target
-
-	sourceBin    string
-	targetImg    string
-	ManifestFile string
-	version      ImageVersion
-
-	hash         []byte
-}
-
-type ImageHdr struct {
-	Magic uint32
-	TlvSz uint32
-	HdrSz uint32
-	ImgSz uint32
-	Flags uint32
-	Vers  ImageVersion
-	Pad   uint32
-}
-
-type ImageTrailerTlv struct {
-	Type uint8
-	Pad  uint8
-	Len  uint16
-}
-
-const (
-	IMAGE_MAGIC = 0x96f3b83c /* Image header magic */
-)
-
-const (
-	IMAGE_HEADER_SIZE = 32
-)
-
-/*
- * Image header flags.
- */
-const (
-	IMAGE_F_PIC        = 0x00000001
-	IMAGE_F_HAS_SHA256 = 0x00000002 /* Image contains hash TLV */
-)
-
-/*
- * Image trailer TLV types.
- */
-const (
-	IMAGE_TLV_SHA256 = 1
-)
-
-/*
- * Data that's going to go to build manifest file
- */
-type ImageManifest struct {
-	Date    string              `json:"build_time"`
-	Version string              `json:"build_version"`
-	Hash    string              `json:"id"`
-	Image   string              `json:"image"`
-	Pkgs    []*ImageManifestPkg `json:"pkgs"`
-	TgtVars []string            `json:"target"`
-}
-
-type ImageManifestPkg struct {
-	Name    string `json:"name"`
-	Version string `json:"version,omitempty"`
-	Hash    string `json:"hash"`
-}
-
-func NewImage(t *target.Target) (*Image, error) {
-	image := &Image{
-		target: t,
-	}
-
-	image.sourceBin = t.ElfPath() + ".bin"
-	image.targetImg = t.ImagePath()
-	return image, nil
-}
-
-func (image *Image) SetVersion(versStr string) error {
-	var err error
-	var major uint64
-	var minor uint64
-	var rev uint64
-	var buildNum uint64
-
-	components := strings.Split(versStr, ".")
-	major, err = strconv.ParseUint(components[0], 10, 8)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
-			versStr))
-	}
-	if len(components) > 1 {
-		minor, err = strconv.ParseUint(components[1], 10, 8)
-		if err != nil {
-			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
-				versStr))
-		}
-	}
-	if len(components) > 2 {
-		rev, err = strconv.ParseUint(components[2], 10, 16)
-		if err != nil {
-			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
-				versStr))
-		}
-	}
-	if len(components) > 3 {
-		buildNum, err = strconv.ParseUint(components[3], 10, 32)
-		if err != nil {
-			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
-				versStr))
-		}
-	}
-	image.version.Major = uint8(major)
-	image.version.Minor = uint8(minor)
-	image.version.Rev = uint16(rev)
-	image.version.BuildNum = uint32(buildNum)
-	log.Printf("[VERBOSE] Assigning version number %d.%d.%d.%d\n",
-		image.version.Major, image.version.Minor,
-		image.version.Rev, image.version.BuildNum)
-
-	buf := new(bytes.Buffer)
-	err = binary.Write(buf, binary.LittleEndian, image.version)
-	if err != nil {
-		fmt.Printf("Bombing out\n")
-		return nil
-	}
-
-	return nil
-}
-
-func (image *Image) Generate() error {
-	binFile, err := os.Open(image.sourceBin)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Can't open target binary %s: %s",
-			image.sourceBin, err.Error()))
-	}
-	defer binFile.Close()
-
-	binInfo, err := binFile.Stat()
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Can't stat target binary %s: %s",
-			image.sourceBin, err.Error()))
-	}
-
-	imgFile, err := os.OpenFile(image.targetImg,
-		os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Can't open target image %s: %s",
-			image.targetImg, err.Error()))
-	}
-	defer imgFile.Close()
-
-	/*
-	 * Compute hash while updating the file.
-	 */
-	hash := sha256.New()
-
-	/*
-	 * First the header
-	 */
-	hdr := &ImageHdr{
-		Magic: IMAGE_MAGIC,
-		TlvSz: 4 + 32,
-		HdrSz: IMAGE_HEADER_SIZE,
-		ImgSz: uint32(binInfo.Size()),
-		Flags: IMAGE_F_HAS_SHA256,
-		Vers:  image.version,
-		Pad:   0,
-	}
-
-	err = binary.Write(imgFile, binary.LittleEndian, hdr)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Failed to serialize image hdr: %s",
-			err.Error()))
-	}
-	err = binary.Write(hash, binary.LittleEndian, hdr)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
-			err.Error()))
-	}
-
-	/*
-	 * Followed by data.
-	 */
-	dataBuf := make([]byte, 1024)
-	for {
-		cnt, err := binFile.Read(dataBuf)
-		if err != nil && err != io.EOF {
-			return util.NewNewtError(fmt.Sprintf("Failed to read from %s: %s",
-				image.sourceBin, err.Error()))
-		}
-		if cnt == 0 {
-			break
-		}
-		_, err = imgFile.Write(dataBuf[0:cnt])
-		if err != nil {
-			return util.NewNewtError(fmt.Sprintf("Failed to write to %s: %s",
-				image.targetImg, err.Error()))
-		}
-		_, err = hash.Write(dataBuf[0:cnt])
-		if err != nil {
-			return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
-				err.Error()))
-		}
-	}
-
-	image.hash = hash.Sum(nil)
-
-	/*
-	 * Trailer with hash of the data
-	 */
-	tlv := &ImageTrailerTlv{
-		Type: IMAGE_TLV_SHA256,
-		Pad:  0,
-		Len:  uint16(len(image.hash)),
-	}
-	err = binary.Write(imgFile, binary.LittleEndian, tlv)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
-			"trailer: %s", err.Error()))
-	}
-	_, err = imgFile.Write(image.hash)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
-			err.Error()))
-	}
-
-	return nil
-}
-
-func (image *Image) CreateManifest() error {
-	versionStr := fmt.Sprintf("%d.%d.%d.%d",
-		image.version.Major, image.version.Minor,
-		image.version.Rev, image.version.BuildNum)
-	hashStr := fmt.Sprintf("%x", image.hash)
-	timeStr := time.Now().Format(time.RFC3339)
-
-	manifest := &ImageManifest{
-		Version: versionStr,
-		Hash:    hashStr,
-		Image:   filepath.Base(image.targetImg),
-		Date:    timeStr,
-	}
-/*
-	for _, builtPkg := range BuiltPkgs {
-		imgPkg := &ImageManifestPkg{
-			Name:    builtPkg.Name,
-			Version: builtPkg.Version,
-			Hash:    builtPkg.Hash,
-		}
-		manifest.Pkgs = append(manifest.Pkgs, imgPkg)
-	}
-*/
-	vars := image.target.Vars
-	var keys []string
-	for k := range vars {
-		keys = append(keys, k)
-	}
-	sort.Strings(keys)
-	for _, k := range keys {
-		manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k])
-	}
-	file, err := os.Create(image.ManifestFile)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Cannot create manifest file %s: %s",
-			image.ManifestFile, err.Error()))
-	}
-	defer file.Close()
-
-	buffer, err := json.MarshalIndent(manifest, "", "  ")
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Cannot encode manifest: %s",
-			err.Error()))
-	}
-	_, err = file.Write(buffer)
-	if err != nil {
-		return util.NewNewtError(fmt.Sprintf("Cannot write manifest file: %s",
-			err.Error()))
-	}
-
-	return nil
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b1c09ba2/newt/newt.go
----------------------------------------------------------------------
diff --git a/newt/newt.go b/newt/newt.go
index 9b05f55..4cb8ad6 100644
--- a/newt/newt.go
+++ b/newt/newt.go
@@ -25,7 +25,6 @@ import (
 
 	"mynewt.apache.org/newt/newt/builder"
 	"mynewt.apache.org/newt/newt/cli"
-	"mynewt.apache.org/newt/newt/image"
 	"mynewt.apache.org/newt/newt/pkg"
 	"mynewt.apache.org/newt/newt/project"
 	"mynewt.apache.org/newt/newt/target"
@@ -92,7 +91,6 @@ func main() {
 	pkg.AddCommands(cmd)
 	target.AddCommands(cmd)
 	builder.AddCommands(cmd)
-	image.AddCommands(cmd)
 
 	cmd.Execute()
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b1c09ba2/newt/target/cmds.go
----------------------------------------------------------------------
diff --git a/newt/target/cmds.go b/newt/target/cmds.go
index 9069574..00bdfae 100644
--- a/newt/target/cmds.go
+++ b/newt/target/cmds.go
@@ -208,6 +208,31 @@ func targetDelCmd(cmd *cobra.Command, args []string) {
 		"Target %s successfully removed\n", args[0])
 }
 
+func createImageRunCmd(cmd *cobra.Command, args []string) {
+	if len(args) < 2 {
+		cli.NewtUsage(cmd, util.NewNewtError("Must specify target and version"))
+	}
+
+	targetName := args[0]
+	t := GetTargets()[targetName]
+	if t == nil {
+		cli.NewtUsage(cmd, util.NewNewtError("Invalid target name"))
+	}
+
+	image, err := NewImage(t)
+	if err != nil {
+		fmt.Println(err)
+	}
+	err = image.SetVersion(args[1])
+	if err != nil {
+		cli.NewtUsage(cmd, err)
+	}
+	err = image.Generate()
+	if err != nil {
+		fmt.Println(err)
+	}
+}
+
 func AddCommands(cmd *cobra.Command) {
 	targetHelpText := ""
 	targetHelpEx := ""
@@ -282,4 +307,20 @@ func AddCommands(cmd *cobra.Command) {
 	}
 
 	targetCmd.AddCommand(delCmd)
+
+        createImageHelpText := "Create image by adding image header to created "+
+                "binary file for <target-name>. Version number in the header is set "+
+		"to be <version>."
+        createImageHelpEx := "  newt create-image <target-name> <version>\n"
+        createImageHelpEx += "  newt create-image my_target1 1.2.0\n"
+        createImageHelpEx += "  newt create-image my_target1 1.2.0.3\n"
+
+        createImageCmd := &cobra.Command{
+                Use:     "create-image",
+                Short:   "Add image header to target binary",
+                Long:    createImageHelpText,
+                Example: createImageHelpEx,
+                Run:     createImageRunCmd,
+        }
+        cmd.AddCommand(createImageCmd)
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b1c09ba2/newt/target/image.go
----------------------------------------------------------------------
diff --git a/newt/target/image.go b/newt/target/image.go
new file mode 100644
index 0000000..1964e5a
--- /dev/null
+++ b/newt/target/image.go
@@ -0,0 +1,328 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package target
+
+import (
+	"bytes"
+	"crypto/sha256"
+	"encoding/binary"
+	"encoding/json"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"mynewt.apache.org/newt/util"
+)
+
+type ImageVersion struct {
+	Major    uint8
+	Minor    uint8
+	Rev      uint16
+	BuildNum uint32
+}
+
+type Image struct {
+	target       *Target
+
+	sourceBin    string
+	targetImg    string
+	ManifestFile string
+	version      ImageVersion
+
+	hash         []byte
+}
+
+type ImageHdr struct {
+	Magic uint32
+	TlvSz uint32
+	HdrSz uint32
+	ImgSz uint32
+	Flags uint32
+	Vers  ImageVersion
+	Pad   uint32
+}
+
+type ImageTrailerTlv struct {
+	Type uint8
+	Pad  uint8
+	Len  uint16
+}
+
+const (
+	IMAGE_MAGIC = 0x96f3b83c /* Image header magic */
+)
+
+const (
+	IMAGE_HEADER_SIZE = 32
+)
+
+/*
+ * Image header flags.
+ */
+const (
+	IMAGE_F_PIC        = 0x00000001
+	IMAGE_F_HAS_SHA256 = 0x00000002 /* Image contains hash TLV */
+)
+
+/*
+ * Image trailer TLV types.
+ */
+const (
+	IMAGE_TLV_SHA256 = 1
+)
+
+/*
+ * Data that's going to go to build manifest file
+ */
+type ImageManifest struct {
+	Date    string              `json:"build_time"`
+	Version string              `json:"build_version"`
+	Hash    string              `json:"id"`
+	Image   string              `json:"image"`
+	Pkgs    []*ImageManifestPkg `json:"pkgs"`
+	TgtVars []string            `json:"target"`
+}
+
+type ImageManifestPkg struct {
+	Name    string `json:"name"`
+	Version string `json:"version,omitempty"`
+	Hash    string `json:"hash"`
+}
+
+func NewImage(t *Target) (*Image, error) {
+	image := &Image{
+		target: t,
+	}
+
+	image.sourceBin = t.ElfPath() + ".bin"
+	image.targetImg = t.ImagePath()
+	return image, nil
+}
+
+func (image *Image) SetVersion(versStr string) error {
+	var err error
+	var major uint64
+	var minor uint64
+	var rev uint64
+	var buildNum uint64
+
+	components := strings.Split(versStr, ".")
+	major, err = strconv.ParseUint(components[0], 10, 8)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+			versStr))
+	}
+	if len(components) > 1 {
+		minor, err = strconv.ParseUint(components[1], 10, 8)
+		if err != nil {
+			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+				versStr))
+		}
+	}
+	if len(components) > 2 {
+		rev, err = strconv.ParseUint(components[2], 10, 16)
+		if err != nil {
+			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+				versStr))
+		}
+	}
+	if len(components) > 3 {
+		buildNum, err = strconv.ParseUint(components[3], 10, 32)
+		if err != nil {
+			return util.NewNewtError(fmt.Sprintf("Invalid version string %s",
+				versStr))
+		}
+	}
+	image.version.Major = uint8(major)
+	image.version.Minor = uint8(minor)
+	image.version.Rev = uint16(rev)
+	image.version.BuildNum = uint32(buildNum)
+	log.Printf("[VERBOSE] Assigning version number %d.%d.%d.%d\n",
+		image.version.Major, image.version.Minor,
+		image.version.Rev, image.version.BuildNum)
+
+	buf := new(bytes.Buffer)
+	err = binary.Write(buf, binary.LittleEndian, image.version)
+	if err != nil {
+		fmt.Printf("Bombing out\n")
+		return nil
+	}
+
+	return nil
+}
+
+func (image *Image) Generate() error {
+	binFile, err := os.Open(image.sourceBin)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Can't open target binary %s: %s",
+			image.sourceBin, err.Error()))
+	}
+	defer binFile.Close()
+
+	binInfo, err := binFile.Stat()
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Can't stat target binary %s: %s",
+			image.sourceBin, err.Error()))
+	}
+
+	imgFile, err := os.OpenFile(image.targetImg,
+		os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Can't open target image %s: %s",
+			image.targetImg, err.Error()))
+	}
+	defer imgFile.Close()
+
+	/*
+	 * Compute hash while updating the file.
+	 */
+	hash := sha256.New()
+
+	/*
+	 * First the header
+	 */
+	hdr := &ImageHdr{
+		Magic: IMAGE_MAGIC,
+		TlvSz: 4 + 32,
+		HdrSz: IMAGE_HEADER_SIZE,
+		ImgSz: uint32(binInfo.Size()),
+		Flags: IMAGE_F_HAS_SHA256,
+		Vers:  image.version,
+		Pad:   0,
+	}
+
+	err = binary.Write(imgFile, binary.LittleEndian, hdr)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Failed to serialize image hdr: %s",
+			err.Error()))
+	}
+	err = binary.Write(hash, binary.LittleEndian, hdr)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
+			err.Error()))
+	}
+
+	/*
+	 * Followed by data.
+	 */
+	dataBuf := make([]byte, 1024)
+	for {
+		cnt, err := binFile.Read(dataBuf)
+		if err != nil && err != io.EOF {
+			return util.NewNewtError(fmt.Sprintf("Failed to read from %s: %s",
+				image.sourceBin, err.Error()))
+		}
+		if cnt == 0 {
+			break
+		}
+		_, err = imgFile.Write(dataBuf[0:cnt])
+		if err != nil {
+			return util.NewNewtError(fmt.Sprintf("Failed to write to %s: %s",
+				image.targetImg, err.Error()))
+		}
+		_, err = hash.Write(dataBuf[0:cnt])
+		if err != nil {
+			return util.NewNewtError(fmt.Sprintf("Failed to hash data: %s",
+				err.Error()))
+		}
+	}
+
+	image.hash = hash.Sum(nil)
+
+	/*
+	 * Trailer with hash of the data
+	 */
+	tlv := &ImageTrailerTlv{
+		Type: IMAGE_TLV_SHA256,
+		Pad:  0,
+		Len:  uint16(len(image.hash)),
+	}
+	err = binary.Write(imgFile, binary.LittleEndian, tlv)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+			"trailer: %s", err.Error()))
+	}
+	_, err = imgFile.Write(image.hash)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
+			err.Error()))
+	}
+
+	return nil
+}
+
+func (image *Image) CreateManifest() error {
+	versionStr := fmt.Sprintf("%d.%d.%d.%d",
+		image.version.Major, image.version.Minor,
+		image.version.Rev, image.version.BuildNum)
+	hashStr := fmt.Sprintf("%x", image.hash)
+	timeStr := time.Now().Format(time.RFC3339)
+
+	manifest := &ImageManifest{
+		Version: versionStr,
+		Hash:    hashStr,
+		Image:   filepath.Base(image.targetImg),
+		Date:    timeStr,
+	}
+/*
+	for _, builtPkg := range BuiltPkgs {
+		imgPkg := &ImageManifestPkg{
+			Name:    builtPkg.Name,
+			Version: builtPkg.Version,
+			Hash:    builtPkg.Hash,
+		}
+		manifest.Pkgs = append(manifest.Pkgs, imgPkg)
+	}
+*/
+	vars := image.target.Vars
+	var keys []string
+	for k := range vars {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k])
+	}
+	file, err := os.Create(image.ManifestFile)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Cannot create manifest file %s: %s",
+			image.ManifestFile, err.Error()))
+	}
+	defer file.Close()
+
+	buffer, err := json.MarshalIndent(manifest, "", "  ")
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Cannot encode manifest: %s",
+			err.Error()))
+	}
+	_, err = file.Write(buffer)
+	if err != nil {
+		return util.NewNewtError(fmt.Sprintf("Cannot write manifest file: %s",
+			err.Error()))
+	}
+
+	return nil
+}