-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Container.init.ps1
111 lines (93 loc) · 3.91 KB
/
Container.init.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<#
.SYNOPSIS
Initializes a container during build.
.DESCRIPTION
Initializes the container image with the necessary modules and packages.
This script should be called from the Dockerfile, during the creation of the container image.
~~~Dockerfile
# Thank you Microsoft! Thank you PowerShell! Thank you Docker!
FROM mcr.microsoft.com/powershell
# Set the shell to PowerShell (thanks again, Docker!)
SHELL ["/bin/pwsh", "-nologo", "-command"]
# Run the initialization script. This will do all remaining initialization in a single layer.
RUN --mount=type=bind,src=./,target=/Initialize ./Initialize/Container.init.ps1
~~~
The scripts arguments can be provided with either an `ARG` or `ENV` instruction in the Dockerfile.
.NOTES
Did you know that in PowerShell you can 'use' namespaces that do not really exist?
This seems like a nice way to describe a relationship to a container image.
That is why this file is using the namespace 'mcr.microsoft.com/powershell'.
(this does nothing, but most likely will be used in the future)
#>
using namespace 'mcr.microsoft.com/powershell AS powershell'
param(
# The name of the module to be installed.
[string]$ModuleName = $(
if ($env:ModuleName) { $env:ModuleName }
else {
(Get-ChildItem -Path $PSScriptRoot |
Where-Object Extension -eq '.psd1' |
Select-String 'ModuleVersion\s=' |
Select-Object -ExpandProperty Path -First 1) -replace '\.psd1$'
}
),
# The packages to be installed.
[string[]]$InstallAptGet = @($env:InstallAptGet -split ','),
# The modules to be installed.
[string[]]$InstallModule = @($env:InstallModule -split ','),
# The Ruby gems to be installed.
[string[]]$InstallRubyGem = @($env:InstallRubyGem -split ','),
# If set, will keep the .git directories.
[switch]$KeepGit = $($env:KeepGit -match $true)
)
# Copy all container-related scripts to the root of the container.
Get-ChildItem -Path $PSScriptRoot |
Where-Object Name -Match '^Container\..+?\.ps1$' |
Copy-Item -Destination /
# Create a profile
New-Item -Path $Profile -ItemType File -Force | Out-Null
if ($ModuleName) {
# Get the root module directory
$rootModuleDirectory = @($env:PSModulePath -split '[;:]')[0]
# Determine the path to the module destination.
$moduleDestination = "$rootModuleDirectory/$ModuleName"
# Copy the module to the destination
# (this is being used instead of the COPY statement in Docker, to avoid additional layers).
Copy-Item -Path "$psScriptRoot" -Destination $moduleDestination -Recurse -Force
# and import this module in the profile
Add-Content -Path $profile -Value "Import-Module $ModuleName" -Force
}
# If we have modules to install
if ($InstallModule) {
# Install the modules
Install-Module -Name $InstallModule -Force -AcceptLicense -Scope CurrentUser
# and import them in the profile
Add-Content -Path $Profile -Value "Import-Module '$($InstallModule -join "','")'" -Force
}
# If we have packages to install
if ($InstallAptGet) {
# install the packages
apt-get update &&
apt-get install -y @InstallAptGet '--no-install-recommends' &&
apt-get clean |
Out-Host
}
if ($InstallRubyGem) {
# Install the Ruby gems
gem install @InstallRubyGem
}
if ($ModuleName) {
# In our profile, push into the module's directory
Add-Content -Path $Profile -Value "Get-Module $ModuleName | Split-Path | Push-Location" -Force
}
if (-not $KeepGit) {
# Remove the .git directories from any modules
Get-ChildItem -Path $rootModuleDirectory -Directory -Force -Recurse |
Where-Object Name -eq '.git' |
Remove-Item -Recurse -Force
}
# Congratulations! You have successfully initialized the container image.
# This script should work in about any module, with minor adjustments.
# If you have any adjustments, please put them below here, in the `#region Custom`
#region Custom
#endregion Custom