Finish draft articles #10
8 changed files with 399 additions and 3 deletions
48
articles/2019-06-12-opengl-kvm-mesa3d.md
Normal file
48
articles/2019-06-12-opengl-kvm-mesa3d.md
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
---
|
||||||
|
title: OpenGL in a virtual machine
|
||||||
|
date: 2019-06-12 18:30:00
|
||||||
|
---
|
||||||
|
|
||||||
|
As I prefer to work on a Linux computer for programming, at work I have to
|
||||||
|
use a virtual machine to execute the product and test in a real environment
|
||||||
|
using different Windows versions.
|
||||||
|
|
||||||
|
The problem encountered is that the emulated graphics card, even with full
|
||||||
|
drivers in my KVM setup is only providing an OpenGL 1.1 version, something
|
||||||
|
so old that some of the functionalities of our application are not working
|
||||||
|
and display black boxes instead.
|
||||||
|
|
||||||
|
After trying to install additional drivers or setup a more complete emulation,
|
||||||
|
a newer emulated card or other complex steps, I found a simpler way : Using
|
||||||
|
a Mesa3D driver with the llvmpipe that will emulate the lastest OpenGL features
|
||||||
|
using what is available on the emulated machine. The result will not be fast
|
||||||
|
enough for a 3D game for example, but every feature will become available.
|
||||||
|
|
||||||
|
You can download an already compiled distribution of the Mesa3D sources at
|
||||||
|
https://github.com/pal1000/mesa-dist-win/releases. By default, I download
|
||||||
|
the msvc version as I usually have everything needed. Once downloaded, simply
|
||||||
|
extract the archive in your download or Desktop folder.
|
||||||
|
|
||||||
|
I usually install the library System-Wide, as a replacement to the Microsoft
|
||||||
|
OpenGL software renderer that only support the very old OpenGL 1.1 version.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Select the first option to install the LLVM pipe System-Wide so that any
|
||||||
|
application needing OpenGL will use the Mesa3D implementation instead of the
|
||||||
|
Microsoft renderer without any further configuration needed.
|
||||||
|
|
||||||
|
Once installed System-Wide, you can simply restart your application and
|
||||||
|
check that the available OpenGL version has been bumped to a default 3.1
|
||||||
|
version. This default version can be overridden by setting the `MESA_GL_VERSION_OVERRIDE`
|
||||||
|
environment variable. For example, if you want to get OpenGL 4.6, you can
|
||||||
|
create a `MyApplication.cmd` that will launch the executable :
|
||||||
|
|
||||||
|
```
|
||||||
|
@set MESA_GL_VERSION_OVERRIDE=4.6COMPAT
|
||||||
|
@MyApplication.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
It is important to note that profiles higher than the default can be incomplete and
|
||||||
|
are not certified as a full implementation. If your application only uses
|
||||||
|
extensions that are implemented, this will work but YMMV.
|
BIN
articles/2019-06-12-opengl-kvm-mesa3d/install.png
Executable file
BIN
articles/2019-06-12-opengl-kvm-mesa3d/install.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
187
articles/2019-09-24-automatic-deploy-on-aws.md
Normal file
187
articles/2019-09-24-automatic-deploy-on-aws.md
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
---
|
||||||
|
title: Automatic deployment on AWS S3 and/or FTP
|
||||||
|
date: 2019-09-24 18:30:00
|
||||||
|
---
|
||||||
|
|
||||||
|
A number of websites I maintain are built and deployed automatically through
|
||||||
|
GitLab pipelines, either on an AWS S3 bucket that is then used by AWS CloudFlare,
|
||||||
|
or to an SFTP server of an hosting provider.
|
||||||
|
|
||||||
|
In this article I will summarize the necessary configuration to GitLab-CI
|
||||||
|
and the necessary variables in the CI/CD settings.
|
||||||
|
|
||||||
|
## Deploy to AWS S3
|
||||||
|
|
||||||
|
We first need to inject the credentials necessary for the GitLab runner to GitLab.
|
||||||
|
Go to your project, `Settings` -> `CI / CD` -> `Secret variables` and set two variables:
|
||||||
|
|
||||||
|
- `AWS_ACCESS_KEY_ID` with the AWS user's access key
|
||||||
|
- `AWS_SECRET_ACCESS_KEY` with the AWS user's access secret key
|
||||||
|
|
||||||
|
These variables must not be protected as we want to publish every branch
|
||||||
|
to a subfolder to be able to preview our branches before merging them.
|
||||||
|
|
||||||
|
The `.gitlab-ci.yml` file will need to contain 3 jobs : Two deployment jobs,
|
||||||
|
one for branches and one for the master, a third one to cleanup the branch
|
||||||
|
deployment once the branch is merged or deleted.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image: "python:latest"
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
S3_BUCKET_NAME: your-bucket-identifier
|
||||||
|
AWS_BUCKET_REGION: us-east-1
|
||||||
|
|
||||||
|
deploys3-branch:
|
||||||
|
stage: deploy
|
||||||
|
before_script:
|
||||||
|
- pip install awscli
|
||||||
|
script:
|
||||||
|
- aws s3 cp . s3://${S3_BUCKET_NAME}/${CI_COMMIT_REF_SLUG} --recursive --exclude ".gitlab-ci.yml" --exclude ".git/*"
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
url: http://${S3_BUCKET_NAME}.s3-website-${AWS_BUCKET_REGION}.amazonaws.com/${CI_COMMIT_REF_SLUG}
|
||||||
|
on_stop: deploys3-branch-cleanup
|
||||||
|
except:
|
||||||
|
- /^master$/
|
||||||
|
|
||||||
|
deploys3-branch-cleanup:
|
||||||
|
stage: deploy
|
||||||
|
before_script:
|
||||||
|
- pip install awscli
|
||||||
|
script:
|
||||||
|
- aws s3 rm s3://${S3_BUCKET_NAME}/${CI_COMMIT_REF_SLUG} --recursive
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
action: stop
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
deploys3:
|
||||||
|
stage: deploy
|
||||||
|
before_script:
|
||||||
|
- pip install awscli
|
||||||
|
script:
|
||||||
|
- aws s3 cp . s3://${S3_BUCKET_NAME}/ --recursive --exclude ".gitlab-ci.yml" --exclude ".git/*"
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
url: http://${S3_BUCKET_NAME}.s3-website-${AWS_BUCKET_REGION}.amazonaws.com/
|
||||||
|
only:
|
||||||
|
- /^master$/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploy to an SFTP server
|
||||||
|
|
||||||
|
This case is somewhat more difficult because of the fact that runner will
|
||||||
|
need to receive the private key, a multiline string.
|
||||||
|
|
||||||
|
We also need to inject the credentials necessary for the GitLab runner to GitLab.
|
||||||
|
Go to your project, `Settings` -> `CI / CD` -> `Secret variables` and set two variables:
|
||||||
|
|
||||||
|
- `SFTP_PRIVATE_KEY` with a password-less private key, base64-encoded
|
||||||
|
|
||||||
|
To create the content of this variable, you can simply pipe the content
|
||||||
|
of your private key into base64 and copy the result into the variable :
|
||||||
|
`cat project/private-key-deploy_ed25519 | base64 -`. Don't use the same
|
||||||
|
key that you use for other servers here, always create a new SSH deployment
|
||||||
|
key!
|
||||||
|
|
||||||
|
These variables must also not be protected as we want to publish every branch
|
||||||
|
to a subfolder to be able to preview our branches before merging them.
|
||||||
|
|
||||||
|
The `.gitlab-ci.yml` file will also contain 3 jobs : Two deployment jobs,
|
||||||
|
one for branches and one for the master, a third one to cleanup the branch
|
||||||
|
deployment once the branch is merged or deleted.
|
||||||
|
|
||||||
|
```
|
||||||
|
variables:
|
||||||
|
SFTP_USER: sftp-user
|
||||||
|
SFTP_SERVER: sftp.server.domain
|
||||||
|
SFTP_TARGET: /sftp/server/folder/path
|
||||||
|
WEBSITE_URL: "https://public.server.domain"
|
||||||
|
RSYNC_CLI_OPTS: "-a -r"
|
||||||
|
RSYNC_RSH: 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -a -x'
|
||||||
|
|
||||||
|
## Task Templates
|
||||||
|
.lftp_template: &lftp_template
|
||||||
|
image: debian:testing-slim
|
||||||
|
stage: deploy
|
||||||
|
before_script:
|
||||||
|
- apt-get update && apt-get install -q -y rsync openssh-client
|
||||||
|
- eval $(ssh-agent -s)
|
||||||
|
- echo ${SFTP_PRIVATE_KEY} | base64 -d - | ssh-add -
|
||||||
|
|
||||||
|
deploysftp-deploy-branches:
|
||||||
|
<<: *lftp_template
|
||||||
|
stage: deploy
|
||||||
|
tags:
|
||||||
|
- documentation
|
||||||
|
except:
|
||||||
|
- master
|
||||||
|
- /^stable/
|
||||||
|
script:
|
||||||
|
- cd docs
|
||||||
|
- rsync ${RSYNC_CLI_OPTS} build/ ${SFTP_USER}@${SFTP_SERVER}:${SFTP_TARGET}/${CI_COMMIT_REF_SLUG}
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
url: ${WEBSITE_URL}/${CI_COMMIT_REF_SLUG}
|
||||||
|
on_stop: deploysftp-clean-doc-branches
|
||||||
|
when: manual
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- merge_requests
|
||||||
|
changes:
|
||||||
|
- docs/**/*
|
||||||
|
|
||||||
|
deploysftp-clean-doc-branches:
|
||||||
|
<<: *lftp_template
|
||||||
|
stage: deploy
|
||||||
|
tags:
|
||||||
|
- documentation
|
||||||
|
script:
|
||||||
|
- ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -a -x ${SFTP_USER}@${SFTP_SERVER} "rm -r ${SFTP_TARGET}/${CI_COMMIT_REF_SLUG}"
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
action: stop
|
||||||
|
when: manual
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- merge_requests
|
||||||
|
changes:
|
||||||
|
- docs/**/*
|
||||||
|
|
||||||
|
deploysftp-deploy-master:
|
||||||
|
<<: *lftp_template
|
||||||
|
stage: deploy
|
||||||
|
tags:
|
||||||
|
- documentation
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
script:
|
||||||
|
- cd docs
|
||||||
|
- rsync ${RSYNC_CLI_OPTS} build/ ${SFTP_USER}@${SFTP_SERVER}:${SFTP_TARGET}/
|
||||||
|
environment:
|
||||||
|
name: ${CI_COMMIT_REF_SLUG}
|
||||||
|
url: ${WEBSITE_URL}/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
With these configurations, you can commit your changes in a new branch,
|
||||||
|
open a merge request and preview your changes deployed as they will be when
|
||||||
|
the branch is merged.
|
||||||
|
|
||||||
|
The links configured in the two files allow GitLab to present the correct
|
||||||
|
links in the Merge Request deployment.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Once the branch is merged, the deployment is automatically stopped, which
|
||||||
|
launch the cleanup jobs.
|
||||||
|
|
||||||
|
Using these configuration, you don't have to worry about generating your
|
||||||
|
website with the latest changes and pushing these changes, the CI/CD process
|
||||||
|
will automatically do that for you, reducing the number of manual steps
|
||||||
|
and thus the number of possible errors.
|
BIN
articles/2019-09-24-automatic-deploy-on-aws/deployment.png
Normal file
BIN
articles/2019-09-24-automatic-deploy-on-aws/deployment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
25
articles/about.md
Normal file
25
articles/about.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
title: About me
|
||||||
|
hidefromhome: true
|
||||||
|
type: page
|
||||||
|
---
|
||||||
|
|
||||||
|
I am Thomas, a software engineer. I love new challenges and learning
|
||||||
|
new things. I earned a Master’s Degree in Computer Science graduating from
|
||||||
|
the EPFL (Swiss Federal Institute of Technology in Lausanne), with a
|
||||||
|
specialization in Software Systems.
|
||||||
|
|
||||||
|
When not programming for my job, I like to [design](https://git.inf3.xyz/tschwery/custom-keyboard) and build mechanical keyboards,
|
||||||
|
[shooting my bow](https://les-archers-du-bisse.ch/) and
|
||||||
|
[cooking](https://recettes.inf3.ch) with my family.
|
||||||
|
|
||||||
|
## My job
|
||||||
|
|
||||||
|
I have been working as a Software Developer at [SAI-ERP](https://sai-erp.net) since 2011.
|
||||||
|
|
||||||
|
I have previously worked as a student assistant at [EPFL](https://ic.epfl.ch).
|
||||||
|
|
||||||
|
## Contact me
|
||||||
|
|
||||||
|
Find me on [Github](https://github.com/tschwery/) / my private [GitLab instance](https://git.inf3.xyz/explore/projects) / [Linkedin](www.linkedin.com/in/thomas-schwery) or just say by email at [thomas@inf3.ch](mailto:thomas@inf3.ch).
|
||||||
|
|
15
layouts/_default/single.html
Normal file
15
layouts/_default/single.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{{ partial "header.html" . }}
|
||||||
|
|
||||||
|
<main role="main">
|
||||||
|
<article itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
<h1 class="entry-title" itemprop="headline">{{ .Title }}</h1>
|
||||||
|
{{ if ne .Type "page"}}
|
||||||
|
<span class="entry-meta"><time itemprop="datePublished" datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 02, 2006" }}</time></span>{{ .Date }}
|
||||||
|
{{ end }}
|
||||||
|
<section itemprop="entry-text">
|
||||||
|
{{ .Content }}
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{{ partial "footer.html" . }}
|
|
@ -15,10 +15,14 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<header role="side" class="sidebar">
|
||||||
<header role="banner">
|
|
||||||
<div class="header-logo">
|
<div class="header-logo">
|
||||||
<a href="/"><img src="{{ .Site.Params.logo }}" width="60" height="60" alt="{{ .Site.Title }}"></a>
|
<a href="/"><img src="{{ .Site.Params.logo }}" width="60" height="60" alt="{{ .Site.Title }}"></a>
|
||||||
</div>
|
</div>
|
||||||
{{ if eq $isHomePage true }}<h1 class="site-title">{{ .Site.Title }}</h1><h2>{{ .Site.Params.subtitle }}</h2>{{ end }}
|
<h1 class="site-title">{{ .Site.Title }}</h1>
|
||||||
|
<h2>{{ .Site.Params.subtitle }}</h2>
|
||||||
|
<div class="navigation">
|
||||||
|
<h2><a href="/index.html">Home</a></h2>
|
||||||
|
<h2><a href="/about/index.html">About me</a></h2>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
117
static/css/custom.css
Normal file
117
static/css/custom.css
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
body {
|
||||||
|
font-family: "Roboto", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
background-color: #FCFCFC;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font-size: 2.1rem; }
|
||||||
|
h2 { font-size: 1.9rem; }
|
||||||
|
h3 { font-size: 1.7rem; }
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 { font-size: 1.5rem; }
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
vertical-align: middle;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
margin: 4rem 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin: 4rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1150px) {
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: -40px;
|
||||||
|
left: 0;
|
||||||
|
width: 200px;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
padding: 30px;
|
||||||
|
background: #242930;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #afbac4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .navigation {
|
||||||
|
padding-top: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1150px) {
|
||||||
|
.sidebar {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .navigation h2 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar h2 a {
|
||||||
|
color: #1EAEDB;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a {
|
||||||
|
color: #afbac4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-logo img {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid #E1E1E1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-logo img:hover {
|
||||||
|
border-color: #F1F1F1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-title {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-title a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-meta {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-size: 1.7rem;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hr {
|
||||||
|
height: 1px;
|
||||||
|
margin: 2rem 0;
|
||||||
|
background: #E1E1E1;
|
||||||
|
background: -webkit-gradient(linear, left top, right top, from(white), color-stop(#E1E1E1), to(white));
|
||||||
|
background: -webkit-linear-gradient(left, white, #E1E1E1, white);
|
||||||
|
background: linear-gradient(to right, white, #E1E1E1, white);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue