1
0
mirror of https://github.com/kairos-io/kairos-sdk.git synced 2025-05-03 13:46:25 +00:00
kairos-sdk/iso/extract.go
Itxaka 24873605ca
Add method to extract files from an iso ()
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-28 09:09:48 +01:00

90 lines
2.3 KiB
Go

package iso
import (
"fmt"
"github.com/diskfs/go-diskfs"
"github.com/kairos-io/kairos-sdk/types"
"io"
"os"
"path/filepath"
"strings"
)
// ExtractFileFromIso will extract a given file from a given iso to a given destination
func ExtractFileFromIso(file, iso, destination string, logger *types.KairosLogger) (err error) {
if logger == nil {
l := types.NewNullLogger()
logger = &l
}
// set a sublogger with the args
log := logger.Logger.With().Str("file", file).Str("iso", iso).Str("destination", destination).Logger()
_, err = os.Stat(iso)
if err != nil {
log.Error().Err(err).Msg("checking iso file")
return fmt.Errorf("error checking on %s: %s", iso, err.Error())
}
if !isFullPath(file) {
log.Error().Err(err).Msg("file to extract is not a full path")
return fmt.Errorf("%s is not a full path", file)
}
log.Trace().Msg("Opening iso file")
log.Debug().Msg("Extracting file from iso")
open, err := diskfs.Open(iso)
if err != nil {
log.Error().Err(err).Msg("opening iso file")
return err
}
log.Trace().Msg("Getting filesystem")
fs, err := open.GetFilesystem(0)
if err != nil {
log.Error().Err(err).Msg("getting filesystem")
return err
}
log.Trace().Msg("Opening file inside iso")
isoFile, err := fs.OpenFile(file, os.O_RDONLY)
if err != nil {
log.Error().Err(err).Msg("opening file inside iso")
return err
}
defer isoFile.Close()
log.Trace().Msg("Opening destination file")
destFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Error().Err(err).Msg("creating destination file")
return err
}
defer destFile.Close()
log.Trace().Msg("Copying file to destination")
// Copy isoFile to destFile
_, err = io.Copy(destFile, isoFile)
if err != nil {
log.Error().Err(err).Msg("copying file to destination")
return err
}
log.Debug().Msg("File extracted from iso")
return err
}
// isFullPath checks a given path to see if its absolute
// removes any relative thingies like .. or .../
// checks that it starts with /
// checks that we dont refer to the full root dir
func isFullPath(path string) bool {
if path == "" {
return false
}
if !strings.HasPrefix(path, "/") {
return false
}
cleaned := filepath.Clean(path)
if !filepath.IsAbs(cleaned) {
return false
}
if cleaned == "/" {
return false
}
return len(strings.Split(cleaned, "/")) > 1
}