1
0
mirror of https://github.com/projectatomic/atomic.git synced 2026-02-05 09:44:59 +01:00
Files
atomic/gotar.go
Shishir Mahajan aeedcef247 Source code for gotar binary
Signed-off-by: Shishir Mahajan <shishir.mahajan@redhat.com>

Closes: #542
Approved by: giuseppe
2016-08-18 18:33:42 +00:00

165 lines
3.2 KiB
Go

// This source code will generate gotar binary
// which is needed for atomic migrate export and import commands.
package main
import (
"archive/tar"
"io"
"log"
"os"
"path"
"path/filepath"
)
func main() {
if len(os.Args) < 3 {
log.Fatalln("Missing arguments")
}
if os.Args[1] == "" {
log.Fatalln("tar flag cannot be empty. Please use -cf for creation or -xf for extraction")
}
if os.Args[1] != "-cf" && os.Args[1] != "-xf" {
log.Fatalf("%s is not a valid tar flag\n", os.Args[1])
}
if os.Args[2] == "" {
log.Fatalln("Destination filename cannot be empty")
}
if os.Args[1] == "-cf" && os.Args[3] == "" {
log.Fatalln("Source directory cannot be empty")
}
tarFlag := os.Args[1]
destinationFilename := os.Args[2]
if tarFlag == "-cf" {
sourceDir := os.Args[3]
tarDir(destinationFilename, sourceDir)
} else if tarFlag == "-xf" {
untarDir(destinationFilename)
}
}
func checkError(err error) {
if err != nil {
log.Fatalln(err)
}
}
func tarDir(destinationFilename, sourceDir string) {
if destinationFilename[len(destinationFilename)-3:] != "tar" {
log.Fatalln("Please provide a valid tar filename")
}
tarFile, err := os.Create(destinationFilename)
checkError(err)
defer tarFile.Close()
var fileWriter io.WriteCloser = tarFile
tarfileWriter := tar.NewWriter(fileWriter)
defer tarfileWriter.Close()
walkTar(sourceDir, tarfileWriter)
}
func walkTar(dirPath string, tarfileWriter *tar.Writer) {
dir, err := os.Open(dirPath)
checkError(err)
dirInfo, err := dir.Stat()
checkError(err)
// prepare the tar header for dir entry.
dheader, err := tar.FileInfoHeader(dirInfo, "")
checkError(err)
dheader.Name = dir.Name()[1:]
err = tarfileWriter.WriteHeader(dheader)
checkError(err)
files, err := dir.Readdir(0) // grab the files list
checkError(err)
for _, fileInfo := range files {
if fileInfo.IsDir() {
walkTar(path.Join(dir.Name(), fileInfo.Name()), tarfileWriter)
} else {
file, err := os.Open(dir.Name() + string(filepath.Separator) + fileInfo.Name())
checkError(err)
defer file.Close()
// prepare the tar header for file entry.
header, err := tar.FileInfoHeader(fileInfo, "")
checkError(err)
header.Name = file.Name()[1:]
err = tarfileWriter.WriteHeader(header)
checkError(err)
_, err = io.Copy(tarfileWriter, file)
checkError(err)
}
}
}
func untarDir(destinationFilename string) {
var fileReader io.ReadCloser
if destinationFilename == "-" {
fileReader = os.Stdin
} else {
if destinationFilename[len(destinationFilename)-3:] != "tar" {
log.Fatalln("Please provide a valid tar filename")
}
file, err := os.Open(destinationFilename)
checkError(err)
defer file.Close()
fileReader = file
}
tarfileReader := tar.NewReader(fileReader)
pwd, err := os.Getwd()
checkError(err)
for {
header, err := tarfileReader.Next()
if err != nil {
if err == io.EOF {
break
}
log.Fatalln(err)
}
fileInfo := header.FileInfo()
if fileInfo.IsDir() {
err = os.MkdirAll(path.Join(pwd, header.Name), fileInfo.Mode())
checkError(err)
} else {
tarFile, err := os.Create(path.Join(pwd, header.Name))
checkError(err)
defer tarFile.Close()
_, err = io.Copy(tarFile, tarfileReader)
checkError(err)
}
}
}