From Fedora Project Wiki
(New Feature Page (WIP))
 
Line 3: Line 3:
== Summary ==
== Summary ==
Replace RPM useradd/groupadd shell script fragments in spec files which dedicated RPM macros.
Replace RPM useradd/groupadd shell script fragments in spec files which dedicated RPM macros.
<code>
# rpmbuild --define "_sourcedir $(pwd)" --define "_specdir $(pwd)" --define "_builddir $(pwd)" --define "_srcrpmdir $(pwd)" --define "_rpmdir $(pwd)" -ba test.spec && rpm -qp --scripts noarch/*.rpm
#################################################################
# macros.sysusers
#################################################################
%define sysusers_useradd(n:S:c:d:g:G:lmMNors:u:UZ:) %{lua:
  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  if package ~= "" then
      name = name .. "_" .. package
  end
 
  local oldlines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  local group = rpm.expand("%{?-g*}")
  local gecko = rpm.expand("%{?-c*}%{?!-c*:-}")
  local home = rpm.expand("%{?-d*}%{!-d*:-}")
  local shell = rpm.expand("%{?-s*}%{!-s*:-}")
  local uid = rpm.expand("%{?-u*}%{!-u*:-}")
  local user = rpm.expand("%{1}")
  local moregroups = rpm.expand("%{?-G*}")
 
  newline = "%{quote:u\\t" .. user .. "\\t" .. uid .. "\\t" .. gecko .. "\\t" .. home .. "\\t" .. shell .. "}"
  if group ~= "" then
      newline = newline .. "%{quote:m\\t" .. user .. "\\t" .. group .. "}"
  end
  for group in string.gmatch(moregroups, "[^,]*,?") do
      if string.sub(group,-1) == "," then group = string.sub(group, 0, -2) end
      newline = newline .. "%{quote:m\\t" .. user .. "\\t" .. group .. "}"
  end
  if oldlines == "" then
      rpm.define("sysusers_useradd_" .. name .. " " .. newline)
  else
      rpm.define("sysusers_useradd_" .. name .. " " .. oldlines .. newline)
  end
 
}
%define sysusers_groupadd(n:S:g:rfoB:N:) %{lua:
  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  if package ~= "" then
      name = name .. "_" .. package
  end
  local oldlines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  local gid = rpm.expand("%{?-g*}%{!-g*:-}")
  local group = rpm.expand("%{1}")
  newline = "%{quote:g\\t" .. group .. "\\t" .. gid .. "\\t-}"
  if oldlines == "" then
      rpm.define("sysusers_useradd_" .. name .. " " .. newline)
  else
      rpm.define("sysusers_useradd_" .. name .. " " .. oldlines .. newline)
  end
}
%define sysusers_pre(n:S:) %{lua:
  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  local filename = name
  if package ~= "" then
      filename = name .. "-" .. package
      name = name .. "_" .. package
  end
  local lines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  print("systemd-sysusers --replace=" .. rpm.expand("%{_sysusersdir}/") .. filename .. ".conf - <<EOF\\n")
  for line in string.gmatch(lines, "\\31[^\\31]*\\31") do print(string.sub(line, 2, -2) .."\\n")  end
  print("EOF\\n")
}
%define sysusers_install(n:S:) %{lua:
  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  local filename = name
  if package ~= "" then
      filename = name .. "-" .. package
      name = name .. "_" .. package
  end
  local lines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  print("mkdir -p " .. rpm.expand("%{buildroot}") .. rpm.expand("%{_sysusersdir}/") .. "\\n")
  print("cat >" .. rpm.expand("%{buildroot}") .. rpm.expand("%{_sysusersdir}/") .. filename .. ".conf <<EOF\\n")
  for line in string.gmatch(lines, "\\31[^\\31]*\\31") do print(string.sub(line, 2, -2) .."\\n") end
  print("EOF\\n")
}
########################################################################################
Name:          test
Version:        1
Release:        1
Summary:        test
License:        MIT
BuildArch:      noarch
%sysusers_groupadd -r -g 11 group1
%sysusers_groupadd -r -g 12 group2
%sysusers_groupadd -r -g 13 group3
%sysusers_groupadd -r -g 14 group4
%sysusers_useradd -r -g group1 -G group3,group4 -u 100 -d /var/user1 -s /sbin/nologin -c %{quote:"User 1"} user1
%sysusers_useradd -r -g group2 -G group3,group4 -u 101 -d /var/user2 -s /sbin/nologin -c %{quote:"User 2"} user2
%description
%package sub
Summary:        sub
%sysusers_groupadd -S sub -r -g 21 subgroup1
%description sub
%package -n foo
Summary:        foo
%sysusers_groupadd -n foo -r -g 31 foo1
%description -n foo
%pre
%sysusers_pre
%pre sub
%sysusers_pre -S sub
%pre -n foo
%sysusers_pre -n foo
%prep
%build
%install
%sysusers_install
%sysusers_install -n foo
%sysusers_install -S sub
%files
%{_sysusersdir}/%{name}.conf
%files sub
%{_sysusersdir}/%{name}-sub.conf
%files -n foo
%{_sysusersdir}/foo.conf
</code>


== Owner ==
== Owner ==

Revision as of 14:39, 8 November 2018

Streamline useradd/groupadd calls in RPM spec files

Summary

Replace RPM useradd/groupadd shell script fragments in spec files which dedicated RPM macros.

  1. rpmbuild --define "_sourcedir $(pwd)" --define "_specdir $(pwd)" --define "_builddir $(pwd)" --define "_srcrpmdir $(pwd)" --define "_rpmdir $(pwd)" -ba test.spec && rpm -qp --scripts noarch/*.rpm
  1. macros.sysusers

%define sysusers_useradd(n:S:c:d:g:G:lmMNors:u:UZ:) %{lua:

  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  if package ~= "" then
     name = name .. "_" .. package
  end
  
  local oldlines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  local group = rpm.expand("%{?-g*}")
  local gecko = rpm.expand("%{?-c*}%{?!-c*:-}")
  local home = rpm.expand("%{?-d*}%{!-d*:-}")
  local shell = rpm.expand("%{?-s*}%{!-s*:-}")
  local uid = rpm.expand("%{?-u*}%{!-u*:-}")
  local user = rpm.expand("%{1}")
  local moregroups = rpm.expand("%{?-G*}")
  
  newline = "%{quote:u\\t" .. user .. "\\t" .. uid .. "\\t" .. gecko .. "\\t" .. home .. "\\t" .. shell .. "}"
  if group ~= "" then
     newline = newline .. "%{quote:m\\t" .. user .. "\\t" .. group .. "}"
  end
  for group in string.gmatch(moregroups, "[^,]*,?") do
     if string.sub(group,-1) == "," then group = string.sub(group, 0, -2) end
     newline = newline .. "%{quote:m\\t" .. user .. "\\t" .. group .. "}"
  end


  if oldlines == "" then
     rpm.define("sysusers_useradd_" .. name .. " " .. newline)
  else
     rpm.define("sysusers_useradd_" .. name .. " " .. oldlines .. newline)
  end


}

%define sysusers_groupadd(n:S:g:rfoB:N:) %{lua:

  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  if package ~= "" then
     name = name .. "_" .. package
  end
  local oldlines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  local gid = rpm.expand("%{?-g*}%{!-g*:-}")
  local group = rpm.expand("%{1}")
  newline = "%{quote:g\\t" .. group .. "\\t" .. gid .. "\\t-}"
  if oldlines == "" then
     rpm.define("sysusers_useradd_" .. name .. " " .. newline)
  else
     rpm.define("sysusers_useradd_" .. name .. " " .. oldlines .. newline)
  end

}

%define sysusers_pre(n:S:) %{lua:

  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  local filename = name
  if package ~= "" then
     filename = name .. "-" .. package
     name = name .. "_" .. package
  end
  local lines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  print("systemd-sysusers --replace=" .. rpm.expand("%{_sysusersdir}/") .. filename .. ".conf - <<EOF\\n")
  for line in string.gmatch(lines, "\\31[^\\31]*\\31") do print(string.sub(line, 2, -2) .."\\n")  end
  print("EOF\\n")

}

%define sysusers_install(n:S:) %{lua:

  local package = rpm.expand("%{?-S*}")
  local name = rpm.expand("%{?!-n*:%{name}}%{?-n*}")
  local filename = name
  if package ~= "" then
     filename = name .. "-" .. package
     name = name .. "_" .. package
  end
  local lines = rpm.expand("%{?sysusers_useradd_" .. name .. "}")
  print("mkdir -p " .. rpm.expand("%{buildroot}") .. rpm.expand("%{_sysusersdir}/") .. "\\n")
  print("cat >" .. rpm.expand("%{buildroot}") .. rpm.expand("%{_sysusersdir}/") .. filename .. ".conf <<EOF\\n")
  for line in string.gmatch(lines, "\\31[^\\31]*\\31") do print(string.sub(line, 2, -2) .."\\n") end
  print("EOF\\n")

}

Name: test Version: 1 Release: 1 Summary: test License: MIT BuildArch: noarch

%sysusers_groupadd -r -g 11 group1 %sysusers_groupadd -r -g 12 group2 %sysusers_groupadd -r -g 13 group3 %sysusers_groupadd -r -g 14 group4 %sysusers_useradd -r -g group1 -G group3,group4 -u 100 -d /var/user1 -s /sbin/nologin -c %{quote:"User 1"} user1 %sysusers_useradd -r -g group2 -G group3,group4 -u 101 -d /var/user2 -s /sbin/nologin -c %{quote:"User 2"} user2

%description

%package sub Summary: sub %sysusers_groupadd -S sub -r -g 21 subgroup1 %description sub

%package -n foo Summary: foo %sysusers_groupadd -n foo -r -g 31 foo1 %description -n foo


%pre %sysusers_pre

%pre sub %sysusers_pre -S sub

%pre -n foo %sysusers_pre -n foo

%prep %build %install %sysusers_install %sysusers_install -n foo %sysusers_install -S sub

%files %{_sysusersdir}/%{name}.conf

%files sub %{_sysusersdir}/%{name}-sub.conf

%files -n foo %{_sysusersdir}/foo.conf

Owner

Current status

  • Targeted release: Fedora 30
  • Tracker bug: <will be assigned by the Wrangler>

Detailed Description

Storing the user and group information in structured data allows to process this data with external tools in a programmatic way instead of running opaque shell scripts.

Benefit to Fedora

Scope

  • Proposal owners:
  • Other developers: N/A (not a System Wide Change)
  • Policies and guidelines: N/A (not a System Wide Change)
  • Trademark approval: N/A (not needed for this Change)

Upgrade/compatibility impact

N/A (not a System Wide Change)

How To Test

N/A (not a System Wide Change)

User Experience

Dependencies

N/A (not a System Wide Change)

Contingency Plan

  • Contingency mechanism: (What to do? Who will do it?) N/A (not a System Wide Change)
  • Contingency deadline: N/A (not a System Wide Change)
  • Blocks release? N/A (not a System Wide Change), Yes/No
  • Blocks product? product

Documentation

N/A (not a System Wide Change)

Release Notes