<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Other on TechBlog about OpenShift/Ansible/Satellite and much more</title><link>https://blog.stderr.at/categories/other/</link><description>TechBlog about OpenShift/Ansible/Satellite and much more</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Toni Schmidbauer &amp; Thomas Jungbauer</copyright><lastBuildDate>Mon, 12 Feb 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.stderr.at/categories/other/index.xml" rel="self" type="application/rss+xml"/><item><title>OpenShift Data Foundation - Noobaa Bucket Data Retention (Lifecycle)</title><link>https://blog.stderr.at/openshift-platform/day-2/storage/2024-02-12-bucket-data-retention/</link><pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/openshift-platform/day-2/storage/2024-02-12-bucket-data-retention/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Data retention or lifecycle configuration for S3 buckets is done by the S3 provider directly. The provider keeps track and files are automatically rotated after the requested time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This article is a simple step-by-step guide to configure such lifecycle for OpenShift Data Foundation (ODF), where buckets are provided by Noobaa. Knowledge about ODF is assumed, however similar steps can be reproduced for any S3-compliant storage operator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Installed OpensShift 4.x cluster (latest version during the creation of this article 4.14)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Installed Open Data Foundation Operator (4.14+)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configured Multi-Cloud Gateway (for example) to provide OpenShift with object storage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Installed aws command line tool. The deployment for different operating system is explained at: &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#cliv2-linux-install"&gt;Installing AWS Client&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A configured bucket and running openshift logging.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
In the further steps we use the bucket that is created for OpenShift Logging (using Lokistack) as a reference.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_working_with_aws_client"&gt;Working with aws client&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The first thing to do to work with the aws client is to retrieve the &lt;strong&gt;access key&lt;/strong&gt; and &lt;strong&gt;secret key&lt;/strong&gt; to be able to authenticate against the S3 API. During the deployment of OpenShift logging and the Lokistack a bucket has been created. The secret to authenticate against this bucket can be found in the openshift-logging namespace. In my example the name of this secret is &lt;strong&gt;logging-loki-s3&lt;/strong&gt; and it contains the following values:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/openshift-platform/day-2/storage/images/lokisecret.png?width=220" alt="Loki Secret"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The easiest way to authenticate against the S3 API is to create the following configuration file:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;&amp;gt; vim ~/.aws/credentials
[default]
aws_access_key_id = &amp;lt;value of access_key_id&amp;gt;
aws_secret_access_key = &amp;lt;value of access_key_secret&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Be sure that this file is not globally accessible.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_listing_objects"&gt;Listing Objects&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As a first test, we can try to list objects. The following command uses the S3 endpoint and the name of the bucket. Again, these values can be found in the Loki secret, mentioned above:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3 ls s3://logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56
PRE application/
PRE audit/
PRE index/
PRE infrastructure/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This command simply lists the current content (some folders in our case) of this bucket.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_copy_a_file_into_the_bucket"&gt;Copy a file into the bucket&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;For further testing we copy a test file into the bucket. This can be any file, I have created an empty one called &lt;strong&gt;testfile.txt&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3 cp testfile.txt s3://logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56
upload: ./testfile.txt to s3://logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56/testfile.txt&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Listing the content again, will now show the uploaded testfile.txt&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3 ls s3://logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56
PRE application/
PRE audit/
PRE index/
PRE infrastructure/
2024-02-10 04:23:14 32 testfile.txt&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_verifying_current_lifecycle_configuration"&gt;Verifying current Lifecycle configuration&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To verify the current lifecycle configuration, execute the following command. It will show any configuration that is currently available, or an empty value if there is no such setting yet.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3api get-bucket-lifecycle-configuration --bucket logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_put_a_lifecycle_configuration_in_place"&gt;Put a lifecycle configuration in place&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;To configure a data retention of 4 days for our bucket we first need to create the following JSON file:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-json hljs" data-lang="json"&gt;cat logging-bucket-lifecycle.json
{
&amp;#34;Rules&amp;#34;: [
{
&amp;#34;Expiration&amp;#34;: {
&amp;#34;Days&amp;#34;: 4 &lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
},
&amp;#34;ID&amp;#34;: &amp;#34;123&amp;#34;, &lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
&amp;#34;Filter&amp;#34;: {
&amp;#34;Prefix&amp;#34;: &amp;#34;&amp;#34; &lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
},
&amp;#34;Status&amp;#34;: &amp;#34;Enabled&amp;#34;
}
]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="colist arabic"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="1"&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Defines the retention period is days.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="2"&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A simple ID for this Rule. (string).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class="conum" data-value="3"&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A filter used to identify objects that a Lifecycle Rule applies to, here the filter is empty, so all objects are affected.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
There are much more setting possible as describe at &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-lifecycle-configuration.html"&gt;AWS S3API&lt;/a&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The following command will put the defined rule in place:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock caution"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-caution" title="Caution"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Already defined rules will be overwritten by the JSON file. If there have been previous configurations, put them into the JSON file as well.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3api put-bucket-lifecycle-configuration --bucket logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56 --lifecycle-configuration file://logging-bucket-lifecycle.json&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Checking again with the previous command, the rule should now be configured:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ aws --endpoint https://s3-openshift-storage.apps.ocp.local --no-verify-ssl s3api get-bucket-lifecycle-configuration --bucket logging-bucket-d39a258c-e971-4a0f-a1fa-302cb7e76a56&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_what_now"&gt;What now?&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now you have to wait. With the configuration used above, it takes 4 days until the file is rotated. I have tested this using a 1 day retention period and saw that the file will be rotated after about 30 hours. So the rotation will not happen exactly at 24 hours but a bit afterwards.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_consclusion"&gt;Consclusion&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This article describes very, and I mean very, briefly how to configure such data retention for OpenShift Data Foundation. Unfortunately, public documentation can be confusing, so I summarized here the commands I have used.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;There are some limitations with the Noobaa integration though. For example file transition (to a different storage class) is (currently) not supported.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Also, there are much more possible API calls that might be interesting. Please follow the AWS documentation:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/s3api/"&gt;S3 API&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/s3/"&gt;S3&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Basic usage of git</title><link>https://blog.stderr.at/integrations/general/2020-05-08-git-and-github-basics/</link><pubDate>Fri, 08 May 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/integrations/general/2020-05-08-git-and-github-basics/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;This is a very short and hopefully simple introduction on how to use
&lt;a href="https://git-scm.com/"&gt;Git&lt;/a&gt; when you would like to contribute to
projects hosted on &lt;a href="http://github.com"&gt;github.com&lt;/a&gt;. The same workflow should also work for
projects on &lt;a href="http://gitlab.com"&gt;gitlab.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_introduction"&gt;Introduction&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;There is this fancy mega application hosted on github called
&lt;a href="https://github.com/rhatservices/megaapp"&gt;megaapp&lt;/a&gt; that you would like
to contribute to. It’s perfect but there’s just this little feature
missing to make it even more perfect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is how we would tackle this.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
rocket science ahead
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_glossary"&gt;Glossary&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;table class="tableblock frame-all grid-all stretch"&gt;
&lt;colgroup&gt;
&lt;col style="width: 27.2727%;"/&gt;
&lt;col style="width: 72.7273%;"/&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Term&lt;/th&gt;
&lt;th class="tableblock halign-left valign-top"&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;fork&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A (personal) copy of a repository you created on github or gitlab.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;upstream&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;When creating forks of repositories on github or gitlab, the original repository hosting the project&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;index&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;The staging area git uses before you can commit to a repository&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;remote repository&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A repository hosted on a server shared by developers&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;local repository&lt;/p&gt;&lt;/td&gt;
&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A local copy of a repository stored on you machine.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_1_fork_the_repository_on_github_com"&gt;Step 1: Fork the repository on github.com&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Login to you Github account and navigate to the project you would like
to fork, &lt;a href="https://github.com/rhatservices/megaapp"&gt;megaapp&lt;/a&gt; in our
example.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Click on the the fork button, as depicted in the image below:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/integrations/general/images/fork.png" alt="fork"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If you are a member of several projects on github.com, github is going
to ask you into which project you would like to clone this repository.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After selecting the project or your personal account, github is going
to clone the repository into the project you selected. For this
example I’m going to use my personal github account &amp;#34;tosmi&amp;#34;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_2_clone_the_repository_to_you_workstation"&gt;Step 2: Clone the repository to you workstation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Next we are going to clone our fork from &lt;a href="#_step_1_fork_the_repository_on_github_com"&gt;Step 1: Fork the repository on github.com&lt;/a&gt; to our workstation and start working on the new
feature.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After forking the upstream project you are redirect to your personal
copy of the project. Click on the &amp;#34;Clone or download&amp;#34; button and
select the link. You can choose between SSH and HTTPS protocols for
downloading the project. We are going to use SSH.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/integrations/general/images/clone.png" alt="clone"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Copy the link into a terminal and execute the &lt;em&gt;git clone&lt;/em&gt; command:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git clone git@github.com:tosmi/megaapp.git&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_3_create_a_feature_branch_for_your_new_fancy_feature"&gt;Step 3: Create a feature branch for your new fancy feature&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Change into the directory of the project you downloaded in &lt;a href="#_step_2_clone_the_repository_to_you_workstation"&gt;Step 2: Clone the repository to you workstation&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;cd megaapp&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now we create a feature branch with a short name that describes our new feature:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;git checkout -b tosmi/addoption&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Because we would like to add a new option to &lt;em&gt;megaapp&lt;/em&gt; we call this feature branch &lt;em&gt;addoption&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We are also prefixing the feature branch with our github username so that
it is clear for the upstream project maintainer(s) who is contributing this.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;How you name you branches is opinionated, so we would search for
upstream project guidelines and if there are none maybe look at some
existing pull request how other people are naming there branches. If we
find no clue upstream we sticking with &lt;em&gt;&amp;lt;github username&amp;gt;/&amp;lt;branch
name&amp;gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We can now start adding our mega feature to the project.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_4_add_you_changes_to_the_git_index"&gt;Step 4: Add you changes to the Git index&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Before we can commit our changes, we have to place the changes made in
the so called &lt;em&gt;index&lt;/em&gt; or staging area:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git add &amp;lt;path to file you have changed&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If we would like to place all of our changes onto the index we could execute&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git add -A&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_5_commit_your_changes"&gt;Step 5: Commit your changes&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After adding our changes to the Git index we can commit with&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git commit&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This will open our favorite editor and we can type a commit
message. The first line should be a short description of our change,
probably not longer than 70 to 80 characters. After two newlines we
can enter a detailed explanation of your changes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is an example commit message&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;Added a `version` option to output the current version of megaapp
This change introduces a `version` option to megaapp. The purpose is
to output the current version of megaapp for users. This might be
helpful when users open a bug report so we can see what version is
affected.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After saving the message and we have successfully created a commit.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Remember this is now only stored in the local copy of the
repository! We still have to push our changes to github.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;There is also the option to add the commit comment directly on the command line&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git commit -m &amp;#39;Added a `version` option to output the current version of megaapp
This change introduces a `version` option to megaapp. The purpose is
to output the current version of megaapp for users. This might be
helpful when users open a bug report so we can see what version is
affected.&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_6_pushing_our_local_changes_to_our_forked_repo_on_github_com"&gt;Step 6: Pushing our local changes to our forked repo on github.com&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We execute&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git push&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;to push our local changes to the forked repository hosted on github.com.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_step_7_creating_a_pull_request_on_github_com"&gt;Step 7: Creating a pull request on github.com&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We navigate to our personal project page of the forked repository on
github. For the fork we are using in this example this is
&lt;a href="http://github.com/tosmi/megaapp" class="bare"&gt;http://github.com/tosmi/megaapp&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Github is going to show us a button &amp;#34;Compare &amp;amp; pull request&amp;#34;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="imageblock"&gt;
&lt;div class="content"&gt;
&lt;img src="https://blog.stderr.at/integrations/general/images/pull_request.png" alt="pull request"/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;After clicking on that button we are able to review the changes we
would like to include in this pull request.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If we are happy with our changes we click on &amp;#34;Create pull
request&amp;#34;. The upstream owner of the repository will get notified and
we can see our open pull request on the upstream project page under
&amp;#34;Pull requests&amp;#34;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If there are CI test configured for that project they will start to
run and we can see if our pull request is going to pass all test
configured.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_rebasing_to_current_upstream_if_required"&gt;Rebasing to current upstream if required&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Sometimes a upstream project maintainer asks you to rebase your work
on the current upstream master branch. The following steps explain the
basic workflow.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;First we are going to create a new remote location of our repository
called &lt;em&gt;upstream&lt;/em&gt;. &lt;em&gt;Upstream&lt;/em&gt; points to the upstream project
repository. We will not push to this location, in most cases this is
not possible because you do not have write access to a remote upstream
repository. It is just used for pulling upstream changes in our forked
repository.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Execute the following commands to add the upstream repository as a new
remote location and display all remote locations currently defined.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git remote add upstream https://github.com/rhatservices/megaapp.git
$ git remote -v origin
git@github.com:tosmi/megaapp.git (fetch) origin
git@github.com:tosmi/megaapp.git (push) upstream
https://github.com/rhatservices/megaapp.git (fetch) upstream
https://github.com/rhatservices/megaapp.git (push)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As we hopefully implemented our new feature in feature branch, we can
pull changes from the upstream master branch into our local copy of
the master branch. Remember we are using a feature branch and master
should be kept clean from local changes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git checkout master
Switched to branch &amp;#39;master&amp;#39;
Your branch is up to date with &amp;#39;origin/master&amp;#39;.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;So now we have this older copy of the upstream master branch checked
out and we would like to update it to the latest and greatest from the
upstream master branch.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git pull upstream master
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 2), reused 6 (delta 2), pack-reused 0
Unpacking objects: 100% (6/6), 630 bytes | 157.00 KiB/s, done.
From https://github.com/rhatservices/megaapp
* branch master -&amp;gt; FETCH_HEAD
* [new branch] master -&amp;gt; upstream/master
Updating 4d8584e..ddfd077
Fast-forward
cmd/megaapp/main.go | 2 ++
cmd/megaapp/rule.go | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 cmd/megaapp/rule.go&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;With the pull command above you pulled all changes from the upstream
master branch into you local copy of master. Just to be sure let’s
display all available branches, local and remote ones.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Branches with a name &lt;em&gt;remote/&amp;lt;remote name&amp;gt;/&amp;lt;branch name&amp;gt;&lt;/em&gt; are remote
branches that git knows about. &lt;em&gt;Origin&lt;/em&gt; points to our forked
repository and is also the default location for push operations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git branch -a
master
* tosmi/megafeature
remotes/origin/HEAD -&amp;gt; origin/master
remotes/origin/master
remotes/origin/tosmi/megafeature
remotes/upstream/master&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;So finally to &lt;strong&gt;rebase&lt;/strong&gt; our feature branch to the upstream master
branch we first need to checkout our feature branch via&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git checkout tosmi/megafeature&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Now we are able to rebase our changes to upstream master. Git
basically pulls in all changes from the master branch and re-applies
the changes we did in our feature branch.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;git rebase upstream/master
Successfully rebased and updated refs/heads/tosmi/megafeature.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;There might be merge conflicts when git tries to apply you changes
from your feature branch. You have to fix those changes, &lt;em&gt;git add&lt;/em&gt; the
fixed files and execute &lt;em&gt;git rebase continue&lt;/em&gt;. Luckily this is not the
case for your megafeature.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;As we have successfully rebased our feature branch to upstream master
we can now try to push changes made to our forked github repository.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git push
To github.com:tosmi/megaapp.git
! [rejected] tosmi/megafeature -&amp;gt; tosmi/megafeature (non-fast-forward)
error: failed to push some refs to &amp;#39;git@github.com:tosmi/megaapp.git&amp;#39;
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: &amp;#39;git pull ...&amp;#39;) before pushing again.
hint: See the &amp;#39;Note about fast-forwards&amp;#39; in &amp;#39;git push --help&amp;#39; for details.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Oh, this fails of course! The reason is that our local feature branch
and the remote feature branch have a different commit history. The
remote feature branch is missing the commits from master that we
applied when rebasing on the current master branch.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;So let’s try again, this time using the &lt;em&gt;--force-with-lease&lt;/em&gt;
option. You could also use &lt;em&gt;-f&lt;/em&gt; or &lt;em&gt;--force&lt;/em&gt; but &lt;em&gt;--force-with-lease&lt;/em&gt;
will stop you if someone else (our you) has modified the remote feature
branch meanwhile. If you push with &lt;em&gt;-f&lt;/em&gt; or &lt;em&gt;--force&lt;/em&gt; anyways you might loose changes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git push --force-with-lease
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 295 bytes | 295.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:tosmi/megaapp.git
+ acf66a3...39357b2 tosmi/megafeature -&amp;gt; tosmi/megafeature (forced update)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;But as no one modified the remote feature branch while we did our
rebase the force push goes through.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Our merge request (if we opened one already) is now updated to the
latest upstream master branch and merging our feature should be a
breeze. You might notify the upstream project maintainer that you
feature branch is up to date and ready for merging&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_using_gits_interactive_rebase_to_change_you_commit_history"&gt;Using git’s interactive rebase to change you commit history&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;When working with upstream projects it might be that a project
maintainer requests that you rework your git history before he is
willing to merge your changes. For example this could be that case if
you have plenty of commits with very small changes (e.g. fixed typos).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The general rule is that one commit should implement one change. This
is not a hard rule, but usually works.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Let’s look at an example. For the implementation of our new feature
that we would like to bring upstream we have the following commit history&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git log --oneline
0a5221d (HEAD -&amp;gt; tosmi/megafeature) fixed typo
0e60d12 update README
bf2ef3c update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We have updated README.md in the repository but there a three commits
for this little change. Before bringing this upstream in our pull
request, we would like to convert those three commits into a single
one and also make the commit message a little more meaningful.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We execute the following command to start reworking our commit history&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git rebase -i&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Git will drop us into our beloved editor (vi in this case), under
Linux you could change the editor git uses by modifying the $EDITOR
environment variable. We are going to see the following output:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;pick bf2ef3c update
pick 0e60d12 update README
pick 0a5221d fixed typo
# Rebase 39357b2..0a5221d onto 39357b2 (3 commands)
#
# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message
# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
# f, fixup &amp;lt;commit&amp;gt; = like &amp;#34;squash&amp;#34;, but discard this commit&amp;#39;s log message
# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with &amp;#39;git rebase --continue&amp;#39;)
# d, drop &amp;lt;commit&amp;gt; = remove commit
# l, label &amp;lt;label&amp;gt; = label current HEAD with a name
# t, reset &amp;lt;label&amp;gt; = reset HEAD to a label
# m, merge [-C &amp;lt;commit&amp;gt; | -c &amp;lt;commit&amp;gt;] &amp;lt;label&amp;gt; [# &amp;lt;oneline&amp;gt;]
# . create a merge commit using the original merge commit&amp;#39;s
# . message (or the oneline, if no original merge commit was
# . specified). Use -c &amp;lt;commit&amp;gt; to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Git automatically selected commit id bf2ef3c as the basis for our
rebase. We could also have specified the commit id where we would like
to start our rebase operation e.g.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;git rebase -i bf2ef3c&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In our editor of choice we can now tell git what it should do with the selected commits.
Please go ahead and read the helpfull explanation text in comments (prefixed with &amp;#39;#&amp;#39;)
to get a better understanding of the operations supported.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;In our case we would like to &lt;em&gt;squash&lt;/em&gt; the last commits. So we change the lines with &lt;em&gt;pick&lt;/em&gt; to
&lt;em&gt;squash&lt;/em&gt; until it looks like the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;pick bf2ef3c update
squash 0e60d12 update README
squash 0a5221d fixed typo&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We would like to squash commits 0a5221d and 0e60d12 onto commit
bf2ef3c. Keep in mind that git actually reverses the order of
commits. So 0a5221d is the last commit we added.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If we save the file and quit our editor (I’m using vi here), git drops us into
another buffer where we can finally modify the commits&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt; This is a combination of 3 commits.
# This is the 1st commit message:
update
# This is the commit message #2:
update README
# This is the commit message #3:
fixed typo
# Please enter the commit message for your changes. Lines starting
# with &amp;#39;#&amp;#39; will be ignored, and an empty message aborts the commit.
#
# Date: Mon May 18 15:46:37 2020 +0200
#
# interactive rebase in progress; onto 39357b2
# Last commands done (3 commands done):
# squash 0e60d12 update README
# squash 0a5221d fixed typo
# No commands remaining.
# You are currently rebasing branch &amp;#39;tosmi/megafeature&amp;#39; on &amp;#39;39357b2&amp;#39;.
#
# Changes to be committed:
# modified: README.md
#&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We can see all three commit message and we are going to modify those messages until we are happy&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;# This is a combination of 3 commits.
# This is the 1st commit message:
updated README.md to megafeature
as we added megafeature, it makes sense to include a short note about it also in README.md
# Please enter the commit message for your changes. Lines starting
# with &amp;#39;#&amp;#39; will be ignored, and an empty message aborts the commit.
#
# Date: Mon May 18 15:46:37 2020 +0200
#
# interactive rebase in progress; onto 39357b2
# Last commands done (3 commands done):
# squash 0e60d12 update README
# squash 0a5221d fixed typo
# No commands remaining.
# You are currently rebasing branch &amp;#39;tosmi/megafeature&amp;#39; on &amp;#39;39357b2&amp;#39;.
#
# Changes to be committed:
# modified: README.md
#&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;When we are happy with new commit message we just save and quit our
editor. Git will now rewirte the history and when we take look at the
commit history again we will see our changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;$ git log --oneline
91d1ae2 (HEAD -&amp;gt; tosmi/megafeature) updated README.md to megafeature
39357b2 (origin/tosmi/megafeature) added a mega feature
ddfd077 (upstream/master, master) added rule command
4d8584e (origin/master, origin/HEAD) Update README.md
eb6ccbc Create README.md
60fcabc start using cobra for argument parsing
5140ed0 import .gitignore
d2b55d1 import a simple Makefile
2ecb412 initial import&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;We only have commit 91d1ae2 now , which includes all three changes from
the commits before.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonitionblock warning"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-warning" title="Warning"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
Rewriting the history of a repository is a dangerous
operation. Especially when you are working in a team. It is not
advised to change the history of commits that got already pushed to a
remote location. Otherwise your teammates will get confused next time
they try to push or pull from the shared repository.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;So it’s OK to change the commit history of a feature branch that only
you are using, but be careful when working on branches more than one
developer is using.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Red Hat Satellite Cheat Sheet</title><link>https://blog.stderr.at/integrations/general/2020-04-15-satellite-cheatsheet/</link><pubDate>Wed, 15 Apr 2020 00:00:00 +0000</pubDate><guid>https://blog.stderr.at/integrations/general/2020-04-15-satellite-cheatsheet/</guid><description>&lt;div class="paragraph"&gt;
&lt;p&gt;Cheat sheet for various Red Hat Satellite tasks from a newbie to a newbie.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_requirements"&gt;Requirements&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="ulist"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;up to Satellite 6.7 RHEL 7.X&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4 CPU Cores&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;20 GB of RAM&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;300 GB disk space&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;for more info see the &lt;a href="https://access.redhat.com/documentation/en-us/red_hat_satellite/6.6/html/installing_satellite_server_from_a_connected_network/preparing_your_environment_for_installation#storage_requirements"&gt;prerequistes guide&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_installation"&gt;Installation&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Satellite up to version 6.7 uses puppet for installation. You can use&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;puppet filebucket&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;to restore files modified by puppet.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Satellite requires the &lt;em&gt;Red Hat Satellite Infrastructure Subscription&lt;/em&gt;, check if it’s available with&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;subscription-manager list --all --available --matches &amp;#39;Red Hat Satellite Infrastructure Subscription&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;If not attach it with&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;subscription-manager attach --pool=pool_id&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Next disable all repos and enable only supported repostories via&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;subscription-manager repos --disable &amp;#34;*&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;and enable required repositories&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;subscription-manager repos --enable=rhel-7-server-rpms \
--enable=rhel-7-server-satellite-6.6-rpms \
--enable=rhel-7-server-satellite-maintenance-6-rpms \
--enable=rhel-server-rhscl-7-rpms \
--enable=rhel-7-server-ansible-2.8-rpms&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;then clean cached all repo data via&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt; yum clean all&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;and install satellite packages via&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;yum install satellite&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Install satellite with&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-installer --scenario satellite \
--foreman-initial-organization &amp;#34;initial_organization_name&amp;#34; \
--foreman-initial-location &amp;#34;initial_location_name&amp;#34; \
--foreman-initial-admin-username admin_user_name \
--foreman-initial-admin-password admin_password&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_backup_restore_cloning"&gt;Backup / Restore / Cloning&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Use &lt;code&gt;satellite-maintain&lt;/code&gt; for doing offline and online backups&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain backup offline /backup/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;when using the &lt;em&gt;online&lt;/em&gt; option make sure that no new content view or
content view versions should be created while the backup is
running. basically satellite should be idle.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_cloning_satellite"&gt;Cloning Satellite&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;The online/offline options also backup &lt;em&gt;/var/lib/pulp&lt;/em&gt;, which contains
all downloaded packages. This could be &lt;strong&gt;huge&lt;/strong&gt;. There’s an option to skip this so&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain backup offline --skip-pulp-tar /backup/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonitionblock note"&gt;
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class="icon"&gt;
&lt;i class="fa icon-note" title="Note"&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class="content"&gt;
For a restore you always need the content of &lt;em&gt;/var/lib/pulp&lt;/em&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This is mainly usefull for cloning satellite. You backup everything
except &lt;em&gt;/var/lib/pulp&lt;/em&gt;, copy the backup to a second system and rsync
&lt;em&gt;/var/lib/pulp&lt;/em&gt; to the new system. Then restore the backup and
satellite should work as normal on the clone.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_snaphot_backups"&gt;Snaphot backups&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Satellite also supports backups via LVM snapshots. For more information see &lt;a href="https://access.redhat.com/documentation/en-us/red_hat_satellite/6.6/html/administering_red_hat_satellite/chap-red_hat_satellite-administering_red_hat_satellite-backup_and_disaster_recovery#snapshot-backup_assembly"&gt;Snapshot backup&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_upgrades"&gt;Upgrades&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="olist arabic"&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;
&lt;p&gt;Read the Satellite release notes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do a offline backup see &lt;a href="#Backup / Restore"&gt;[Backup / Restore]&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You could clone satellite to a other system&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there are local changes to dhcpd or dns configurations use&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-installer --foreman-proxy-dns-managed=false --foreman-proxy-dhcp-managed=false&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;to stop satellite-install from overwriting those files.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;install the latest version of satellite-maintain via&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;yum install rubygem-foreman_maintain&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;check for available satellite versions with&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain upgrade list-versions&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;test the possible upgrade with&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain upgrade check --target-version 6.7&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;and finally run the upgrade and PRAY!&lt;/p&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain upgrade run --target-version 6.7&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect1"&gt;
&lt;h2 id="_various_tips_and_tricks"&gt;Various tips and tricks&lt;/h2&gt;
&lt;div class="sectionbody"&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_installing_packages_via_yum"&gt;Installing packages via yum&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;Satellite installs a yum plugin called &lt;code&gt;foreman-protector&lt;/code&gt;. If you try
to install a package via yum you get the following message&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-none hljs"&gt;WARNING: Excluding 12190 packages due to foreman-protector.
Use foreman-maintain packages install/update &amp;lt;package&amp;gt;
to safely install packages without restrictions.
Use foreman-maintain upgrade run for full upgrade.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;so use&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;satellite-maintain install &amp;lt;package name&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="sect2"&gt;
&lt;h3 id="_os_package_upgrade"&gt;OS package upgrade&lt;/h3&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This should be done via satellite-maintain because all packages are locked by default (see &lt;a href="#_installing_packages_via_yum"&gt;Installing packages via yum&lt;/a&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;This basically comes down to running&lt;/p&gt;
&lt;/div&gt;
&lt;div class="listingblock"&gt;
&lt;div class="content"&gt;
&lt;pre class="highlightjs highlight"&gt;&lt;code class="language-bash hljs" data-lang="bash"&gt;oreman-maintain upgrade run --target-version 6.6.z&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="paragraph"&gt;
&lt;p&gt;for upgrading OS packages if you have satellite 6.6 installed.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item></channel></rss>