Git Deployment

I ‘inherited’ the Git server at work — which means I had to learn how the back end component of Git works (beyond my file-system based implementation where there are just clients and a disk location). It is not as complicated as I feared. The chap who had deployed the Git backend at work chose Bonobo — since he no longer works for the company, I cannot just ask why this particular implementation. It’s Windows based and priced in our 0$ budget, and I am certain these were selling points. It seems quite stripped down compared to GitHub too — none of the issue tracking / Wiki / chat about it features. Which, for what my department does, is fine. We are not software developers. We have a lot of internal code for task automation, we have some internal code for departmental web sites, and we have some sample code we hand out to other developers (i.e. someone wants to start using LDAP or ADFS authentication, we can give them a sample implementation in their language). There aren’t feature requests. Generally speaking, there aren’t simultaneous development tasks on a project.

Since I deciphered the server implementation at work, I wanted to set up a Git server at home too. The limited feature set of Bonobo was off-putting. I wanted integrated issue tracking. Looking at the available opensource and free options, I selected GitLab. As a sandbox — poke around the server, see how it works and what features it offers — I wanted something ready-to-go. I noticed that there is a Docker container for the project. I helped a few friends who were testing Docker as a development and deployment methodology (I’ve even suggested it for my employer’s internal development staff … being able to develop and run an application with an integrated web server *without* needing the Windows permissions and configuration for a web server (and doing it all over again when your computer is replaced) seemed efficient. But I’d never actually used a Docker container before. It is incredibly easy.

Install docker — a bit obvious, but that was the most time consuming part of the process. I elected to install it on my Windows laptop for expediency. If we decide not to use GitLab, I haven’t thrown a bunch of unnecessary binaries on the server. Lenovo, as a default, does not enable virtualisation. Getting into the BIOS config tool (shift then click the power button, keep holding shift whilst you click restart) was the most time consuming bit of the installation.

Once Docker is installed, pull the container from the Docker store (docker pull gitlab/gitlab-ce). Then run it (docker run –detach –hostname gitlab.rushworth.us –publish 443:443 –publish 80:80 –publish 22:22 –name gitlab –restart always –volume /srv/gitlab/config://c/gldata/etc –volume /srv/gitlab/logs:/var/log/gitlab –volume /srv/gitlab/data://c/gldata/data –volume /svr/docker/gitlab/gitlab://c/gldata/gitlab gitlab/gitlab-ce:latest). You can remap ports (e.g. publish 8443:443) if needed.

Not quite there yet — you’ve got to edit the container config (docker exec -it gitlab vi /etc/gitlab/gitlab.rb) for your environment. Set a valid external url (external_url ‘http://gitlab.rushworth.us’). I also enabled LDAP authentication to test that out.


gitlab_rails[‘ldap_enabled’] = true

###! **remember to close this block with ‘EOS’ below**
gitlab_rails[‘ldap_servers’] = YAML.load <<-‘EOS’
main: # ‘main’ is the GitLab ‘provider ID’ of this LDAP server
label: ‘LDAP’
host: ‘ADHostname.rushworth.us’
port: 636
uid: ‘sAMAccountName’
method: ‘ssl’ # “tls” or “ssl” or “plain”
bind_dn: ‘cn=UserID,ou=SystemAccounts,dc=domain,dc=ccTLD’
password: ‘AccountPasswordGoesHere’
active_directory: true
allow_username_or_email_login: false
block_auto_created_users: false
base: ‘ou=ResourceUsers,dc=domain,dc=ccTLD’
user_filter: ‘(&(sAMAccountName=*))’ # Can add attribute value to restrict authorized users to GitLab access, we leave open to all valid user accounts in the OU. Should be able to authorize based on group membership using linked attribute value like (&(memberOf=cn=group,ou=groupOU,dc=domain,dc=ccTLD))
attributes:
username: [‘uid’, ‘userid’, ‘sAMAccountName’]
email: [‘mail’, ’email’, ‘userPrincipalName’]
name: ‘cn’
first_name: ‘givenName’
last_name: ‘sn’

EOS


The default is to retain a lot of log files — 30 days! This might be reasonable in a corporate environment, but even for production at home … that’s a lot of space dedicated to log files.


logging[‘logrotate_frequency’] = “daily” # rotate logs daily
logging[‘logrotate_rotate’] = 3 # keep 3 rotated logs
logging[‘logrotate_compress’] = “compress” # see ‘man logrotate’
logging[‘logrotate_method’] = “copytruncate” # see ‘man logrotate’


And finally configure SMTP for outbound mail. We don’t use authentication on our SMTP server; it controls relay based on source IP. We do use starttls, but the certificate is not going to be trusted without additional configuration … so I set the ssl verify mode to none.


gitlab_rails[‘smtp_enable’] = true
gitlab_rails[‘smtp_address’] = “smtp.hostname.ccTLD”
gitlab_rails[‘smtp_port’] = 25
# gitlab_rails[‘smtp_user_name’] = “smtp user”
# gitlab_rails[‘smtp_password’] = “smtp password”
# gitlab_rails[‘smtp_domain’] = “example.com”
# gitlab_rails[‘smtp_authentication’] = “login”
gitlab_rails[‘smtp_enable_starttls_auto’] = true
# gitlab_rails[‘smtp_tls’] = false

###! **Can be: ‘none’, ‘peer’, ‘client_once’, ‘fail_if_no_peer_cert’**
###! Docs: http://api.rubyonrails.org/classes/ActionMailer/Base.html
gitlab_rails[‘smtp_openssl_verify_mode’] = ‘none’


Once the config has been updated, restart the container (docker restart gitlab).

Access the web site and you’ll be prompted to set a password for the admin user, root. You can click the ‘ldap’ tab and log in with Active Directory credentials. Fin.

If we deploy this for a production system, I would set up SSL on the web site and possibly externalize the GitLab database to MySQL. The external database is more of an academic experiment because we already use MySQL (and I still don’t want  to learn about vacuuming PostgreSQL).

Soap Swirls!

I have tried many times to get swirls in soap. What I’ve actually gotten is halfway seized blobs of colour. Still works, still smells nice … but it doesn’t look like the pretty soaps I see online.

Everything I’ve read says to mix the components to a light trace so it won’t seize before you get it poured and swirled. Many attempts later, I have swirls! Two tricks — I mixed the essential oil into the oil before adding lye. Adding the EO after the oil:lye is mixed was just too much mixing. I also used more water than the normal 2:1 water to lye ratio.

Added the lye water to the oil/EO mixture and used the stick blender until it was just combined. There were no longer oil spots floating on top, the entire mixture was a homogeneous colour. I split the soap into two pots and stirred in the clay with a tiny whisk. At this point, I still had REALLY runny soap.

I used a modified column pour technique — a rounded cup in the middle of a large mold. This made concentric rings of colour. I then used a very thin wooden dowel / gigantic toothpick that was used in a sandwich at a local restaurant and dragged lines from the perimeter of the mold into the center. The shape held! Popped the whole thing in the oven with the light on and let it sit for 24 hours. Removed it from the mold and it was really soft compared to my normal recipe. That’s the extra water – it needs to cure longer. Bonus, though – it was soft enough to cut easily with a knife.

 

 

When cut into bars, there are actual swirls!

Stromboli Recipe

I made, well not quite a stromboli (as I understand it, stromboli have tomato sauce inside, and this was completely without tomato sauce). The bread part is easy enough — you can use whatever pizza dough recipe you fancy. I had purchased KAF’s Artisan Bread Flour when it was on sale a few months ago. Or their French style flour and used a traditional baguette recipe (3c flour, 1t salt, 1c or so water, and 2 1/4t yeast kneaded for a long time to make a chewy bread. Normal bread process – mix/knead, sit until doubled in bulk). For additional flavour, I added 1T of Italian spices to the flour. Once the dough has finished rising, preheat the oven to 550 F.

Take a chunk (I used about a quarter of the dough) and roll it out onto a silicone baking mat. The dough shouldn’t be too thick – somewhere around an eighth of an inch. I made very large stromboli to be cut when served, so the rectangle of dough was about 12″ x 9″. Brush the dough with roasted garlic butter (1T melted salted butter, 1-2 cloves roasted garlic)

Spread filling in the rectangle – leaving some dough on either side to fold in, some dough on the bottom to seal the thing, and a lot of dough on the top to fold over.

Fold the sides along the line shown below — this will seal the ends.

Fold the large piece of dough down to cover the filling. Then stretch the small piece of dough up over stromboli and seal it to the other piece of dough.

Place on a half sheet pan seam side down. If a glossy, crunchy crust is desired, brush with egg wash (mix an egg with a splash of water), let sit for a minute, and then brush again with egg wash. For a softer crust, brush with roasted garlic butter or butter.

Using a sharp knife or bread lame, slice five diagonal lines along the stromboli. I sliced almost completely through the dough and allowed it to split open as it baked. Bake for 10-15 minutes.

What can you put in a stromboli? Traditionally, you cover the dough with tomato sauce, sprinkle on cheese, add Italian meats, then sprinkle more cheese. I wasn’t in the mood for tomato sauce. I made two fillings – 1c ricotta cheese, 1/2c shredded sharp cheddar, and 1c shredded broccoli (this is a great way to use up broccoli stems if you have some left over from another recipe). The other filling was 1c ricotta, 1/2c shredded sharp cheddar, 1c shredded chicken, and 2 diced peaches.

Alternative Fact: Don’t Quote Me On That

Alternative Fact: Trump has tapes from his meetings with Comey (and tune in later this week to hear exciting news about them!).

Real Fact: Rationally, if Trump had something that exonerated him, he would have produced the evidence WEEKS ago. Hell, the day after Comey’s testimony would have been late but suitably theatrical. But it is a little silly to expect rational behaviour from someone who has thus far displayed nothing of the sort.

With the “but it was a ‘scare quote’ so he didn’t literally mean it” argument from March’s wire tapping bit of craziness

how can I possibly be asked to believe he has “tapes”?

Bonus real fact: It is impossible to differentiate scare quotes (the phrase in quotes is used sarcastically, ironically, or otherwise without intending the actual meaning of the word) from highlight quote (the “word” is what should be emphasized in this sentence) without prescient knowledge.

Broadcast Blackout

Seems like the White House Press Office is trialing banning audio and video recordings of their press briefings. My first thought is that this can backfire. You don’t want to give me video to go with my report, I’ll make some. They are allowed to write stuff down, right? Some agency gets a court stenographer credentialed for the briefing; Melissa McCarthy can dress up and recreate the scene for news agencies to record. Get the political cartoonist to draw the scene a la the courtroom sketches from closed proceedings. Or, hell, send the sketch artist you’ve already got on staff.

 

Amazon Acquisition Of Whole Foods

I don’t know why everyone is talking about Amazon Fresh expanding to a radius around every Whole Foods store. There’s not a lot of cost savings or synergy there. Amazon will use their own logistics solution to move thousands of orders to a Whole Foods distribution center and those orders ride on trucks already headed out to the Whole Foods stores. You will stop in after work / on the weekend and pick them up. Saves the expensive last-mile shipping bit (where Amazon currently has to pay money to Fedex or UPS to get a package from their distribution centre to your doorstep). And may increase Whole Foods grocery market share … if you are going there anyway to pick up your stuff, saves time getting your groceries too.

Apache Airflow — No Backfill

A lot of software seems to be designed to save the user from themselves. This is great 90% of the time when you mess up and really want their help (or when the software’s help is cosmetic … my gripe against auto-correcting smart quotes, as an example). But I seem to fall into the other 10% a lot. And I mean a LOT. Apache Airflow jobs try to grab new information all.of.the.time. It’s a feature called “backfill”, and I’m sure it helps all sorts of people do exactly what they really wanted done. Not me 🙁

Having updated to 1.8, though, I now see a configuration parameter to instruct a DAG not to do me any favors. Just do what you’re asked when you’re asked to do it: catchup = False

DAG('testjob', default_args=default_args, schedule_interval='0 * * * *', catchup=False)

The Only

It helps me to remember that my kid has never once asked for a *real* sibling. She is asking for a fantasy sibling — someone who always wants to play the game she want to play, never asks to share anything, takes absolutely none of my time, doesn’t make noise while she is reading but doesn’t complain when she is running around screaming, never gets the bigger bowl of ice cream, never blames her for anything, and promptly disappears when she is bored of having a sibling.

There’s no such thing. I don’t feel bad about not getting my kid a unicorn or a trip to Jupiter to harvest diamonds … I don’t feel bad about not “giving” her a sibling either.