Skip to content

Instantly share code, notes, and snippets.

@me-kell
Created January 5, 2023 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save me-kell/9fb4a8c97e875c8f529a0bbce0699ee9 to your computer and use it in GitHub Desktop.
Save me-kell/9fb4a8c97e875c8f529a0bbce0699ee9 to your computer and use it in GitHub Desktop.
# Instructions
# In a PowerShell terminal run the following:
# . install_plone_6.0.0.2.ps1

$TIMESTAMP_START = Get-Date

# store current path

# clear path and use only actually needed paths
$env:Path = ''
$env:Path += ';C:\Windows'
$env:Path += ';C:\Windows\system32'
$env:Path += ';C:\Program Files\Git\cmd'
$env:Path += ';C:\Program Files\nodejs'
#$env:Path += ';C:\Windows\System32\WindowsPowerShell\v1.0\'
Write-Output $env:Path

# set variables
$PLONE_VERSION = '6.0.0.2'
$PLONE_NAME = "Plone-${PLONE_VERSION}"
$PLONE_HOME = "s:\${PLONE_NAME}"
$PLONE_CONSTRAINTS_URL = "https://dist.plone.org/release/${PLONE_VERSION}/constraints.txt"
$PLONE_CONSTRAINTS="${PLONE_HOME}\constraints.txt"

$PLONE_SITE_NAME="Plone"
$ZEO_HOST="127.0.0.1"
$ZEO_PORT="8100"
$ZEO_NAME="zeoserver"
$ZOPE_INSTANCE_NAME="client1"
# set localhost instead of 127.0.0.1
# see https://community.plone.org/t/http-127-0-0-1-8080-plone-and-http-localhost-8080-plone-render-differently/15257
# see https://pypi.org/project/plone.app.theming/#advanced-settings
$ZOPE_INSTANCE_HOST="localhost"
$ZOPE_INSTANCE_PORT="8081"
$ADMIN_USERNAME="admin"
$ADMIN_PASSWORD="admin"


Set-Location -Path ${env:HOMEDRIVE}${env:HOMEPATH}
if (Test-Path -LiteralPath ${PLONE_HOME}) { Set-Location -Path ${PLONE_HOME} }

$PLONE_REQUIREMENTS = "https://dist.plone.org/release/${PLONE_VERSION}/requirements.txt"

Write-Output "Set vars ok"

# function venv
function venv {
    Write-Output "Running venv"
    
    # delete PLONE_HOME directory if it exists
    Set-Location -Path "${env:HOMEDRIVE}${env:HOMEPATH}"
    if (Test-Path -LiteralPath ${PLONE_HOME}) { Remove-Item -LiteralPath ${PLONE_HOME} -Recurse -Force }

    New-Item -ItemType 'Directory' -Path ${PLONE_HOME} -Force
    Set-Location -Path ${PLONE_HOME}

    # create venv in PLONE_HOME
    $PYTHON_TARGET_DIR="c:\Python39"
    & "${PYTHON_TARGET_DIR}\python.exe" -m venv "${PLONE_HOME}"

    # get installed versions
    & ${PLONE_HOME}\Scripts\python --version
    & ${PLONE_HOME}\Scripts\pip --version

    Set-Location -Path ${PLONE_HOME}
}

# function plone
function plone {
    Write-Output "Running plone"

    # we don't need plone.volto for Classic UI Site
    $(Invoke-WebRequest -Uri "$PLONE_CONSTRAINTS_URL").Content -split '\n' | Select-String -Pattern 'plone.volto' -NotMatch  | Set-Content -Path "${PLONE_CONSTRAINTS}"

    # installing via "requirements.txt" will mess up pip
    # we manually modify pip version
    & ${PLONE_HOME}\Scripts\python.exe -m pip install -U pip==22.3.1 -c ${PLONE_CONSTRAINTS}
    # install setuptools and wheel for PLONE_VERSION
    & "${PLONE_HOME}\Scripts\pip.exe" install setuptools==65.5.1 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install wheel==0.38.4 -c ${PLONE_CONSTRAINTS}

    # we don't need zc.buildout for a pip installation
    # if yes, uncomment the following line
    # & ${PLONE_HOME}\Scripts\pip install zc.buildout==3.0.1 -c ${PLONE_CONSTRAINTS}

    # install Plone
    # we don't need plone.volto for a Clasic UI installation
    # if yes, uncomment the following line
    # & "${PLONE_HOME}\Scripts\pip.exe" install Plone -r ${PLONE_REQUIREMENTS} -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install Products.CMFPlone==6.0.0 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install Products.CMFPlacefulWorkflow==3.0.0 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install plone.app.caching==3.0.1 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install plone.app.iterate==4.0.3 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install plone.app.upgrade==3.0.0 -c ${PLONE_CONSTRAINTS}
    & "${PLONE_HOME}\Scripts\pip.exe" install plone.restapi==8.32.6 -c ${PLONE_CONSTRAINTS}
    # "%PLONE_HOME%\Scripts\pip.exe" install plone.volto==4.0.4 -c %PLONE_CONSTRAINTS%
}

# function conf
function conf {
    Write-Output "Running conf"

    # set constraints
    $PLONE_CONSTRAINTS="${PLONE_HOME}\constraints.txt"

    # install zope.mkzeoinstance and cookiecutter
    & ${PLONE_HOME}\Scripts\pip install zope.mkzeoinstance==4.1 -c ${PLONE_CONSTRAINTS}
    & ${PLONE_HOME}\Scripts\pip install cookiecutter==2.1.1 -c ${PLONE_CONSTRAINTS}

    # create parts directory for zeo and zope instances
    Set-Location -Path ${PLONE_HOME}
    if (Test-Path -LiteralPath ${PLONE_HOME}\parts) { Remove-Item -LiteralPath ${PLONE_HOME}\parts -Recurse  -Force}

    # mkzeoinstance
    & ${PLONE_HOME}\Scripts\mkzeoinstance.exe "${PLONE_HOME}\parts\${ZEO_NAME}" ${ZEO_HOST}:${ZEO_PORT}

    # patch zeo.conf
    $PATCHFILE="${PLONE_HOME}\patchfile.diff"
    @"
`@`@ -15,0 +16 `@`@
+  blob-dir ${PLONE_HOME}\parts\blobstorage
"@ | Out-File -Encoding ascii "${PATCHFILE}"
    Get-Content "${PATCHFILE}"
    & "C:\Program Files\Git\usr\bin\patch.exe" "${PLONE_HOME}\parts\${ZEO_NAME}\etc\zeo.conf" "${PATCHFILE}"
    
    # generate zope-instance
    Set-Location -Path ${PLONE_HOME}\parts

    @"
default_context:
    target: '${ZOPE_INSTANCE_NAME}'
    wsgi_listen: '${ZOPE_INSTANCE_HOST}:${ZOPE_INSTANCE_PORT}'
    initial_user_name: '${ADMIN_USERNAME}'
    initial_user_password: '${ADMIN_PASSWORD}'
    db_blobs_mode: 'shared'
    db_storage: 'zeo'
    db_zeo_server: '${ZEO_HOST}:${ZEO_PORT}'
    #db_filestorage_location: "filestorage/Data.fs"
    db_zeo_read_only: false
    db_zeo_read_only_fallback: false
    db_blobs_location: "blobstorage"
"@ | Out-File -Encoding ascii ${PLONE_HOME}\client1.yaml

    Get-Content ${PLONE_HOME}\client1.yaml
    # uncomment the following line when the pull request has been accepted. Replace the checkout version.
    # "%PLONE_HOME%\Scripts\cookiecutter" -f --no-input --config-file "%PLONE_HOME%\%ZOPE_INSTANCE_NAME%.yaml" --checkout 1.0.0b3  https://github.com/plone/cookiecutter-zope-instance
    # comment out the following line when the pull request has been accepted.
    & "${PLONE_HOME}\Scripts\cookiecutter.exe" -f --no-input --config-file ${PLONE_HOME}\client1.yaml https://github.com/me-kell/cookiecutter-zope-instance
    
    # set debug-mode on
    (Get-Content "${PLONE_HOME}\parts\client1\etc\zope.conf") -replace "^debug-mode .*", "debug-mode on" | Set-Content  "${PLONE_HOME}\parts\client1\etc\zope.conf"
    Get-Content  "${PLONE_HOME}\parts\client1\etc\zope.conf"
}

# function runzeo
function runzeo {
    Write-Output "Running runzeo"
    # runzeo in another window
    $RUNZEO_CMD = "${PLONE_HOME}\Scripts\runzeo.exe -C ${PLONE_HOME}\parts\${ZEO_NAME}\etc\zeo.conf"
    Write-Output "${RUNZEO_CMD} in new terminal"
    Start-Process "cmd" -ArgumentList "/c echo ${RUNZEO_CMD} & echo Press Ctrl-C to stop & ${RUNZEO_CMD}"
}

# function runwsgi
function runwsgi {
    Write-Output "Running runwsgi"
    # runwsgi in another window
    $RUNWSGI_CMD = "${PLONE_HOME}\Scripts\runwsgi.exe -dv ${PLONE_HOME}\parts\client1\etc\zope.ini"
    Write-Output "${RUNWSGI_CMD} in new terminal"
    Start-Process "cmd" -ArgumentList "/c echo ${RUNWSGI_CMD} & echo Press Ctrl-C to stop & ${RUNWSGI_CMD}"
}

# function runwsgidebug
function runwsgidebug {
    Write-Output "Running runwsgi in debug mode"
    # runwsgi in debug mode
    & "${PLONE_HOME}\Scripts\runwsgi.exe" -dv "${PLONE_HOME}\parts\client1\etc\zope.ini"
}
# function run
function run {
    Write-Output "Running run"
    runzeo
    runwsgi
}
# function create
function create {
    Write-Output "Running create"

    # create a Python script to add a PloneSite
    $SCRIPTNAME = "${PLONE_HOME}\create_plone_site.py"
    @"
app._p_jar.sync()
from Testing.makerequest import makerequest
app = makerequest(app)
from AccessControl.SecurityManagement import newSecurityManager, noSecurityManager
admin_username='${ADMIN_USERNAME}'
acl_users = app.acl_users
user = acl_users.getUser(admin_username)
user = user.__of__(acl_users)
newSecurityManager(None,user)
from Products.CMFPlone.factory import addPloneSite
plone_site_name = 'Plone'
plone_site_title = plone_site_name

if app.hasObject(plone_site_name):
    app.manage_delObjects(plone_site_name);
    print(f"Deleted existing '{plone_site_name}'")

plone_site = addPloneSite(
    app, 
    plone_site_name, 
    title=plone_site_title, 
    description='', 
    extension_ids=(
        'plonetheme.barceloneta:default', 
        'plone.app.caching:default',
        ), 
    setup_content=True, 
    default_language='de', 
    portal_timezone='Europe/Berlin'
)

import transaction
transaction.commit()
print(f"Created '{plone_site}'")
"@ | Out-File -Encoding ascii ${SCRIPTNAME}
    Get-Content ${SCRIPTNAME}

    # set a variable for the file zope.conf
    $ZOPECONF_FILENAME = "${PLONE_HOME}\parts\client1\etc\zope.conf"
    $ZOPECONF_FILENAME_WITH_FORWARD_SLASHES = ${ZOPECONF_FILENAME} -replace "\\", "/"
    Write-Output $ZOPECONF_FILENAME_WITH_FORWARD_SLASHES

    # wait for runwsgi to start and run the script in zconsole
    Write-Output "Waiting 20 sec. ..."
    Start-Sleep 20
    Write-Output "running ${SCRIPTNAME}"
    & "${PLONE_HOME}\Scripts\zconsole.exe" run ${ZOPECONF_FILENAME_WITH_FORWARD_SLASHES} ${SCRIPTNAME}

    # wait and check if the PloneSite is available
    Write-Output "Waiting 5 sec. ..."
    Start-Sleep 5
    $(Invoke-WebRequest "http://${ZOPE_INSTANCE_HOST}:${ZOPE_INSTANCE_PORT}/Plone").Content.Split([Environment]::NewLine) | Select-String -Pattern "<title>${PLONE_SITE_NAME}</title>"

    $TIMESTAMP_END = Get-Date
    Write-Output TIMESTAMP_START = ${TIMESTAMP_START}
    Write-Output TIMESTAMP_END   = ${TIMESTAMP_END}
}

# function all
function all {
    Write-Output "Running all"

    venv
    plone
    conf
    run
    create
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment