mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-18 04:27:06 +02:00
This fixes A/B upgrades and rollback API. Installer manifest supports now an option to preserve partition contents while disk is being re-partitioned and partitions are re-formatted. Mount `/boot` partition as needed (to find current label before starting the installation and in the rollback API). Fix upgrade API for non-master nodes. Contents of `/boot`, `/system/state` and META partitions are preserved in memory while the disk is re-partitioned. Remove `--save` flag from the installer as it's not being used. Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package archiver
|
|
|
|
import (
|
|
"archive/tar"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/talos-systems/talos/pkg/safepath"
|
|
)
|
|
|
|
// Untar extracts .tar archive from r into filesystem under rootPath.
|
|
//
|
|
//nolint: gocyclo
|
|
func Untar(ctx context.Context, r io.Reader, rootPath string) error {
|
|
tr := tar.NewReader(r)
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
default:
|
|
}
|
|
|
|
hdr, err := tr.Next()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
|
|
return fmt.Errorf("error reading tar header: %s", err)
|
|
}
|
|
|
|
hdrPath := safepath.CleanPath(hdr.Name)
|
|
if hdrPath == "" {
|
|
return fmt.Errorf("empty tar header path")
|
|
}
|
|
|
|
path := filepath.Join(rootPath, hdrPath)
|
|
|
|
switch hdr.Typeflag {
|
|
case tar.TypeDir:
|
|
mode := hdr.FileInfo().Mode()
|
|
mode |= 0o700 // make rwx for the owner
|
|
|
|
if err = os.Mkdir(path, mode); err != nil {
|
|
return fmt.Errorf("error creating directory %q mode %s: %w", path, mode, err)
|
|
}
|
|
|
|
if err = os.Chmod(path, mode); err != nil {
|
|
return fmt.Errorf("error updating mode %s for %q: %w", mode, path, err)
|
|
}
|
|
|
|
case tar.TypeSymlink:
|
|
if err = os.Symlink(hdr.Linkname, path); err != nil {
|
|
return fmt.Errorf("error creating symlink %q -> %q: %w", path, hdr.Linkname, err)
|
|
}
|
|
|
|
default:
|
|
mode := hdr.FileInfo().Mode()
|
|
|
|
fp, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_EXCL, mode)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating file %q mode %s: %w", path, mode, err)
|
|
}
|
|
|
|
_, err = io.Copy(fp, tr)
|
|
if err != nil {
|
|
return fmt.Errorf("error copying data to %q: %w", path, err)
|
|
}
|
|
|
|
if err = fp.Close(); err != nil {
|
|
return fmt.Errorf("error closing %q: %w", path, err)
|
|
}
|
|
|
|
if err = os.Chmod(path, mode); err != nil {
|
|
return fmt.Errorf("error updating mode %s for %q: %w", mode, path, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|