Skip to content

Commit

Permalink
Add support for setting uid/gid from pkg_attributes (#671)
Browse files Browse the repository at this point in the history
This enables the user to produce identical tarballs to fix
#670

Signed-off-by: Austin Schuh <[email protected]>
Co-authored-by: aiuto <[email protected]>
  • Loading branch information
AustinSchuh and aiuto authored May 1, 2023
1 parent 0aa9277 commit e7a1ba1
Show file tree
Hide file tree
Showing 16 changed files with 211 additions and 67 deletions.
9 changes: 6 additions & 3 deletions docs/latest.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,22 @@ attributes = pkg_attributes(
mode = "0644",
user = "root",
group = "wheel",
uid = 5,
gid = 7,
my_custom_attribute = "some custom value",
)
```

`mode`, `user`, and `group` correspond to common UNIX-style filesystem
permissions. Attributes should always be specified using the `pkg_attributes`
helper macro.
permissions. `uid` and `gid` correspond to the numeric uid/gid. Attributes
should always be specified using the `pkg_attributes` helper macro.

Each mapping rule has some default mapping attributes. At this time, the only
default is "mode", which will be set if it is not otherwise overridden by the user.

If `user` and `group` are not specified, then defaults for them will be chosen
by the underlying package builder. Any specific behavior from package builders
by the underlying package builder. If `uid` and `gid` are not specified,
they will default to 0. Any specific behavior from package builders
should not be relied upon.

Any other attributes should be specified as additional arguments to
Expand Down
18 changes: 11 additions & 7 deletions pkg/install.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ def _pkg_install_script_impl(ctx):
files_to_run = []
content_map = {}
for src in ctx.attr.srcs:
process_src(content_map,
files_to_run,
src = src,
origin = src.label,
default_mode = "0644",
default_user = None,
default_group = None)
process_src(
content_map,
files_to_run,
src = src,
origin = src.label,
default_mode = "0644",
default_user = None,
default_group = None,
default_uid = None,
default_gid = None,
)

manifest_file = ctx.actions.declare_file(ctx.attr.name + "-install-manifest.json")

Expand Down
33 changes: 28 additions & 5 deletions pkg/mappings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,21 @@ strip_prefix = struct(
from_root = _sp_from_root,
)

def pkg_attributes(mode = None, user = None, group = None, **kwargs):
def pkg_attributes(
mode = None,
user = None,
group = None,
uid = None,
gid = None,
**kwargs):
"""Format attributes for use in package mapping rules.
If "mode" is not provided, it will default to the mapping rule's default
mode. These vary per mapping rule; consult the respective documentation for
more details.
Not providing any of "user", or "group" will result in the package builder
choosing one for you. The chosen value should not be relied upon.
Not providing any of "user", "group", "uid", or "gid" will result in the package
builder choosing one for you. The chosen value should not be relied upon.
Well-known attributes outside of the above are documented in the rules_pkg
reference.
Expand All @@ -90,8 +96,10 @@ def pkg_attributes(mode = None, user = None, group = None, **kwargs):
Args:
mode: string: UNIXy octal permissions, as a string.
user: string: Filesystem owning user.
group: string: Filesystem owning group.
user: string: Filesystem owning user name.
group: string: Filesystem owning group name.
uid: int: Filesystem owning user id.
gid: int: Filesystem owning group id.
**kwargs: any other desired attributes.
Returns:
Expand All @@ -105,6 +113,21 @@ def pkg_attributes(mode = None, user = None, group = None, **kwargs):
ret["user"] = user
if group:
ret["group"] = group
if uid != None:
if type(uid) != type(0):
fail('Got "' + str(uid) + '" instead of integer uid')
ret["uid"] = uid
if gid != None:
if type(gid) != type(0):
fail('Got "' + str(gid) + '" instead of integer gid')
ret["gid"] = gid

if user != None and user.isdigit() and uid == None:
print("Warning: found numeric username and no uid, did you mean to specify the uid instead?")

if group != None and group.isdigit() and gid == None:
print("Warning: found numeric group and no gid, did you mean to specify the gid instead?")

return json.encode(ret)

####
Expand Down
6 changes: 5 additions & 1 deletion pkg/private/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,19 @@ class ManifestEntry(object):
mode: str
user: str
group: str
uid: int
gid: int
origin: str = None

def __init__(self, type, dest, src, mode, user, group, origin = None):
def __init__(self, type, dest, src, mode, user, group, uid = None, gid = None, origin = None):
self.type = type
self.dest = dest
self.src = src
self.mode = mode
self.user = user
self.group = group
self.uid = uid
self.gid = gid
self.origin = origin

def __repr__(self):
Expand Down
Loading

0 comments on commit e7a1ba1

Please sign in to comment.