From a3dc0c92d373be7f50d06304ef08a578ea7550d1 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 8 Apr 2023 12:32:25 +0300 Subject: Update content for gemtext --- gemfeed/atom.xml | 2214 ++++++++++----- gemfeed/atom.xml.tmp | 7609 -------------------------------------------------- 2 files changed, 1493 insertions(+), 8330 deletions(-) delete mode 100644 gemfeed/atom.xml.tmp (limited to 'gemfeed') diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml index 1241a848..408db2c3 100644 --- a/gemfeed/atom.xml +++ b/gemfeed/atom.xml @@ -1,6 +1,6 @@ - 2023-04-03T23:19:57+03:00 + 2023-04-08T12:32:07+03:00 foo.zone feed To be in the .zone! @@ -18,9 +18,12 @@ These are my personal takeaways after reading 'Never split the difference' by Chris Voss. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.
-

"Never split the difference" book notes

-

Published at 2023-04-01T20:00:17+03:00

-

These are my personal takeaways after reading "Never split the difference" by Chris Voss. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.

+

"Never split the difference" book notes


+
+Published at 2023-04-01T20:00:17+03:00
+
+These are my personal takeaways after reading "Never split the difference" by Chris Voss. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.
+
          ,..........   ..........,
      ,..,'          '.'          ',..,
@@ -32,77 +35,106 @@
  '''''''''''''''''';''';''''''''''''''''''
                     '''
 
-

Tactical listening, spreading empathy

-

Be a mirror, copy each other to be comfy with each other to build up trust. Mirroring is mainly body language. A mirror is to repeat the words the other just said. Simple but effective.

+
+

Tactical listening, spreading empathy


+
+Be a mirror, copy each other to be comfy with each other to build up trust. Mirroring is mainly body language. A mirror is to repeat the words the other just said. Simple but effective.
+
  • A mirror needs space and silence between the words. At least 4 seconds.
  • A mirror might be awkward to be used at first, especially with a question coupled to it.
  • We fear what's different and are drawn to what is similar.
  • -
-

Mirror training is like Jedi training. Simple but effective. A mirror needs space. Be silent after "you want this?"

-

Mindset of discovery

-

Try to have multiple realities in your mind and use facts to distinguish between real and false.

+
+Mirror training is like Jedi training. Simple but effective. A mirror needs space. Be silent after "you want this?"
+
+

Mindset of discovery


+
+Try to have multiple realities in your mind and use facts to distinguish between real and false.
+
  • Focus on what the counterpart has to say and what he needs and wants. Understanding him makes him vulnerable.
  • Empathy understanding the other person from his perspective, but it does not mean agreeing with him.
  • Detect and label the emotions of others for your powers.
  • To be understood seems to solve all problems magically.
  • -
-

Try: to put a label on someone's emotion and then be silent. Wait for the other to reveal himself. "You seem unhappy about this?"

-

More tips

+
+Try: to put a label on someone's emotion and then be silent. Wait for the other to reveal himself. "You seem unhappy about this?"
+
+

More tips


+
  • Put on a poker face and don't show emotions.
  • Slow things down. Don't be a problem solver.
  • Smile while you are talking, even on the phone. Be easy and encouraging.
  • Being right is not the key to successful negotiation; being mindful is.
  • Be in the safe zone of empathy and acknowledge bad news.
  • -
-

"No" starts the conversation

-

When the opponent starts with a "no", he feels in control and comfortable. That's why he has to start with "no".

+
+

"No" starts the conversation


+
+When the opponent starts with a "no", he feels in control and comfortable. That's why he has to start with "no".
+
  • "Yes" and "maybe" might be worthless, but "no" starts the conversation.
  • If someone is saying "no" to you, he will be open to what you have to say next.
  • "No" is not stopping the negotiation but will open up opportunities you were not thinking about before.
  • Start with "no". Great negotiators seek "no" because that's when the great discussions begin.
  • A "no" can be scary if you are not used to it. If your biggest fear is "no", then you can't negotiate.
  • -
-

Get a "That's right" when negotiating. Don't get a "you're right". You can summarise the opponent to get a "that's right".

-

Win-win

-

Win-win is a naive approach when encountering the win-lose counterpart, but always cooperate. Don't compromise, and don't split the difference. We don't compromise because it's right; we do it because it is easy. You must embrace the hard stuff; that's where the great deals are.

-

On Deadlines

+
+Get a "That's right" when negotiating. Don't get a "you're right". You can summarise the opponent to get a "that's right".
+
+

Win-win


+
+Win-win is a naive approach when encountering the win-lose counterpart, but always cooperate. Don't compromise, and don't split the difference. We don't compromise because it's right; we do it because it is easy. You must embrace the hard stuff; that's where the great deals are.
+
+

On Deadlines


+
  • All deadlines are imaginary.
  • Most of the time, deadlines unsettle us without a good reason.
  • They push a deal to a conclusion.
  • They rush the counterpart to cause pressure and anxiety.
  • -
-

Analyse the opponent

+
+

Analyse the opponent


+
  • Understand the motivation of people behind the table as well.
  • Ask how affected they will be.
  • Determine your and the opposite negotiation style. Accommodation, analyst, assertive.
  • Treat them how they need to be treated.
  • -
-

The person on the other side is never the issue; the problem is the issue. Keep this in mind to avoid emotional issues with the person and focus on the problem, not the person. The bond is essential; never create an enemy.

-

Use different ways of saying "no."

-

I had paid my rent always in time. I had positive experiences with the building and would be sad for the landlord to lose a good tenant. I am looking for a win-win agreement between us. Pulling out the research, other neighbours offer much lower prices even if your building is a better location and services. How can I effort 200 more....

-

...then put an extreme anker.

-

You always have to embrace thoughtful confrontation for good negotiation and life. Don't avoid honest, clear conflict. It will give you the best deals. Compromises are mostly bad deals for both sides. Most people don't negotiate a win-win but a win-lose. Know the best and worst outcomes and what is acceptable for you.

-

Calibrated question

-

Calibrated questions. Give the opponent a sense of power. Ask open-how questions to get the opponent to solve your problem and move him in your direction. Calibrated questions are the best tools. Summarise everything, and then ask, "how I am supposed to do that?". Asking for help this way with a calibrated question is a powerful tool for joint problem solving

-

Being calm and respectful is essential. Without control of your emotions, it won't work. The counterpart will have no idea how constrained they are with your question. Avoid questions which get a yes or short answers. Use "why?".

-

Counterparts are more involved if these are their solutions. The counterpart must answer with "that's right", not "you are right". He has to own the problem. If not, then add more why questions.

+
+The person on the other side is never the issue; the problem is the issue. Keep this in mind to avoid emotional issues with the person and focus on the problem, not the person. The bond is essential; never create an enemy.
+
+

Use different ways of saying "no."


+
+I had paid my rent always in time. I had positive experiences with the building and would be sad for the landlord to lose a good tenant. I am looking for a win-win agreement between us. Pulling out the research, other neighbours offer much lower prices even if your building is a better location and services. How can I effort 200 more....
+
+...then put an extreme anker.
+
+You always have to embrace thoughtful confrontation for good negotiation and life. Don't avoid honest, clear conflict. It will give you the best deals. Compromises are mostly bad deals for both sides. Most people don't negotiate a win-win but a win-lose. Know the best and worst outcomes and what is acceptable for you.
+
+

Calibrated question


+
+Calibrated questions. Give the opponent a sense of power. Ask open-how questions to get the opponent to solve your problem and move him in your direction. Calibrated questions are the best tools. Summarise everything, and then ask, "how I am supposed to do that?". Asking for help this way with a calibrated question is a powerful tool for joint problem solving
+
+Being calm and respectful is essential. Without control of your emotions, it won't work. The counterpart will have no idea how constrained they are with your question. Avoid questions which get a yes or short answers. Use "why?".
+
+Counterparts are more involved if these are their solutions. The counterpart must answer with "that's right", not "you are right". He has to own the problem. If not, then add more why questions.
+
  • Tone and body language need to align with what people are saying.
  • Deal with it via a labelled question.
  • Liers tend to talk with "them" and "their" and not with "I".
  • Also, liars tend to talk in complex sentences.
  • -
-

Prepare 3 to 5 calibrated questions for your counterpart. Be curious what is really motivating the other side. You can get out the "Black Swan".

-

The black swan

-

What we don't know can break our deal. Uncovering it can bring us unexpected success. You get what you ask for in this world, but you must learn to ask correctly. Reveal the black swan by asking questions.

-

More

-

Establish a range at top places like corp. I get... (e.g. remote London on a project basis). Set a high salary range and not a number. Also, check on LinkedIn premium for the salaries.

+
+Prepare 3 to 5 calibrated questions for your counterpart. Be curious what is really motivating the other side. You can get out the "Black Swan".
+
+

The black swan


+
+What we don't know can break our deal. Uncovering it can bring us unexpected success. You get what you ask for in this world, but you must learn to ask correctly. Reveal the black swan by asking questions.
+
+

More


+
+Establish a range at top places like corp. I get... (e.g. remote London on a project basis). Set a high salary range and not a number. Also, check on LinkedIn premium for the salaries.
+
  • Give an unexpected gift, e.g. show them my pet project and publicity for engineering.
  • Use an odd number, which makes you seem to have thought a lot about the sum and calculated it.
  • @@ -113,13 +145,17 @@
  • Tactical empathy, listening as a martial art. It is emotional intelligence on steroids.
  • Being right isn't the key to a successful negotiation, but having the correct mindset is.
  • Don't shop the groceries when you are hungry.
  • -
-

Slow.... it.... down....

-

Other book notes of mine are:

-2023-04-01 "Never split the difference" book notes (You are currently reading this)
-2023-03-16 "The Pragmatic Programmer" book notes
-

E-Mail your comments to hi@paul.cyou :-)

-Back to the main site
+
+Slow.... it.... down....
+
+Other book notes of mine are:
+
+2023-04-01 "Never split the difference" book notes (You are currently reading this)
+2023-03-16 "The Pragmatic Programmer" book notes
+
+E-Mail your comments to hi@paul.cyou :-)
+
+Back to the main site
@@ -135,8 +171,10 @@ I proudly announce that I've released Gemtexter version `2.0.0`. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.
-

Gemtexter 2.0.0 - Let's Gemtext again^2

-

Published at 2023-03-25T17:50:32+02:00

+

Gemtexter 2.0.0 - Let's Gemtext again^2


+
+Published at 2023-03-25T17:50:32+02:00
+
 -=[ typewriters ]=-  1/98
 
@@ -149,14 +187,23 @@
  jgs  `"""""""""`      |o=======.|
   mod. by Paul Buetow  `"""""""""`
 
-

I proudly announce that I've released Gemtexter version 2.0.0. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.

-https://codeberg.org/snonux/gemtexter
-

This is a new major release, so it contains a breaking change (see "Meta cache made obsolete").

-

Let's list what's new!

-

Minimal template engine

-

Gemtexter now supports templating, enabling dynamically generated content to .gmi files before converting anything to any output format like HTML and Markdown.

-

A template file name must have the suffix gmi.tpl. A template must be put into the same directory as the Gemtext .gmi file to be generated. Gemtexter will generate a Gemtext file index.gmi from a given template index.gmi.tpl. A <<< and >>> encloses a multiline template. All lines starting with << will be evaluated as a single line of Bash code and the output will be written into the resulting Gemtext file.

-

For example, the template index.gmi.tpl:

+
+I proudly announce that I've released Gemtexter version 2.0.0. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.
+
+https://codeberg.org/snonux/gemtexter
+
+This is a new major release, so it contains a breaking change (see "Meta cache made obsolete").
+
+Let's list what's new!
+
+

Minimal template engine


+
+Gemtexter now supports templating, enabling dynamically generated content to .gmi files before converting anything to any output format like HTML and Markdown.
+
+A template file name must have the suffix gmi.tpl. A template must be put into the same directory as the Gemtext .gmi file to be generated. Gemtexter will generate a Gemtext file index.gmi from a given template index.gmi.tpl. A <<< and >>> encloses a multiline template. All lines starting with << will be evaluated as a single line of Bash code and the output will be written into the resulting Gemtext file.
+
+For example, the template index.gmi.tpl:
+
 # Hello world
 
@@ -170,7 +217,9 @@ Welcome to this capsule!
   done
 >>>
 
-

... results into the following index.gmi after running ./gemtexter --generate (or ./gemtexter --template, which instructs to do only template processing and nothing else):

+
+... results into the following index.gmi after running ./gemtexter --generate (or ./gemtexter --template, which instructs to do only template processing and nothing else):
+
 # Hello world
 
@@ -189,7 +238,9 @@ Multiline template line 8
 Multiline template line 9
 Multiline template line 10
 
-

Another thing you can do is insert an index with links to similar blog posts. E.g.:

+
+Another thing you can do is insert an index with links to similar blog posts. E.g.:
+
 See more entries about DTail and Golang:
 
@@ -197,7 +248,9 @@ See more entries about DTail and Golang:
 
 Blablabla...
 
-

... scans all other post entries with dtail and golang in the file name and generates a link list like this:

+
+... scans all other post entries with dtail and golang in the file name and generates a link list like this:
+
 See more entries about DTail and Golang:
 
@@ -208,25 +261,37 @@ See more entries about DTail and Golang:
 
 Blablabla...
 
-

Added hooks

-

You can configure PRE_GENERATE_HOOK and POST_PUBLISH_HOOK to point to scripts to be executed before running --generate, or after running --publish. E.g. you could populate some of the content by an external script before letting Gemtexter do its thing or you could automatically deploy the site after running --publish.

-

The sample config file gemtexter.conf includes this as an example now; these scripts will only be executed when they actually exist:

+
+

Added hooks


+
+You can configure PRE_GENERATE_HOOK and POST_PUBLISH_HOOK to point to scripts to be executed before running --generate, or after running --publish. E.g. you could populate some of the content by an external script before letting Gemtexter do its thing or you could automatically deploy the site after running --publish.
+
+The sample config file gemtexter.conf includes this as an example now; these scripts will only be executed when they actually exist:
+
 declare -xr PRE_GENERATE_HOOK=./pre_generate_hook.sh
 declare -xr POST_PUBLISH_HOOK=./post_publish_hook.sh
 
-

Use of safer Bash options

-

Gemtexter now does set -euf -o pipefile, which helps to eliminate bugs and to catch scripting errors sooner. Previous versions only set -e.

-

Meta cache made obsolete

-

Here is the breaking change to older versions of Gemtexter. The $BASE_CONTENT_DIR/meta directory was made obsolete. meta was used to store various information about all the blog post entries to make generating an Atom feed in Bash easier. Especially the publishing dates of each post were stored there. Instead, the publishing date is now encoded in the .gmi file. And if it is missing, Gemtexter will set it to the current date and time at first run.

-

An example blog post without any publishing date looks like this:

+
+

Use of safer Bash options


+
+Gemtexter now does set -euf -o pipefile, which helps to eliminate bugs and to catch scripting errors sooner. Previous versions only set -e.
+
+

Meta cache made obsolete


+
+Here is the breaking change to older versions of Gemtexter. The $BASE_CONTENT_DIR/meta directory was made obsolete. meta was used to store various information about all the blog post entries to make generating an Atom feed in Bash easier. Especially the publishing dates of each post were stored there. Instead, the publishing date is now encoded in the .gmi file. And if it is missing, Gemtexter will set it to the current date and time at first run.
+
+An example blog post without any publishing date looks like this:
+
 % cat gemfeed/2023-02-26-title-here.gmi
 # Title here
 
 The remaining content of the Gemtext file...
 
-

Gemtexter will add a line starting with > Published at ... now. Any subsequent Atom feed generation will then use that date.

+
+Gemtexter will add a line starting with > Published at ... now. Any subsequent Atom feed generation will then use that date.
+
 % cat gemfeed/2023-02-26-title-here.gmi
 # Title here
@@ -235,17 +300,25 @@ The remaining content of the Gemtext file...
 
 The remaining content of the Gemtext file...
 
-

XMLLint support

-

Optionally, when the xmllint binary is installed, Gemtexter will perform a simple XML lint check against the Atom feed generated. This is a double-check of whether the Atom feed is a valid XML.

-

More

-

Additionally, there were a couple of bug fixes, refactorings and overall improvements in the documentation made.

-

Other related posts are:

-2023-03-25 Gemtexter 2.0.0 - Let's Gemtext again^2 (You are currently reading this)
-2022-08-27 Gemtexter 1.1.0 - Let's Gemtext again
-2021-06-05 Gemtexter - One Bash script to rule it all
-2021-04-24 Welcome to the Geminispace
-

E-Mail your comments to hi@paul.cyou :-)

-Back to the main site
+
+

XMLLint support


+
+Optionally, when the xmllint binary is installed, Gemtexter will perform a simple XML lint check against the Atom feed generated. This is a double-check of whether the Atom feed is a valid XML.
+
+

More


+
+Additionally, there were a couple of bug fixes, refactorings and overall improvements in the documentation made.
+
+Other related posts are:
+
+2023-03-25 Gemtexter 2.0.0 - Let's Gemtext again^2 (You are currently reading this)
+2022-08-27 Gemtexter 1.1.0 - Let's Gemtext again
+2021-06-05 Gemtexter - One Bash script to rule it all
+2021-04-24 Welcome to the Geminispace
+
+E-Mail your comments to hi@paul.cyou :-)
+
+Back to the main site
@@ -261,9 +334,12 @@ The remaining content of the Gemtext file... These are my personal takeaways after reading 'The Pragmatic Programmer' by David Thomas and Andrew Hunt. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.
-

"The Pragmatic Programmer" book notes

-

Published at 2023-03-16T00:55:20+02:00

-

These are my personal takeaways after reading "The Pragmatic Programmer" by David Thomas and Andrew Hunt. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.

+

"The Pragmatic Programmer" book notes


+
+Published at 2023-03-16T00:55:20+02:00
+
+These are my personal takeaways after reading "The Pragmatic Programmer" by David Thomas and Andrew Hunt. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.
+
          ,..........   ..........,
      ,..,'          '.'          ',..,
@@ -275,58 +351,81 @@ The remaining content of the Gemtext file...
  '''''''''''''''''';''';''''''''''''''''''
                     '''
 
-

Think about your work while doing it - every day on every project. Have a feeling of continuous improvement.

+
+Think about your work while doing it - every day on every project. Have a feeling of continuous improvement.
+
  • Be a realist.
  • Smell challenges.
  • Care about your craft.
  • Code can always be flawed, but it can meet the requirements.
  • You should be proud of your code, though.
  • -
-

No one writes perfect code, including you. However:

+
+No one writes perfect code, including you. However:
+
  • Paranoia is good thinking.
  • Practice defensive programming and crash early.
  • Crashing is often the best thing you can do.
  • Changes should be reversible.
  • -
-

Erlang: Defensive programming is a waste of time. Let it crash. "This can never happen" - don't practise that kind of self-deception when programming.

-

Leave assertions in the code, even in production. Only leave out the assertions causing the performance issues.

-

Take small steps, always. Get feedback, too, for each of the steps the code does. Avoid fortune telling. If you have to involve in it, then the step is too large.

-

Decouple the code (e.g. OOP or functional programming). Prefer interfaces for types and mixins for a class extension over class inheritance.

+
+Erlang: Defensive programming is a waste of time. Let it crash. "This can never happen" - don't practise that kind of self-deception when programming.
+
+Leave assertions in the code, even in production. Only leave out the assertions causing the performance issues.
+
+Take small steps, always. Get feedback, too, for each of the steps the code does. Avoid fortune telling. If you have to involve in it, then the step is too large.
+
+Decouple the code (e.g. OOP or functional programming). Prefer interfaces for types and mixins for a class extension over class inheritance.
+
  • Refactor now and not later.
  • Later, it will be even more painful.
  • -
-

Don't think outside the box. Find the box. The box is more extensive than you think. Think about the hard problem at hand. Do you have to do it a certain way, or do you have to do it at all?

-

Do what works and not what's fashionable. E.g. does SCRUM make sense? The goal is to deliver deliverables and not to "become" agile.

-

Continuous learning

-

Add new tools to your repertoire every day and keep the momentum up. Learning new things is your most crucial aspect. Invest regularly in your knowledge portfolio. The learning process extends your thinking. It does not matter if you will never use it.

+
+Don't think outside the box. Find the box. The box is more extensive than you think. Think about the hard problem at hand. Do you have to do it a certain way, or do you have to do it at all?
+
+Do what works and not what's fashionable. E.g. does SCRUM make sense? The goal is to deliver deliverables and not to "become" agile.
+
+

Continuous learning


+
+Add new tools to your repertoire every day and keep the momentum up. Learning new things is your most crucial aspect. Invest regularly in your knowledge portfolio. The learning process extends your thinking. It does not matter if you will never use it.
+
  • Learn a new programming language every year.
  • Read a technical book every month.
  • Take courses.
  • -
-

Think critically about everything you learn. Use paper for your notes. There is something special about it.

-

Stay connected

-

It's your life, and you own it. Bruce Lee once said:

-

"I am not on the world to life after your expectations, neither are you to life after mine."

+
+Think critically about everything you learn. Use paper for your notes. There is something special about it.
+
+

Stay connected


+
+It's your life, and you own it. Bruce Lee once said:
+
+"I am not on the world to life after your expectations, neither are you to life after mine."
+
  • Go to meet-ups and actively engage.
  • Stay current.
  • Dealing with computers is hard. Dealing with people is harder.
  • -
-

It's your life. Share it, celebrate it, be proud and have fun.

-

The story of stone soup

-

How to motivate others to contribute something (e.g. ideas to a startup):

-

A kindly, old stranger was walking through the land when he came upon a village. As he entered, the villagers moved towards their homes, locking doors and windows. The stranger smiled and asked, why are you all so frightened. I am a simple traveler, looking for a soft place to stay for the night and a warm place for a meal. "There's not a bite to eat in the whole province," he was told. "We are weak and our children are starving. Better keep moving on." "Oh, I have everything I need," he said. "In fact, I was thinking of making some stone soup to share with all of you." He pulled an iron cauldron from his cloak, filled it with water, and began to build a fire under it. Then, with great ceremony, he drew an ordinary-looking stone from a silken bag and dropped it into the water. By now, hearing the rumor of food, most of the villagers had come out of their homes or watched from their windows. As the stranger sniffed the "broth" and licked his lips in anticipation, hunger began to overcome their fear. "Ahh," the stranger said to himself rather loudly, "I do like a tasty stone soup. Of course, stone soup with cabbage -- that's hard to beat." Soon a villager approached hesitantly, holding a small cabbage he'd retrieved from its hiding place, and added it to the pot. "Wonderful!!" cried the stranger. "You know, I once had stone soup with cabbage and a bit of salt beef as well, and it was fit for a king." The village butcher managed to find some salt beef . . . And so it went, through potatoes, onions, carrots, mushrooms, and so on, until there was indeed a delicious meal for everyone in the village to share. The village elder offered the stranger a great deal of money for the magic stone, but he refused to sell it and traveled on the next day. As he left, the stranger came upon a group of village children standing near the road. He gave the silken bag containing the stone to the youngest child, whispering to a group, "It was not the stone, but the villagers that had performed the magic."

-

By working together, everyone contributes what they can, achieving a greater good together.

-

Other book notes of mine are:

-2023-04-01 "Never split the difference" book notes
-2023-03-16 "The Pragmatic Programmer" book notes (You are currently reading this)
-

E-Mail your comments to hi@paul.cyou :-)

-More books and other resources I found useful.
-Back to the main site
+
+It's your life. Share it, celebrate it, be proud and have fun.
+
+

The story of stone soup


+
+How to motivate others to contribute something (e.g. ideas to a startup):
+
+A kindly, old stranger was walking through the land when he came upon a village. As he entered, the villagers moved towards their homes, locking doors and windows. The stranger smiled and asked, why are you all so frightened. I am a simple traveler, looking for a soft place to stay for the night and a warm place for a meal. "There's not a bite to eat in the whole province," he was told. "We are weak and our children are starving. Better keep moving on." "Oh, I have everything I need," he said. "In fact, I was thinking of making some stone soup to share with all of you." He pulled an iron cauldron from his cloak, filled it with water, and began to build a fire under it. Then, with great ceremony, he drew an ordinary-looking stone from a silken bag and dropped it into the water. By now, hearing the rumor of food, most of the villagers had come out of their homes or watched from their windows. As the stranger sniffed the "broth" and licked his lips in anticipation, hunger began to overcome their fear. "Ahh," the stranger said to himself rather loudly, "I do like a tasty stone soup. Of course, stone soup with cabbage -- that's hard to beat." Soon a villager approached hesitantly, holding a small cabbage he'd retrieved from its hiding place, and added it to the pot. "Wonderful!!" cried the stranger. "You know, I once had stone soup with cabbage and a bit of salt beef as well, and it was fit for a king." The village butcher managed to find some salt beef . . . And so it went, through potatoes, onions, carrots, mushrooms, and so on, until there was indeed a delicious meal for everyone in the village to share. The village elder offered the stranger a great deal of money for the magic stone, but he refused to sell it and traveled on the next day. As he left, the stranger came upon a group of village children standing near the road. He gave the silken bag containing the stone to the youngest child, whispering to a group, "It was not the stone, but the villagers that had performed the magic."
+
+By working together, everyone contributes what they can, achieving a greater good together.
+
+Other book notes of mine are:
+
+2023-04-01 "Never split the difference" book notes
+2023-03-16 "The Pragmatic Programmer" book notes (You are currently reading this)
+
+E-Mail your comments to hi@paul.cyou :-)
+
+More books and other resources I found useful.
+Back to the main site
@@ -737,8 +836,10 @@ nmap ,j :call OpenJournalPage()<CR> This will be a quick blog post, as I am busy with my personal life now. I have relocated to a different country and am still busy arranging things. So bear with me :-)
-

Installing DTail on OpenBSD

-

Published at 2022-10-30T11:03:19+02:00

+

Installing DTail on OpenBSD


+
+Published at 2022-10-30T11:03:19+02:00
+
        ,_---~~~~~----._
  _,,_,*^____      _____``*g*\"*,
@@ -775,18 +876,29 @@ nmap ,j :call OpenJournalPage()<CR>
                             /   `._____V_____V'
                                        '     '
 
-

This will be a quick blog post, as I am busy with my personal life now. I have relocated to a different country and am still busy arranging things. So bear with me :-)

-

In this post, I want to give a quick overview (or how-to) about installing DTail on OpenBSD, as the official documentation only covers Red Hat and Fedora Linux! And this blog post will also be used as my reference!

-https://dtail.dev
-

I am using Rexify for my OpenBSD automation. Check out the following article covering my Rex setup in a little bit more detail:

-Let's Encrypt with OpenBSD and Rex
-

I will also mention some relevant Rexfile snippets in this post!

-

Compile it

-

First of all, DTail needs to be downloaded and compiled. For that, git, go, and gmake are required:

+
+This will be a quick blog post, as I am busy with my personal life now. I have relocated to a different country and am still busy arranging things. So bear with me :-)
+
+ In this post, I want to give a quick overview (or how-to) about installing DTail on OpenBSD, as the official documentation only covers Red Hat and Fedora Linux! And this blog post will also be used as my reference!
+
+https://dtail.dev
+
+I am using Rexify for my OpenBSD automation. Check out the following article covering my Rex setup in a little bit more detail:
+
+Let's Encrypt with OpenBSD and Rex
+
+I will also mention some relevant Rexfile snippets in this post!
+
+

Compile it


+
+First of all, DTail needs to be downloaded and compiled. For that, git, go, and gmake are required:
+
 $ doas pkg_add git go gmake
 
-

I am happy that the Go Programming Language is readily available in the OpenBSD packaging system. Once the dependencies got installed, clone DTail and compile it:

+
+I am happy that the Go Programming Language is readily available in the OpenBSD packaging system. Once the dependencies got installed, clone DTail and compile it:
+
 $ mkdir git
 $ cd git
@@ -794,32 +906,44 @@ $ git clone https://github.com/mimecast/dtail
 $ cd dtail
 $ gmake 
 
-

You can verify the version by running the following command:

+
+You can verify the version by running the following command:
+
 $ ./dtail --version
  DTail  4.1.0  Protocol 4.1  Have a lot of fun!
 $ file dtail
  dtail: ELF 64-bit LSB executable, x86-64, version 1
 
-

Now, there isn't any need anymore to keep git, go and gmake, so they can be deinstalled now:

+
+Now, there isn't any need anymore to keep git, go and gmake, so they can be deinstalled now:
+
 $ doas pkg_delete git go gmake
 
-

One day I shall create an official OpenBSD port for DTail.

-

Install it

-

Installing the binaries is now just a matter of copying them to /usr/local/bin as follows:

+
+One day I shall create an official OpenBSD port for DTail.
+
+

Install it


+
+Installing the binaries is now just a matter of copying them to /usr/local/bin as follows:
+
 $ for bin in dserver dcat dgrep dmap dtail dtailhealth; do
   doas cp -p $bin /usr/local/bin/$bin
   doas chown root:wheel /usr/local/bin/$bin
 done
 
-

Also, we will be creating the _dserver service user:

+
+Also, we will be creating the _dserver service user:
+
 $ doas adduser -class nologin -group _dserver -batch _dserver
 $ doas usermod -d /var/run/dserver/ _dserver
 
-

The OpenBSD init script is created from scratch (not part of the official DTail project). Run the following to install the bespoke script:

+
+The OpenBSD init script is created from scratch (not part of the official DTail project). Run the following to install the bespoke script:
+
 $ cat <<'END' | doas tee /etc/rc.d/dserver
 #!/bin/ksh
@@ -841,8 +965,11 @@ rc_cmd $1 &
 END
 $ doas chmod 755 /etc/rc.d/dserver
 
-

Rexification

-

This is the task for setting it up via Rex. Note the . . . ., that's a placeholder which we will fill up more and more during this blog post:

+
+

Rexification


+
+This is the task for setting it up via Rex. Note the . . . ., that's a placeholder which we will fill up more and more during this blog post:
+
 desc 'Setup DTail';
 task 'dtail', group => 'frontends',
@@ -865,14 +992,19 @@ task 'dtail', group => 'frontends',
       service 'dserver', ensure => 'started';
    };
 
-

Configure it

-

Now, DTail is fully installed but still needs to be configured. Grab the default config file from GitHub ...

+
+

Configure it


+
+Now, DTail is fully installed but still needs to be configured. Grab the default config file from GitHub ...
+
 $ doas mkdir /etc/dserver
 $ curl https://raw.githubusercontent.com/mimecast/dtail/master/samples/dtail.json.sample |
     doas tee /etc/dserver/dtail.json
 
-

... and then edit it and adjust LogDir in the Common section to /var/log/dserver. The result will look like this:

+
+... and then edit it and adjust LogDir in the Common section to /var/log/dserver. The result will look like this:
+
   "Common": {
     "LogDir": "/var/log/dserver",
@@ -883,8 +1015,11 @@ $ curl https://raw.githubusercontent.com/mimecast/dtail/master/samples/dtail.jso
     "LogLevel": "Info"
   }
 
-

Rexification

-

That's as simple as adding the following to the Rex task:

+
+

Rexification


+
+That's as simple as adding the following to the Rex task:
+
 file '/etc/dserver',
   ensure => 'directory';
@@ -896,9 +1031,13 @@ file '/etc/dserver/dtail.json',
   mode => '755',
   on_change => sub { $restart = TRUE };
 
-

Update the key cache for it

-

DTail relies on SSH for secure authentication and communication. However, the system user _dserver has no permission to read the SSH public keys from the user's home directories, so the DTail server also checks for available public keys in an alternative path /var/run/dserver/cache.

-

The following script, populating the DTail server key cache, can be run periodically via CRON:

+
+

Update the key cache for it


+
+DTail relies on SSH for secure authentication and communication. However, the system user _dserver has no permission to read the SSH public keys from the user's home directories, so the DTail server also checks for available public keys in an alternative path /var/run/dserver/cache.
+
+The following script, populating the DTail server key cache, can be run periodically via CRON:
+
 $ cat <<'END' | doas tee /usr/local/bin/dserver-update-key-cache.sh
 #!/bin/ksh
@@ -938,13 +1077,18 @@ echo 'All set...'
 END
 $ doas chmod 500 /usr/local/bin/dserver-update-key-cache.sh
 
-

Note that the script above is a slight variation of the official DTail script. The official DTail one is a bash script, but on OpenBSD, there's ksh. I run it once daily by adding it to the daily.local:

+
+Note that the script above is a slight variation of the official DTail script. The official DTail one is a bash script, but on OpenBSD, there's ksh. I run it once daily by adding it to the daily.local:
+
 $ echo /usr/local/bin/dserver-update-key-cache.sh | doas tee -a /etc/daily.local
 /usr/local/bin/dserver-update-key-cache.sh
 
-

Rexification

-

That's done by adding ...

+
+

Rexification


+
+That's done by adding ...
+
 file '/usr/local/bin/dserver-update-key-cache.sh',
   content => template('./scripts/dserver-update-key-cache.sh.tpl'),
@@ -954,9 +1098,13 @@ file '/usr/local/bin/dserver-update-key-cache.sh',
 
 append_if_no_such_line '/etc/daily.local', '/usr/local/bin/dserver-update-key-cache.sh';
 
-

... to the Rex task!

-

Start it

-

Now, it's time to enable and start the DTail server:

+
+... to the Rex task!
+
+

Start it


+
+Now, it's time to enable and start the DTail server:
+
 $ sudo rcctl enable dserver
 $ sudo rcctl start dserver
@@ -978,7 +1126,9 @@ INFO|1022-090739|86050|stats.go:53|2|11|7|||MAPREDUCE:STATS|currentConnections=0
 .
 Ctr+C
 
-

As we don't want to wait until tomorrow, let's populate the key cache manually:

+
+As we don't want to wait until tomorrow, let's populate the key cache manually:
+
 $ doas /usr/local/bin/dserver-update-key-cache.sh
 Updating SSH key cache
@@ -990,9 +1140,13 @@ Caching /home/paul/.ssh/authorized_keys -> /var/cache/dserver/paul.authorized
 Caching /home/rex/.ssh/authorized_keys -> /var/cache/dserver/rex.authorized_keys
 All set...
 
-

Use it

-

The DTail server is now ready to serve connections. You can use any DTail commands, such as dtail, dgrep, dmap, dcat, dtailhealth, to do so. Checkout out all the usage examples on the official DTail page.

-

I have installed DTail server this way on my personal OpenBSD frontends blowfish, and fishfinger, and the following command connects as user rex to both machines and greps the file /etc/fstab for the string local:

+
+

Use it


+
+The DTail server is now ready to serve connections. You can use any DTail commands, such as dtail, dgrep, dmap, dcat, dtailhealth, to do so. Checkout out all the usage examples on the official DTail page.
+
+I have installed DTail server this way on my personal OpenBSD frontends blowfish, and fishfinger, and the following command connects as user rex to both machines and greps the file /etc/fstab for the string local:
+
 ❯ ./dgrep -user rex -servers blowfish.buetow.org,fishfinger.buetow.org --regex local /etc/fstab
 CLIENT|earth|WARN|Encountered unknown host|{blowfish.buetow.org:2222 0xc0000a00f0 0xc0000a61e0 [blowfish.buetow.org]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9ZnF/LAk14SgqCzk38yENVTNfqibcluMTuKx1u53cKSp2xwHWzy0Ni5smFPpJDIQQljQEJl14ZdXvhhjp1kKHxJ79ubqRtIXBlC0PhlnP8Kd+mVLLHYpH9VO4rnaSfHE1kBjWkI7U6lLc6ks4flgAgGTS5Bb7pLAjwdWg794GWcnRh6kSUEQd3SftANqQLgCunDcP2Vc4KR9R78zBmEzXH/OPzl/ANgNA6wWO2OoKKy2VrjwVAab6FW15h3Lr6rYIw3KztpG+UMmEj5ReexIjXi/jUptdnUFWspvAmzIl6kwzzF8ExVyT9D75JRuHvmxXKKjyJRxqb8UnSh2JD4JN [23.88.35.144]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9ZnF/LAk14SgqCzk38yENVTNfqibcluMTuKx1u53cKSp2xwHWzy0Ni5smFPpJDIQQljQEJl14ZdXvhhjp1kKHxJ79ubqRtIXBlC0PhlnP8Kd+mVLLHYpH9VO4rnaSfHE1kBjWkI7U6lLc6ks4flgAgGTS5Bb7pLAjwdWg794GWcnRh6kSUEQd3SftANqQLgCunDcP2Vc4KR9R78zBmEzXH/OPzl/ANgNA6wWO2OoKKy2VrjwVAab6FW15h3Lr6rYIw3KztpG+UMmEj5ReexIjXi/jUptdnUFWspvAmzIl6kwzzF8ExVyT9D75JRuHvmxXKKjyJRxqb8UnSh2JD4JN 0xc0000a2180}
@@ -1004,24 +1158,34 @@ CLIENT|earth|INFO|Added hosts to known hosts file|/home/paul/.ssh/known_hosts
 REMOTE|blowfish|100|7|fstab|31bfd9d9a6788844.h /usr/local ffs rw,wxallowed,nodev 1 2
 REMOTE|fishfinger|100|7|fstab|093f510ec5c0f512.h /usr/local ffs rw,wxallowed,nodev 1 2
 
-

Running it the second time, and given that you trusted the keys the first time, it won't prompt you for the host keys anymore:

+
+Running it the second time, and given that you trusted the keys the first time, it won't prompt you for the host keys anymore:
+
 ❯ ./dgrep -user rex -servers blowfish.buetow.org,fishfinger.buetow.org --regex local /etc/fstab
 REMOTE|blowfish|100|7|fstab|31bfd9d9a6788844.h /usr/local ffs rw,wxallowed,nodev 1 2
 REMOTE|fishfinger|100|7|fstab|093f510ec5c0f512.h /usr/local ffs rw,wxallowed,nodev 1 2
 
-

Conclusions

-

It's a bit of manual work, but it's ok on this small scale! I shall invest time in creating an official OpenBSD port, though. That would render most of the manual steps obsolete, as outlined in this post!

-

Check out the following for more information:

-https://dtail.dev
-https://github.com/mimecast/dtail
-https://www.rexify.org
-

Other related posts are:

-2022-10-30 Installing DTail on OpenBSD (You are currently reading this)
-2022-03-06 The release of DTail 4.0.0
-2021-04-22 DTail - The distributed log tail program
-

E-Mail your comments to hi@paul.cyou :-)

-Back to the main site
+
+

Conclusions


+
+It's a bit of manual work, but it's ok on this small scale! I shall invest time in creating an official OpenBSD port, though. That would render most of the manual steps obsolete, as outlined in this post!
+
+Check out the following for more information:
+
+https://dtail.dev
+https://github.com/mimecast/dtail
+https://www.rexify.org
+
+Other related posts are:
+
+2022-10-30 Installing DTail on OpenBSD (You are currently reading this)
+2022-03-06 The release of DTail 4.0.0
+2021-04-22 DTail - The distributed log tail program
+
+E-Mail your comments to hi@paul.cyou :-)
+
+Back to the main site
@@ -1112,8 +1276,10 @@ jgs (________\ \ I proudly announce that I've released Gemtexter version `1.1.0`. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.
-

Gemtexter 1.1.0 - Let's Gemtext again

-

Published at 2022-08-27T18:25:57+01:00

+

Gemtexter 1.1.0 - Let's Gemtext again


+
+Published at 2022-08-27T18:25:57+01:00
+
 -=[ typewriter ]=-  1/98
 
@@ -1125,12 +1291,19 @@ jgs                (________\  \
       |o=======.|
  jgs  `"""""""""`
 
-

I proudly announce that I've released Gemtexter version 1.1.0. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.

-https://codeberg.org/snonux/gemtexter
-

It has been around a year since I released the first version 1.0.0. Although, there aren't any groundbreaking changes, there have been a couple of smaller commits and adjustments. I was quite surprised that I received a bunch of feedback and requests about Gemtexter so it means that I am not the only person in the universe actually using it.

-

What's new?

-

Automatic check for GNU version requirements

-

Gemtexter relies on the GNU versions of the tools grep, sed and date and it also requires the Bash shell in version 5 at least. That's now done in the check_dependencies() function:

+
+I proudly announce that I've released Gemtexter version 1.1.0. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown written in GNU Bash.
+
+https://codeberg.org/snonux/gemtexter
+
+It has been around a year since I released the first version 1.0.0. Although, there aren't any groundbreaking changes, there have been a couple of smaller commits and adjustments. I was quite surprised that I received a bunch of feedback and requests about Gemtexter so it means that I am not the only person in the universe actually using it.
+
+

What's new?


+
+

Automatic check for GNU version requirements


+
+Gemtexter relies on the GNU versions of the tools grep, sed and date and it also requires the Bash shell in version 5 at least. That's now done in the check_dependencies() function:
+
 check_dependencies () {
     # At least, Bash 5 is required
@@ -1150,34 +1323,56 @@ check_dependencies () {
     done
 }
 
-

Especially macOS users didn't read the README carefully enough to install GNU Grep, GNU Sed and GNU Date before using Gemtexter.

-

Backticks now produce inline code blocks in the HTML output

-

The Gemtext format doesn't support inline code blocks, but Gemtexter now produces inline code blocks (means, small code fragments can be placed in the middle of a paragraph) in the HTML output when the code block is enclosed with Backticks. There were no adjustments required for the Markdown output format, because Markdown supports it already out of the box.

-

Cache for Atom feed generation

-

The Bash is not the most performant language. Gemtexter already takes a couple of seconds only to generate the Atom feed for around two hand full of articles on my slightly underpowered Surface Go 2 Linux tablet. Therefore, I introduced a cache, so that subsequent Atom feed generation runs finish much quicker. The cache uses a checksum of the Gemtext .gmi file to decide whether anything of the content has changed or not.

-

Input filter support

-

Once your capsule reaches a certain size, it can become annoying to re-generate everything if you only want to preview the HTML or Markdown output of one single content file. The following will add a filter to only generate the files matching a regular expression:

+
+Especially macOS users didn't read the README carefully enough to install GNU Grep, GNU Sed and GNU Date before using Gemtexter.
+
+

Backticks now produce inline code blocks in the HTML output


+
+The Gemtext format doesn't support inline code blocks, but Gemtexter now produces inline code blocks (means, small code fragments can be placed in the middle of a paragraph) in the HTML output when the code block is enclosed with Backticks. There were no adjustments required for the Markdown output format, because Markdown supports it already out of the box.
+
+

Cache for Atom feed generation


+
+The Bash is not the most performant language. Gemtexter already takes a couple of seconds only to generate the Atom feed for around two hand full of articles on my slightly underpowered Surface Go 2 Linux tablet. Therefore, I introduced a cache, so that subsequent Atom feed generation runs finish much quicker. The cache uses a checksum of the Gemtext .gmi file to decide whether anything of the content has changed or not.
+
+

Input filter support


+
+Once your capsule reaches a certain size, it can become annoying to re-generate everything if you only want to preview the HTML or Markdown output of one single content file. The following will add a filter to only generate the files matching a regular expression:
+
 ./gemtexter --generate '.*hello.*'
 
-

Revamped git support

-

The Git support has been completely rewritten. It's now more reliable and faster too. Have a look at the README for more information.

-

Addition of htmlextras and web font support

-

The htmlextras folder now contains all extra files required for the HTML output format such as cascading style sheet (CSS) files and web fonts.

-

Sub-section support

-

It's now possible to define sub-sections within a Gemtexter capsule. For the HTML output, each sub-section can use its own CSS and web font definitions. E.g.:

-The foo.zone main site
-The notes sub-section (with different fonts)
-

More

-

Additionally, there were a couple of bug fixes, refactorings and overall improvements in the documentation made.

-

Overall I think it's a pretty solid 1.1.0 release without anything groundbreaking (therefore no major versio