Skip to content

Commit

Permalink
deb: Fix content file modes to support gdebi, etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgeiser committed Feb 4, 2025
1 parent 14dcdfe commit 067a99a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
29 changes: 15 additions & 14 deletions deb/deb.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +394,20 @@ func createFilesInsideDataTar(info *nfpm.Info, tw *tar.Writer) (md5buf bytes.Buf
// skip ghost files in deb
continue
case files.TypeDir, files.TypeImplicitDir:
err = tw.WriteHeader(&tar.Header{
Name: files.AsExplicitRelativePath(file.Destination),
Mode: int64(file.FileInfo.Mode),
Typeflag: tar.TypeDir,
Format: tar.FormatGNU,
Uname: file.FileInfo.Owner,
Gname: file.FileInfo.Group,
ModTime: modtime.Get(info.MTime),
})
header, headerErr := tar.FileInfoHeader(file, "") // headerErr to avoid shadowing err
if err != nil {
return md5buf, 0, fmt.Errorf("build directory header: %w", headerErr)
}

Check warning on line 400 in deb/deb.go

View check run for this annotation

Codecov / codecov/patch

deb/deb.go#L399-L400

Added lines #L399 - L400 were not covered by tests

// we need to change the type from file to dir because
// tar.FileInfoHEader thinks it is a file because the file mode does
// not contain type flags and in this case, it ignores file.IsDir().
header.Typeflag = tar.TypeDir
header.Name = files.AsExplicitRelativePath(file.Destination)
header.Format = tar.FormatGNU
header.ModTime = modtime.Get(info.MTime)

err = tw.WriteHeader(header)
case files.TypeSymlink:
err = newItemInsideTar(tw, []byte{}, &tar.Header{
Name: files.AsExplicitRelativePath(file.Destination),
Expand Down Expand Up @@ -438,13 +443,9 @@ func copyToTarAndDigest(file *files.Content, tw *tar.Writer, md5w io.Writer) (in
return 0, err
}

// tar.FileInfoHeader only uses file.Mode().Perm() which masks the mode with
// 0o777 which we don't want because we want to be able to set the suid bit.
header.Mode = int64(file.Mode())
header.Format = tar.FormatGNU
header.Name = files.AsExplicitRelativePath(file.Destination)
header.Uname = file.FileInfo.Owner
header.Gname = file.FileInfo.Group

if err := tw.WriteHeader(header); err != nil {
return 0, fmt.Errorf("cannot write header of %s to data.tar.gz: %w", file.Source, err)
}
Expand Down
19 changes: 18 additions & 1 deletion files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ type Content struct {
Expand bool `yaml:"expand,omitempty" json:"expand,omitempty"`
}

// FileInfoNames is used to make sure *Content satisfies tar.FileInfoNames.
type FileInfoNames interface {
fs.FileInfo
Uname() (string, error)
Gname() (string, error)
}

var _ FileInfoNames = &Content{}

type ContentFileInfo struct {
Owner string `yaml:"owner,omitempty" json:"owner,omitempty"`
Group string `yaml:"group,omitempty" json:"group,omitempty"`
Expand Down Expand Up @@ -183,7 +192,15 @@ func (c *Content) ModTime() time.Time {

// IsDir to part of the os.FileInfo interface
func (c *Content) IsDir() bool {
return false
return c.Type == TypeDir || c.Type == TypeImplicitDir

Check warning on line 195 in files/files.go

View check run for this annotation

Codecov / codecov/patch

files/files.go#L195

Added line #L195 was not covered by tests
}

func (c *Content) Uname() (string, error) {
return c.FileInfo.Owner, nil
}

func (c *Content) Gname() (string, error) {
return c.FileInfo.Group, nil
}

// Sys to part of the os.FileInfo interface
Expand Down

0 comments on commit 067a99a

Please sign in to comment.