Skip to content

Commit 8371520

Browse files
committed
Added PS script to build cloudbase-init from sources
Change-Id: I3750d5777abf8d2f56d98c20232801ed647d1aab
1 parent 4b0d94c commit 8371520

2 files changed

Lines changed: 290 additions & 0 deletions

File tree

scripts/Readme.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
### Requirements ###
2+
3+
#### Clean Windows Server 2016 /2019 or Windows 10 install with latest updates
4+
5+
#### Python 3.7 installed and added to path (with pip installed).
6+
Download link: https://www.python.org/ftp/python/3.7.7/python-3.7.7-amd64.exe
7+
8+
#### Visual Studio 2015 Community installed, with the following components:
9+
- Programming Languages -> Visual C++ (all)
10+
- Windows and Web Development -> Windows 8.1 (only Tools and Windows SDKs)
11+
12+
VS 2015 Download link (you need to be logged in to access it): https://download.my.visualstudio.com/db/en_visual_studio_community_2015_with_update_1_x86_x64_web_installer_8234321.exe
13+
If you prefer to not build pywin32, Visual Studio 2017 / 2019 can be used too.
14+
Reboot after VS installation is complete.
15+
16+
#### All the Python packages will be built and installed using pip flags: "--no-binary :all:"
17+
18+
## The full build of cloudbase-init (and dependencies) from sources takes around 10 minutes.
19+
20+
#### How to run:
21+
22+
23+
```powershell
24+
.\build_install_from_sources.ps1 `
25+
-CloudbaseInitRepoUrl "https://github.com/cloudbase/cloudbase-init" `
26+
-PyWin32RepoUrl "https://github.com/mhammond/pywin32" `
27+
-PyMiRepoUrl "https://github.com/cloudbase/PyMI" `
28+
-BuildDir "build"
29+
30+
```
31+
32+
33+
#### Workflow of the script:
34+
- Download and set pip upper requirements from OpenStack
35+
- Create / clean temporary build directory
36+
- Build and install PyWin32 from sources
37+
- Build and install PyMI from sources
38+
- Build, install and create Cloudbase-Init binary from sources
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
#ps1
2+
param(
3+
[string]$CloudbaseInitRepoUrl="https://github.com/cloudbase/cloudbase-init",
4+
[string]$PyWin32RepoUrl="https://github.com/mhammond/pywin32",
5+
[string]$PyMiRepoUrl="https://github.com/cloudbase/PyMI",
6+
[string]$BuildDir=""
7+
)
8+
9+
$ErrorActionPreference = "Stop"
10+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
11+
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
12+
13+
$PIP_BUILD_NO_BINARIES_ARGS = "--no-binary :all:"
14+
15+
function Run-CmdWithRetry {
16+
param(
17+
$command,
18+
[int]$maxRetryCount=3,
19+
[int]$retryInterval=1
20+
)
21+
22+
$currErrorActionPreference = $ErrorActionPreference
23+
$ErrorActionPreference = "Continue"
24+
25+
$retryCount = 0
26+
while ($true) {
27+
try {
28+
& $command
29+
break
30+
} catch [System.Exception] {
31+
$retryCount++
32+
if ($retryCount -ge $maxRetryCount) {
33+
$ErrorActionPreference = $currErrorActionPreference
34+
throw
35+
} else {
36+
Write-Error $_.Exception
37+
Start-Sleep $retryInterval
38+
}
39+
}
40+
}
41+
42+
$ErrorActionPreference = $currErrorActionPreference
43+
}
44+
45+
function Download-File {
46+
param(
47+
$url,
48+
$dest
49+
)
50+
51+
Write-Host "Downloading: $url"
52+
53+
$webClient = New-Object System.Net.webclient
54+
Run-CmdWithRetry {
55+
$webClient.DownloadFile($url, $dest)
56+
}
57+
}
58+
59+
function Set-VCVars {
60+
param(
61+
$Version="14.0",
62+
$Platform="x86_amd64"
63+
)
64+
65+
Write-Host "Setting Visual Studio version ${Version} environment variables"
66+
67+
Push-Location "$ENV:ProgramFiles (x86)\Microsoft Visual Studio ${Version}\VC\"
68+
try {
69+
cmd /c "vcvarsall.bat $platform & set" |
70+
ForEach-Object {
71+
if ($_ -match "=") {
72+
$v = $_.split("=")
73+
Set-Item -Force -Path "ENV:\$($v[0])" -Value "$($v[1])"
74+
}
75+
}
76+
} finally {
77+
Pop-Location
78+
}
79+
}
80+
81+
function Run-Command {
82+
param(
83+
$cmd,
84+
$arguments,
85+
$expectedExitCode = 0
86+
)
87+
88+
Write-Host "Executing: $cmd $arguments"
89+
90+
$p = Start-Process -Wait -PassThru `
91+
-NoNewWindow $cmd -ArgumentList $arguments
92+
if ($p.ExitCode -ne $expectedExitCode) {
93+
throw "$cmd failed with exit code: $($p.ExitCode)"
94+
}
95+
}
96+
97+
function Clone-Repo {
98+
param(
99+
$Url,
100+
$Destination
101+
)
102+
103+
Write-Host "Cloning ${Url} to ${Destination}"
104+
105+
Run-CmdWithRetry {
106+
try {
107+
Push-Location $BuildDir
108+
git clone $Url $Destination
109+
if ($LastExitCode) {
110+
throw "git clone ${Url} ${Destination} failed"
111+
}
112+
} finally {
113+
Pop-Location
114+
}
115+
}
116+
}
117+
118+
function Install-PythonRequirements {
119+
param([string]$SourcePath,
120+
[switch]$BuildWithoutBinaries
121+
)
122+
123+
Write-Host "Installing Python requirements from ${SourcePath}"
124+
125+
$extraPipArgs = ""
126+
if ($BuildWithoutBinaries) {
127+
$extraPipArgs = $PIP_BUILD_NO_BINARIES_ARGS
128+
}
129+
130+
Run-CmdWithRetry {
131+
try {
132+
Push-Location (Join-Path $BuildDir $SourcePath)
133+
Run-Command -Cmd "python" -Arguments @("-m", "pip", "install", $extraPipArgs, "-r", ".\requirements.txt")
134+
} finally {
135+
Pop-Location
136+
}
137+
}
138+
}
139+
140+
function Install-PythonPackage {
141+
param([string]$SourcePath,
142+
[switch]$BuildWithoutBinaries
143+
)
144+
145+
Write-Host "Installing Python package from ${SourcePath}"
146+
147+
$extraPipArgs = ""
148+
if ($BuildWithoutBinaries) {
149+
$extraPipArgs = $PIP_BUILD_NO_BINARIES_ARGS
150+
}
151+
152+
Run-CmdWithRetry {
153+
try {
154+
Push-Location (Join-Path $BuildDir $SourcePath)
155+
Run-Command -Cmd "python" -Arguments @("-m", "pip", "install", $extraPipArgs, ".")
156+
} finally {
157+
Pop-Location
158+
}
159+
}
160+
}
161+
162+
function Prepare-BuildDir {
163+
Write-Host "Creating / Cleaning up build directory ${BuildDir}"
164+
165+
if ($BuildDir -and (Test-Path $BuildDir)) {
166+
Remove-Item -Recurse -Force $BuildDir
167+
}
168+
New-Item -Type Directory -Path $BuildDir -Force | Out-Null
169+
}
170+
171+
function Setup-PythonPip {
172+
$env:PIP_CONSTRAINT = ""
173+
$env:PIP_NO_BINARY = ""
174+
175+
# Update pip. Not needed for latest version of Python 3.7.
176+
# Download-File "https://bootstrap.pypa.io/get-pip.py" "${BuildDir}/get-pip.py"
177+
# Run-CmdWithRetry {
178+
# python "${BuildDir}/get-pip.py"
179+
# if ($LastExitCode) {
180+
# throw "Failed to run 'python get-pip.py'"
181+
# }
182+
#}
183+
184+
# Cloudbase-Init Python requirements should respect the OpenStack upper constraints
185+
Clone-Repo "https://github.com/openstack/requirements" "requirements"
186+
$constraintsFilePath = Join-Path $BuildDir "requirements/upper-constraints.txt"
187+
188+
$env:PIP_CONSTRAINT = $constraintsFilePath
189+
}
190+
191+
function Install-PyWin32FromSource {
192+
param($Url)
193+
194+
$sourcePath = "pywin32"
195+
196+
Clone-Repo $Url $sourceFolder
197+
Install-PythonPackage -SourcePath $sourcePath -BuildWithoutBinaries
198+
}
199+
200+
function Install-PyMI {
201+
param($Url)
202+
203+
$sourcePath = "PyMI"
204+
205+
Clone-Repo $Url $sourcePath
206+
Install-PythonRequirements -SourcePath $sourcePath -BuildWithoutBinaries
207+
Install-PythonPackage -SourcePath $sourcePath -BuildWithoutBinaries
208+
}
209+
210+
function Install-CloudbaseInit {
211+
param($Url)
212+
213+
$sourcePath = "cloudbase-init"
214+
215+
Clone-Repo $Url $sourcePath
216+
Install-PythonRequirements -SourcePath $sourcePath -BuildWithoutBinaries
217+
Install-PythonPackage -SourcePath $sourcePath
218+
}
219+
220+
### Main ###
221+
222+
try {
223+
$startDate = Get-Date
224+
Write-Host "Cloudbase-Init build started."
225+
226+
# Make sure that BuildDir is created and cleaned up properly
227+
if (!$BuildDir) {
228+
$BuildDir = "build"
229+
}
230+
if (![System.IO.Path]::IsPathRooted($BuildDir)) {
231+
$BuildDir = Join-Path $scriptPath $BuildDir
232+
}
233+
Prepare-BuildDir
234+
235+
# Make sure VS 2015 is used
236+
Set-VCVars -Version "14.0"
237+
238+
# Setup pip upper requirements
239+
Setup-PythonPip
240+
241+
# Install PyWin32 from source
242+
Install-PyWin32FromSource $PyWin32RepoUrl
243+
244+
# PyMI setup can be skipped once the upstream version is published on pypi
245+
Install-PyMI $PyMiRepoUrl
246+
247+
Install-CloudbaseInit $CloudbaseInitRepoUrl
248+
} finally {
249+
$endDate = Get-Date
250+
Write-Host "Cloudbase-Init build finished after $(($endDate - $StartDate).Minutes + 1) minutes."
251+
}
252+

0 commit comments

Comments
 (0)