func (av *Writer) write(updates []parser.UpdateData) error { av.availableUpdates = updates // write temporary header (we need to know the size before storing in tar) if err := av.WriteHeader(); err != nil { return err } // archive info info := av.getInfo() ia := archiver.NewMetadataArchiver(&info, "info") if err := ia.Archive(av.aArchiver); err != nil { return errors.Wrapf(err, "writer: error archiving info") } // archive header ha := archiver.NewFileArchiver(av.hTmpFile.Name(), "header.tar.gz") if err := ha.Archive(av.aArchiver); err != nil { return errors.Wrapf(err, "writer: error archiving header") } // archive data if err := av.WriteData(); err != nil { return err } // we've been storing everything in temporary file if err := av.aArchiver.Close(); err != nil { return errors.New("writer: error closing archive") } // prevent from closing archiver twice av.aArchiver = nil if err := av.aTmpFile.Close(); err != nil { return errors.New("writer: error closing archive temporary file") } return os.Rename(av.aTmpFile.Name(), av.aName) }
func (rp *RootfsParser) archiveToTmp(tw *tar.Writer, f *os.File) (err error) { gz := gzip.NewWriter(f) defer func() { err = gz.Close() }() dtw := tar.NewWriter(gz) defer func() { err = dtw.Close() }() for _, data := range rp.updates { a := archiver.NewFileArchiver(data.Path, data.Name) if err = a.Archive(dtw); err != nil { return err } } return err }
func (rp *RootfsParser) ArchiveData(tw *tar.Writer, dst string) error { f, err := ioutil.TempFile("", "data") if err != nil { return errors.Wrapf(err, "parser: can not create tmp data file") } defer os.Remove(f.Name()) if err := rp.archiveToTmp(tw, f); err != nil { return errors.Wrapf(err, "parser: error archiving data to tmp file") } a := archiver.NewFileArchiver(f.Name(), dst) if err := a.Archive(tw); err != nil { return err } return nil }
func (s *scriptArch) archScrpt(path string, info os.FileInfo, err error) error { if err != nil { // if there is no `scripts` directory if pErr, ok := err.(*os.PathError); ok && pErr.Err == syscall.ENOENT { return nil } return err } // store only files if info.IsDir() { return nil } // scripts should be always stored in `./scripts/{pre,post,check}/` directory sPath, err := filepath.Rel(filepath.Join(path, "..", ".."), path) if err != nil { return errors.Wrapf(err, "parser: can not archive scripts") } a := archiver.NewFileArchiver(path, filepath.Join(s.dst, sPath)) return a.Archive(s.w) }
func (rp *RootfsParser) ArchiveHeader(tw *tar.Writer, dstDir string, update *UpdateData) error { if update == nil { return errors.New("paser: empty update") } e := new(HeaderElems) if update.Data != nil { var ok bool e, ok = update.Data.(*HeaderElems) if !ok { return errors.New("invalid header elements type") } } // create a updates map with the key being the update file name (without extension) rp.updates = make(map[string]UpdateFile, len(update.DataFiles)) for _, f := range update.DataFiles { rp.updates[withoutExt(f)] = UpdateFile{ Name: filepath.Base(f), Path: f, } } if err := archiveFiles(tw, update.DataFiles, dstDir); err != nil { return errors.Wrapf(err, "parser: can not store files") } if e.TypeInfo == nil { tInfo := metadata.TypeInfo{Type: update.Type} info, err := json.Marshal(&tInfo) if err != nil { return errors.Wrapf(err, "parser: can not create type-info") } e.TypeInfo = info } a := archiver.NewStreamArchiver(e.TypeInfo, filepath.Join(dstDir, "type-info")) if err := a.Archive(tw); err != nil { return errors.Wrapf(err, "parser: can not store type-info") } // if metadata info is not provided we need to have one stored in file if e.Metadata == nil { a := archiver.NewFileArchiver(filepath.Join(update.Path, "meta-data"), filepath.Join(dstDir, "meta-data")) if err := a.Archive(tw); err != nil { return errors.Wrapf(err, "parser: can not store meta-data") } } else { a = archiver.NewStreamArchiver(e.Metadata, filepath.Join(dstDir, "meta-data")) if err := a.Archive(tw); err != nil { return errors.Wrapf(err, "parser: can not store meta-data") } } if err := archiveChecksums(tw, update.DataFiles, filepath.Join(dstDir, "checksums")); err != nil { return err } // scripts if len(e.Scripts) > 0 { for _, scr := range e.Scripts { scrRelPath, err := filepath.Rel(scr, filepath.Dir(filepath.Dir(scr))) if err != nil { return err } a := archiver.NewFileArchiver(scr, filepath.Join(dstDir, "scripts", scrRelPath)) if err := a.Archive(tw); err != nil { return err } } } else { sa := scriptArch{ w: tw, dst: filepath.Join(dstDir, "scripts"), } if err := filepath.Walk(filepath.Join(update.Path, "scripts"), sa.archScrpt); err != nil { return errors.Wrapf(err, "parser: can not archive scripts") } } return nil }