diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/README.md b/src/Microsoft.DotNet.Build.Tasks.Installers/README.md
index 7fede7aa078..a5424064b06 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Installers/README.md
+++ b/src/Microsoft.DotNet.Build.Tasks.Installers/README.md
@@ -37,10 +37,15 @@ To add symlinks that should be installed on the system, add a `LinuxPackageSymli
> Symlinks added with `LinuxPackageSymlink` are relative to the filesystem root, not to the `LinuxInstallRoot` property.
> As the vast majority of symlinks in a package are from system locations to the install root, this provides an easier UX for defining symlinks.
+Add a `LinuxPostInstallScript` item to specify an sh script that should be run after the package is installed.
+Add a `LinuxPostRemoveScript` item to specify an sh script that should be run after the package is removed.
+
#### Deb package configuration
To add additional properties for the deb control file, add `DebControlProperty` items with the value of the field in the `Value` metadata.
+To add additional files to the `control` tarball in the package, add `DebControlFile` items for each file.
+
#### Rpm package configuration
To specify directories owned by the package, add `RpmOwnedDirectory` items for each directory. These are provided automatically for any non-ToolPack packages produced by the Shared Framework SDK.
diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.build.targets b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.build.targets
index d4028780cd0..70b54b187ca 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.build.targets
+++ b/src/Microsoft.DotNet.Build.Tasks.Installers/build/installer.build.targets
@@ -247,6 +247,26 @@
+
+
+
+
+
+
+
+
@@ -293,6 +313,11 @@
+
+ <_RpmScriptlet Include="@(LinuxPostInstallScript)" Kind="Postin" />
+ <_RpmScriptlet Include="@(LinuxPostRmScript)" Kind="Postun" />
+
+
diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateRpmPackage.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateRpmPackage.cs
index c5cb71127e2..3a900d21a89 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateRpmPackage.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateRpmPackage.cs
@@ -61,6 +61,8 @@ public sealed class CreateRpmPackage : BuildTask
public string Description { get; set; } = "";
[Required]
public string PackageUrl { get; set; } = "";
+ [Required]
+ public ITaskItem[] Scripts { get; set; } = [];
public override bool Execute()
{
@@ -109,6 +111,11 @@ public override bool Execute()
HashSet ownedDirectories = new(OwnedDirectories.Select(d => d.ItemSpec));
+ foreach (ITaskItem script in Scripts)
+ {
+ builder.AddScript(script.GetMetadata("Kind"), File.ReadAllText(script.ItemSpec));
+ }
+
using (CpioReader reader = new(File.OpenRead(Payload), leaveOpen: false))
{
Dictionary filePathToKind = RawPayloadFileKinds.Select(k => k.ItemSpec.Split(':')).ToDictionary(k => k[0], k => k[1].Trim());
diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmBuilder.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmBuilder.cs
index 2a3b9870fe2..3d778ebb39f 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmBuilder.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmBuilder.cs
@@ -146,6 +146,13 @@ public void AddFile(CpioEntry file, string fileKind)
_files.Add((file, fileKind));
}
+ private readonly Dictionary _scripts = [];
+
+ public void AddScript(string kind, string script)
+ {
+ _scripts.Add(kind, script);
+ }
+
public string Url { get; set; } = "";
public string Vendor { get; set; } = "";
public string License { get; set; } = "";
@@ -195,6 +202,12 @@ public RpmPackage Build()
entries.Add(new(RpmHeaderTag.Summary, RpmHeaderEntryType.I18NString, Summary));
entries.Add(new(RpmHeaderTag.Description, RpmHeaderEntryType.I18NString, Description));
+ foreach (var script in _scripts)
+ {
+ entries.Add(new((RpmHeaderTag)Enum.Parse(typeof(RpmHeaderTag), script.Key), RpmHeaderEntryType.String, "/bin/sh"));
+ entries.Add(new((RpmHeaderTag)Enum.Parse(typeof(RpmHeaderTag), $"{script.Key}prog"), RpmHeaderEntryType.String, script.Value));
+ }
+
MemoryStream cpioArchive = new();
using (CpioWriter writer = new(cpioArchive, leaveOpen: true))
using (SHA256 sha256 = SHA256.Create())
diff --git a/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderTag.cs b/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderTag.cs
index 27560a8596f..e3a1352e0ea 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderTag.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderTag.cs
@@ -31,6 +31,8 @@ public enum RpmHeaderTag
Url = 1020,
OperatingSystem = 1021,
Architecture = 1022,
+ Postin = 1024,
+ Postun = 1026,
FileSizes = 1028,
FileModes = 1030,
DeviceFileIds = 1033,
@@ -53,6 +55,8 @@ public enum RpmHeaderTag
ChangelogTimestamp = 1080,
ChangelogName = 1081,
ChangelogText = 1082,
+ Postinprog = 1086,
+ Postunprog = 1088,
FileDevices = 1095,
FileInode = 1096,
FileLang = 1097,
@@ -76,4 +80,4 @@ public enum RpmHeaderTag
PayloadDigestAlgorithm = 5093,
UncompressedPayloadDigest = 5097,
}
-}
\ No newline at end of file
+}