Commit 8c16466a authored by Lu Xu's avatar Lu Xu 👀

software/hugo: Add Hugo software in slapos

See merge request nexedi/slapos!994
parents cb5c5b83 73c03caf
[buildout]
extends =
../golang/buildout.cfg
../../stack/slapos.cfg
parts =
slapos-cookbook
gowork
[hugo-get]
<= go-git-package
go.importpath = github.com/gohugoio/hugo
repository = https://github.com/gohugoio/hugo.git
revision = f6821b88abbc1237af0e28cefbc624e6cda3305a
[gowork]
install =
${hugo-get:location}:./...
environment =
CGO_ENABLED = 1
buildflags = --tags extended
[gowork.goinstall]
depends_gitfetch =
${hugo-get:recipe}
command = set -e
. ${gowork:env.sh}
cd ${hugo-get:location}
go build ${gowork:buildflags} -o ${gowork:bin}/hugo
[hugo]
<= gowork.goinstall
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[template-cfg]
filename = instance.cfg.in
md5sum = 9653104b2217dc26b23f9c1b997124ca
[template_nginx_conf]
_update_hash_filename_ = templates/nginx_conf.in
md5sum = 7ea6d7cc3e05edafe7fcf707f547cb04
[template_mime_types]
_update_hash_filename_ = templates/mime_types.in
md5sum = 4ef94a7b458d885cd79ba0b930a5727e
[template_index_html]
_update_hash_filename_ = templates/index.html.in
md5sum = d588af7ad4d5adefa2e245d78c401ce1
[buildout]
parts =
default-index-html
default-config-toml
hugo-server
hugo-server-service
hugo-frontend
hugo-frontend-port
hugo-frontend-promise
hugo-port-listening-promise
logrotate-entry-nginx
mime-types
nginx-conf
nginx-launcher
nginx-graceful
nginx-certificate
nginx-frontend
nginx-frontend-port
nginx-frontend-promise
nginx-port-listening-promise
publish-connection-information
eggs-directory = {{ buildout['eggs-directory'] }}
develop-eggs-directory = {{ buildout['develop-eggs-directory'] }}
offline = true
extends = {{ parameter_list['template_monitor'] }}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration
computer = ${slap-connection:computer-id}
partition = ${slap-connection:partition-id}
url = ${slap-connection:server-url}
key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file}
configuration.hugo-monitor-httpd-port = 8196
configuration.nginx-monitor-httpd-port = 8197
configuration.site = default
# Create all needed directories, depending on your needs
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
srv = ${:home}/srv
bin = ${:home}/bin
[basedirectory]
recipe = slapos.cookbook:mkdirectory
script = ${directory:etc}/run
service = ${directory:etc}/service
log = ${directory:var}/log
run = ${directory:var}/run
backup = ${directory:srv}/backup
data = ${directory:srv}/hugo
ssl = ${directory:etc}/ssl
default-site = ${:data}/default
default-public = ${:default-site}/public
[tempdirectory]
recipe = slapos.cookbook:mkdirectory
tmp = ${directory:home}/tmp
client-body-temp-path = ${:tmp}/client_body_temp_path
proxy-temp-path = ${:tmp}/proxy_temp_path
fastcgi-temp-path = ${:tmp}/fastcgi_temp_path
uwsgi-temp-path = ${:tmp}/uwsgi_temp_path
scgi-temp-path = ${:tmp}/scgi_temp_path
[hugo-frontend-port]
recipe = slapos.cookbook:free_port
minimum = 1313
maximum = 1323
ip = ${slap-configuration:ipv6-random}
[nginx-frontend-port]
recipe = slapos.cookbook:free_port
minimum = 1324
maximum = 1334
ip = ${slap-configuration:ipv6-random}
[hugo]
nb-workers = 2
go-environment = {{ parameter_list['go_environment'] }}
ip = ${slap-configuration:ipv6-random}
hugo-port = ${hugo-frontend-port:port}
nginx-port = ${nginx-frontend-port:port}
hugo-access-url = http://[${:ip}]:${:hugo-port}
nginx-access-url = https://[${:ip}]:${:nginx-port}
path-pid = ${basedirectory:run}/nginx.pid
path-log = ${basedirectory:log}/nginx.log
path-access-log = ${basedirectory:log}/nginx.access.log
path-error-log = ${basedirectory:log}/nginx.error.log
path-tmp = ${tempdirectory:tmp}
path-nginx-conf = ${directory:etc}/nginx.conf
path-mime-types = ${directory:etc}/mime_types
path-nginx = {{ parameter_list['nginx_location'] }}/sbin/nginx
# Docroot
docroot = ${basedirectory:data}/${slap-configuration:configuration.site}/public
[hugo-server]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:bin}/hugo-server
mode = 0700
template =
inline:#!/bin/sh
. ${hugo:go-environment}
cd ${basedirectory:data}/${slap-configuration:configuration.site}
if [ -d "public" ]; then rm -Rf public; fi
hugo && hugo server --bind=${hugo:ip} --port=${hugo:hugo-port} --baseURL=${hugo-frontend:connection-secure_access} --appendPort=false
[hugo-server-service]
recipe = slapos.cookbook:wrapper
wrapper-path = ${basedirectory:service}/hugo-server
command-line = ${hugo-server:rendered}
hash-files =
${hugo-server:rendered}
[hugo-port-listening-promise]
<= monitor-promise-base
module = check_socket_listening
name = hugo-port-listening.py
config-host = ${hugo:ip}
config-port = ${hugo:hugo-port}
[monitor-instance-parameter]
monitor-httpd-port = ${slap-configuration:configuration.hugo-monitor-httpd-port}
[hugo-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Hugo frontend
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config-url = ${hugo:hugo-access-url}
config-https-only = true
return = domain secure_access
[hugo-frontend-promise]
<= monitor-promise-base
module = check_url_available
name = hugo-http-frontend.py
url = ${hugo-frontend:connection-secure_access}
config-url = ${:url}
[nginx-conf]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_list['template_nginx_conf'] }}
rendered = ${hugo:path-nginx-conf}
context =
section param_hugo hugo
section param_tempdir tempdirectory
section param_nginxcert nginx-certificate
[mime-types]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_list['template_mime_types'] }}
rendered = ${hugo:path-mime-types}
[nginx-launcher]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_list['nginx_location'] }}/sbin/nginx -c ${hugo:path-nginx-conf}
wrapper-path = ${basedirectory:service}/nginx
# Generate a self-signed TLS certificate.
[nginx-certificate]
recipe = plone.recipe.command
command =
if [ ! -e ${:key-file} ]
then
{{ parameter_list['openssl_location'] }}/bin/openssl req -x509 -nodes -days 3650 \
-subj "/C=AA/ST=X/L=X/O=Dis/CN=${hugo:ip}" \
-newkey rsa:1024 -keyout ${:key-file} \
-out ${:cert-file}
fi
update-command = ${:command}
key-file = ${basedirectory:ssl}/nginx-certificate.key
cert-file = ${basedirectory:ssl}/nginx-certificate.cert
common-name = ${hugo:ip}
stop-on-error = true
[default-index-html]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_list['template_index_html'] }}
rendered = ${basedirectory:default-public}/index.html
context =
key go_environment hugo:go-environment
key data basedirectory:data
[default-config-toml]
recipe = slapos.recipe.template:jinja2
rendered = ${basedirectory:default-site}/config.toml
template =
inline:
baseURL = "${hugo-frontend:connection-secure_access}"
languageCode = "en-us"
title = "My New Hugo Site"
[nginx-graceful]
recipe = slapos.recipe.template:jinja2
rendered = ${basedirectory:script}/nginx-graceful
mode = 0700
template =
inline:#!/bin/sh
exec kill -s SIGHUP $(cat ${hugo:path-pid})
[nginx-port-listening-promise]
<= monitor-promise-base
module = check_socket_listening
name = nginx-port-listening.py
config-host = ${hugo:ip}
config-port = ${hugo:nginx-port}
[monitor-instance-parameter]
monitor-httpd-port = ${slap-configuration:configuration.nginx-monitor-httpd-port}
[logrotate-entry-nginx]
<= logrotate-entry-base
name = nginx
log = ${hugo:path-access-log} ${hugo:path-error-log}
post = kill -USR1 $(cat ${hugo:path-pid})
[nginx-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Hugo Nginx frontend
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config-url = ${hugo:nginx-access-url}
config-https-only = true
return = domain secure_access
[nginx-frontend-promise]
<= monitor-promise-base
module = check_url_available
name = nginx-http-frontend.py
url = ${nginx-frontend:connection-secure_access}
config-url = ${:url}
[publish-connection-information]
recipe = slapos.cookbook:publish
<= monitor-publish
go-environment = ${hugo:go-environment}
data = ${basedirectory:data}
hugo-server-url = ${hugo:hugo-access-url}
nginx-server-url = ${hugo:nginx-access-url}
hugo-server-cdn-url = ${hugo-frontend-promise:url}
nginx-server-cdn-url = ${nginx-frontend-promise:url}
[buildout]
extends =
buildout.hash.cfg
../../stack/slapos.cfg
../../stack/monitor/buildout.cfg
../../component/hugo/buildout.cfg
../../component/nginx/buildout.cfg
../../component/openssl/buildout.cfg
parts =
slapos-cookbook
hugo
template-cfg
[python]
part = python3
[profile-common]
nginx_location = ${nginx:location}
dash_location = ${dash:location}
go_environment = ${gowork:env.sh}
openssl_location = ${openssl:location}
template_nginx_conf = ${template_nginx_conf:target}
template_mime_types = ${template_mime_types:target}
template_index_html = ${template_index_html:target}
template_monitor = ${monitor-template:rendered}
[template-cfg]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/template.cfg
template = ${:_profile_base_location_}/${:filename}
mode = 0644
context =
section buildout buildout
section parameter_list profile-common
[download-base]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
mode = 0644
[template_nginx_conf]
<= download-base
[template_mime_types]
<= download-base
[template_index_html]
<= download-base
<h1 style="text-align: center;" dir="ltr"><span style="font-family: 'comic sans ms', sans-serif;">Welcome to <a href="https://gohugo.io/">Hugo</a>'s workplace</span></h1>
<table border="1" style="border-collapse: collapse; width: 66%; border-color: #ffffff; margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td style="width: 99.934%;">
<p><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">Here are some instructions you might need:</span></p>
<ol>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">To get started, please change the directory to a Hugo workplace by</span><br />
<pre><code>$ cd {{ data }}</code></pre>
<span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">It's suggested that you store your splendid Hugo site in this directory that you can also find from the published information of the request script (<code>data</code>). There is always a Hugo server running for you so that the website can dynamically update according to your changes.<br /><br /></span></li>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">Then let's <code>source</code> the <code>go.work</code>'s environment path by typing the following command in your terminal:</span><br />
<pre><code>$ source {{ go_environment }}</code></pre>
<span style="font-family: 'comic sans ms', sans-serif; font-size: 14pt;">&nbsp;You can also find the path (<code>go_environment</code>) from the published information of the request script.<br /><br /></span></li>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">Once you see <code>(go.work) bash-4.3$</code> displayed on your terminal, you can follow Hugo's official documentation to have a <a href="https://gohugo.io/getting-started/quick-start/">quick start</a><br /><br /></span></li>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">Pass the <code>site</code> by <code>--parameter site='your_site'</code> with slapos request command (you can do it in the request script) to make your website online, eg.</span><br />
<pre><code>$ slapos request $software_name'_1' $software_release_uri --parameters site='quickstart'</code></pre>
</li>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;"><a href="https://handbook.rapid.space/user/rapidspace-HowTo.Supply.A.Software.And.Request.An.Instance.On.Theia.Runner">re-instanciate</a>(<code>slapos node instance</code>)<br /><br /></span></li>
<li><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;">Retrieve the CDN URLs by re-launching the slapos request command. </span><br /><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;"><code>hugo-server-cdn-url</code> is the website hosted by the Hugo server while <code>nginx-server-cdn-url</code> is the website hosted by the Ngnix server.</span></li>
</ol>
</td>
</tr>
</tbody>
</table>
<p style="text-align: center;"><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;"><strong></strong></span></p>
<p style="text-align: center;"><span style="font-size: 14pt; font-family: 'comic sans ms', sans-serif;"><strong>Now you can access your published website powered by Hugo</strong></span></p>
types {
text/html html htm shtml;
text/css css;
text/xml xml rss;
image/gif gif;
image/jpeg jpeg jpg;
application/x-javascript js;
application/atom+xml atom;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
application/java-archive jar war ear;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.ms-excel xls;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream eot;
application/octet-stream iso img;
application/octet-stream msi msp msm;
application/ogg ogx;
audio/midi mid midi kar;
audio/mpeg mpga mpega mp2 mp3 m4a;
audio/ogg oga ogg spx;
audio/x-realaudio ra;
audio/webm weba;
video/3gpp 3gpp 3gp;
video/mp4 mp4;
video/mpeg mpeg mpg mpe;
video/ogg ogv;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
worker_processes {{ param_hugo['nb-workers'] }};
pid {{ param_hugo['path-pid'] }};
error_log {{ param_hugo['path-error-log'] }};
daemon off;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include {{ param_hugo['path-mime-types'] }};
default_type application/octet-stream;
types_hash_bucket_size 64;
access_log {{ param_hugo['path-access-log'] }} combined;
index index.html;
server {
listen [{{ param_hugo['ip'] }}]:{{ param_hugo['nginx-port'] }} ssl http2;
server_name _;
ssl_certificate {{ param_nginxcert['cert-file'] }};
ssl_certificate_key {{ param_nginxcert['key-file'] }};
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
keepalive_timeout 5;
client_body_temp_path {{ param_tempdir['client-body-temp-path'] }};
proxy_temp_path {{ param_tempdir['proxy-temp-path'] }};
fastcgi_temp_path {{ param_tempdir['fastcgi-temp-path'] }};
uwsgi_temp_path {{ param_tempdir['uwsgi-temp-path'] }};
scgi_temp_path {{ param_tempdir['scgi-temp-path'] }};
# path for static files
root {{ param_hugo['docroot'] }};
}
}
Tests for hugo software release
##############################################################################
#
# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.hugo'
with open("README.md") as f:
long_description = f.read()
setup(
name=name,
version=version,
description="Test for SlapOS' HUGO",
long_description=long_description,
long_description_content_type='text/markdown',
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'slapos.libnetworkcache',
'erp5.util',
'requests',
],
zip_safe=True,
test_suite='test',
)
##############################################################################
#
# Copyright (c) 2021 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import requests
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg')))
class HugoTestCase(SlapOSInstanceTestCase):
def setUp(self):
self.connection_parameters = self.computer_partition.getConnectionParameterDict()
# Test Pulished Parameters
def test_nginx_url_get(self):
resp = requests.get(self.connection_parameters['nginx-server-cdn-url'], verify=False)
self.assertEqual(requests.codes.ok, resp.status_code)
def test_hugo_url_get(self):
resp = requests.get(self.connection_parameters['hugo-server-cdn-url'], verify=False)
self.assertEqual(requests.codes.ok, resp.status_code)
def test_dir_data(self):
data_path = self.connection_parameters['data']
self.assertTrue(os.path.exists(data_path))
def test_dir_go_env(self):
go_env = self.connection_parameters['go-environment']
self.assertTrue(os.path.exists(go_env))
\ No newline at end of file
...@@ -23,3 +23,4 @@ extra = ...@@ -23,3 +23,4 @@ extra =
repman ${slapos.test.repman-setup:setup} repman ${slapos.test.repman-setup:setup}
restic-rest-server ${slapos.test.restic_rest_server-setup:setup} restic-rest-server ${slapos.test.restic_rest_server-setup:setup}
headless-chromium ${slapos.test.headless-chromium-setup:setup} headless-chromium ${slapos.test.headless-chromium-setup:setup}
hugo ${slapos.test.hugo-setup:setup}
...@@ -139,6 +139,11 @@ setup = ${slapos-repository:location}/software/html5as/test/ ...@@ -139,6 +139,11 @@ setup = ${slapos-repository:location}/software/html5as/test/
egg = slapos.test.html5asbase egg = slapos.test.html5asbase
setup = ${slapos-repository:location}/software/html5as-base/test/ setup = ${slapos-repository:location}/software/html5as-base/test/
[slapos.test.hugo-setup]
<= setup-develop-egg
egg = slapos.test.hugo
setup = ${slapos-repository:location}/software/hugo/test/
[slapos.test.jupyter-setup] [slapos.test.jupyter-setup]
<= setup-develop-egg <= setup-develop-egg
egg = slapos.test.jupyter egg = slapos.test.jupyter
...@@ -272,6 +277,7 @@ extra-eggs = ...@@ -272,6 +277,7 @@ extra-eggs =
${slapos.test.fluentd-setup:egg} ${slapos.test.fluentd-setup:egg}
${slapos.test.headless-chromium-setup:egg} ${slapos.test.headless-chromium-setup:egg}
${slapos.test.erp5testnode-setup:egg} ${slapos.test.erp5testnode-setup:egg}
${slapos.test.hugo-setup:egg}
# We don't name this interpreter `python`, so that when we run slapos node # We don't name this interpreter `python`, so that when we run slapos node
# software, installation scripts running `python` use a python without any # software, installation scripts running `python` use a python without any
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment