How Do You Troubleshoot a C Program That Prints a Warning Message like “expects argument of type ‘char*’, but argument 2 has type ‘int’ [-Wformat=]”?

Problem scenario
You compile a C program (with gcc foobar.cc) but you get an error message like this:

"foofbar1.cc:71...: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'int' [-Wformat=]
   printf ("y is a %s\n", y);
                           ^  "

What do you do to not get this error?

Solution
While the code compiles, the executable may not run.  A compilation error can be benign.  For this case, integers need a special syntax to be printed out.  

Here is a line that will produce this error (with a variable named "y"):

   printf ("y is a %s\n", y);

Here is a similar but corrected line that will be error free:

  printf ("y is a %d\n",y);

The "%s" is appropriate for printing string variables.  For integer variables, use "%d" syntax.


For learning about the C programming language, you may want to purchase a book below:

0131103628C Programming Language, 2nd Edition by Pearson
1718501048Effective C: An Introduction to Professional C Programming by No Starch Press
1789349915Learn C Programming: A beginner's guide to learning C programming the easy and disciplined way by Packt Publishing
1789343623Extreme C: Taking you to the limit in Concurrency, OOP, and the most advanced capabilities of C by Packt Publishing
0393979504C Programming: A Modern Approach, 2nd Edition by W. W. Norton & Compan

How Do You Write an Ansible Playbook to Transfer a Compressed File and Unzip It without Using Linux Utilities?

Problem scenario
You have installed Ansible and configured it to work with other servers (managed nodes).  You want to write an Ansible playbook that will work with Linux managed nodes with three requirements:

1.  Transfer a compressed file from a web sever without wget.
2.  Uncompress a .zip file without unzip.
3.  Work without passwordless SSH authentication to the managed nodes.

How do you accomplish this with using Ansible-supported features?

Solution
1.  Have the playbook use the get_url command to transfer the file.  You do not need to use wget on the managed nodes.  Here is an example of how the syntax should appear:

  get_url:
    url: https://www.continualintegration.com/good.zip
    dest: /tmp/good.zip

It can support cksum which is recommended for security reasons.  If you want to learn more about this feature, see this posting.

2.  Have the playbook use the "unarchive" command.  You do not need to install unzip.  Here is an example:

- name: Unzip a file on a remote server
  unarchive:
    src: /tmp/good.zip
    dest: /usr/local/bin
    remote_src: yes    # This tells Ansible the source file is on the remote server.  If the source file is elsewhere, remove this stanza.

To learn more about the unarchive feature, see this external link.

3.  When running the "ansible-playbook" command, use the "--ask-pass" flag.  For example if you want to run foo.yaml as the playbook, run a command like this:

ansible-playbook foo.yaml --ask-pass

This will prompt you for a password to SSH into the managed nodes. 

What is GitOps?

Question
What is GitOps?

Answer
GitOps is a declarative method of managing infrastructure that is driven by committing code into a version control system. GitOps is an indirect, and usually imperative, approach to systems administration that gives a detailed history of past operations.  GitOps is the practice of adding code to a Git repository to trigger an operational event (such as rebooting a server, creating a user account, or provisioning a new virtual server). Upon a successive file being uploaded to a specific location in Git, which may or may not require peer review to become complete and take effect, an action or set of actions will be taken. Each older version of the file will be saved in Git for future retrospection(s).

The term is a portmanteau of the software named Git and "Ops" which is short for [system] operations.  Git itself was developed by Linus Torvalds and is the most popular distributed code versioning solution as of 2018.  Some businesses may use GitOps with a different code versioning solution from Git itself.  The term appears to have originated from Weaveworks.  

GitOps was born of widespread automation and a need to audit systems administration (e.g., for security investigations or postmortems).  As the popularity of the CI/CD pipeline has grown, triggering actions by uploading code has become a standard practice.  GitOps is an extension of infrastructure-as-a-code -- using text to specify virtual servers' CPU, RAM, and hard disk capacities.  Moreover GitOps is an outgrowth of event execution prompted by new files being uploaded into a code repository, often after one or two approvals of successful peer review.  For root cause analysis, having detailed records in a centralized location can be of great value.  Code versioning systems will continually track changes to configuration files as they are merged with the exact corresponding time and date. Pull-request detection can be set up to trigger actions and be the impetus of GitOps.

At the 18 minute and 46 second mark of this video presentation by Gene Kim, the DevOps guru states that the "top predictor of IT performance" was whether or not the Operations team was using a code version control system. In his book The DevOps Handbook says that in 2014 Puppet Labs found the same thing (on page 117). One factor in the "12 Factor App" methodology is having a single source code repository (https://12factor.net/). This methodology's adoption has increased lately, and this is right in line with ushering in adoption of GitOps with one exception: the twelve-factor app recommends environment variables never be stored in code repositories. It will be interesting to see how the industry reconciles GitOps and the twelve-factor app for environment variables.

How Do You Get the SonarQube Service to Remain on when It Stops Shortly after Being Started?

Problem scenario
You start SonarQube and the service seems to come up.  You see TCP port connection activity.  It does not stay up long enough to log in.  

You have SonarQube installed on a Linux server.  SonarQube starts, but it does not remain running because it dies out.  It stops running after 30 seconds of being started.  

In /opt/sonarqube/es.log you see a message like this:  "2018.05.23 17:01:53 WARN  es[][o.e.b.ElasticsearchUncaughtExceptionHandler] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root"

In /opt/sonarqube/sonar.log you see a message like this:
"WrapperSimpleApp: Encountered an error running main: java.nio.file.AccessDeniedException: /opt/sonarqube/temp/conf/es/log4j2.properties
java.nio.file.AccessDeniedException: /opt/sonarqube/temp/conf/es/log4j2.properties
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
"

You did not start sonar as a root user.  How do you get the SonarQube service to remain on when it keeps stopping for no reason?

Solution
Possible solution #1
In the sonar.properties file are the credentials to the database correct?  An invalid username and password could produce the behavior you are experiencing.

Possible solution #2
Go to the logs directory in the sonarqube directory.  There may be clues there.

Possible solution #3
1.  Run this command: sudo rm -rf /opt/sonarqube/temp

2.  Run this command, but see the notes below to customize it for your server:

sudo chown -R sonar:sonargroup /opt/sonarqube   

# replace the first "sonar" with the user that will start the service;
# replace the sonargroup in the above with the group of the user that will start the service.  If you do not know what this is but you do know the user, log into the Linux server as the user and run the "groups" command.  The result will be some of the groups the user is in.

3.  Reboot the server.

4.  Start the Sonar service as normal.  A normal way would be to log in as the "sonar" user and run the sonar.sh script like this:

./sonar.sh start

Another way would be to run these commands:

sudo systemctl start sonar
sudo systemctl enable sonar
sudo systemctl status sonar

How Can Conway’s Law Avoid Conflicting with the DevOps Movement?

Organizational structures are created by business leaders.  A constellation of specialists in theory can be very productive for modular codebases where the work is distributed intelligently.

Conway's Law is "[a]ny organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure." Conway's Law indirectly asserts that the Unix philosophy of having things be modular is achievable best by loosely-coupled groups rather than tightly-coupled groups (such as an aggregation of mini-groups into one business unit) according to WhatIs.com.

The book Building Microservices by Sam Newman says 'Eric S. Raymond summarized this phenomenon in The New Hacker’s Dictionary (MIT Press) by stating “If you have four groups working on a compiler, you’ll get a 4-pass compiler."' (1)

Software developers know that in the context of compilers, the fewer passes a compiler needs, the better it is.  Each pass takes time, and code must compile quickly as there are many compilers to choose from, and in business, time is money.  Based on this literature about Conway's Law, theoretically, one group would not create a four-pass compiler but rather a sophisticated one-pass interpreter or an efficient two-pass compiler.

For the sake of argument, two or more groups could not be more tightly-coupled than if they were all to merge into one group.  To heed the warning from Conway would be to have fewer small groups in favor of one large group. Conway's Law suggests that such a group (a single large team) could create unmodular (tightly-coupled) code. Readily breakable or easily divided code (with logical separations of functionality) adheres to Demeter's Law

"It only takes two branches performing a refactoring in a tightly coupled codebase to bring the entire team to a halt when one of them merges" (Continuous Delivery, page 410).

In some ways it seems that the DevOps trend toward generalization and merging disciplines could lead to monolithic codebases that are not modular. With any paradigm shift, such as that of the recent DevOps movement, potential disadvantages need to be considered and mitigated. By reducing silos and promoting individual generalists in one team, modularity should not be forsaken. You will need to maintain the codebase.

Communication between I.T. professionals and groups presents a serious set of potential problems. There is a rule called Brook's Law that is defined as "[a]dding more programmers to a late project makes it later" (The Cathedral and the Bazaar, page 34). According to Eric S. Raymond, "Brook's Law is founded on experience that bugs tend strongly to cluster at the interfaces between code written by different people, and that communications/coordination overhead on a project tends to rise with the number of interfaces between human beings" (The Cathedral and the Bazaar, page 34).

The latest trend is to shun DevOps departments in favor of bringing systems administrators into the same group as software engineers.  Departments can be seen as barriers that inhibit collaboration for addressing weaknesses and leveraging strengths.  Gene Kim illustrates the benefit of having one department rather than two or three. (2) 

The popularity of full-stack engineers (as opposed to traditional, pure programmers) is at least partially attributable to the adoption of DevOps business culture.  Full-stack engineers, as jacks-of-all-trades, can leverage automation and be mindful of security at crucial stages of their development given their versatility in solving problems from the beginning with developing a platform until the end (after the CI/CD release to production).  Generalists work in a variety of environments contributing to platform, security, software, and database development. With knowledge of each specialty such as programming, networking, databases, and security itself, the shift-left paradigm (where security is designed at an early stage in the life cycle of development as opposed to an afterthought near the release of the product) can be implemented.

As one considers the role of individuals in groups, she can look at Nietzsche's Beyond Good and Evil where the author delves into a human as being a part of nature. (3)  In the same section of this book that the reference to being a part of nature is in, Nietzsche states that ideas can project themselves onto something else that was not originally intended. (3)  This Nietzschean concept of unintentional idea projection is consistent with Conway's view that the organizational structure will mirror the technical dependencies of products it creates.  The underlying product may unintentionally reflect the organization's communication systems (a man-made idea, and a whole composed of subcomponents).  (The Nietzschean concept of humans being part of nature is also analogous to Conway's view that branches of a business combine to be a greater whole.)

Enterprises use DevOps for compliance, and in some cases regulations affect how labor is divided. "For software developers, the big problem comes in Separation of Duties. Basically, SarbOx says that a software developer should not have ANY kind of write access to production systems that can affect the financial reporting of the corporation." (This quote was taken from https://www.toolbox.com/tech/programming/blogs/what-does-the-sarbanes-oxley-act-mean-to-developers-061904/.)

Keep in mind if a company will be Sarbanes-Oxley compliant, its developers should not have access to production systems that deal with corporate finance reports. This means you may need dedicated release, build, DevOps or Site Reliability engineers to deploy the code to production for corporate finance reporting applications.

Some companies error on the side of caution and ensure that development in production does not happen (according to this external posting). Many small companies do not need to be Sarbanes Oxley compliant.

Adam Smith in the Wealth of Nations discusses dividing labor into distinct stages (or branches as he calls them), to maximize productivity (see the third paragraph of book one, chapter one for an example about pin makers).  If certain professionals focus on distinct operations (a collaboration through specializing in modular aspects of substages of the production process), Smith says that the total output of the workers will be much greater than the sum of individual efforts to manufacture useful pins with no collaboration from the beginning of the process to the end.  According to Smith, output can be multiplied with each laborer specializing in one segment of the product manufacturing process.  According to Oxford Journals however, the business concept of modular organizational structure comes from Nobel Prize winner Herbert Simon who happened to be a computer pioneer.  Simon's conclusion is consistent with Smith's recommendation for the division of labor with modular stages for each worker.  In Simon's book The Sciences of the Artificial, he describes an anachronistic parable based on ancient Greek characters dividing labor in the enterprise of creating timepieces (http://en.citizendium.org/).  The ancient Greeks, who influenced the philosopher Friedrich Nietzsche, valued moderation. 

Overwhelmingly we know the benefits of both modularity and DevOps culture.  We can reconcile the need for loosely-coupled groups with the ostensibly opposite DevOps commitment toward eliminating subgroups altogether.  If Conway's Law is correct, companies must be moderate in their application of DevOps culture for the sake of promoting modularity as extremist implementation of DevOps has not been championed by anyone.  Relatively uncoupled groups of specialized experts and/or unspecialized (generalist) professionals can be placed into a company's DevOps operations to leverage automation with sufficient knowledge of infrastructure as a part of the development life-cycle for secure and efficient operations.  The prescription is Greek: moderate adoption of DevOps culture is key.

Footnotes
(1)  The hyperlink and underline inside the single quotes were not part of the original quote.
(2)  At the 29 minute mark of this video, Gene Kim shows how an organization changed the number of teams from two to three, and then from three to one.  The organization did the best when it had the fewest number of departments (one team).
(3)  The passage referenced here is as follows:  'Stoicism is self-tyranny—Nature will also allow herself to be tyrannized over: is not the Stoic a part of Nature?... But this is an old and everlasting story: what happened in old times with the Stoics still happens today, as soon as ever a philosophy begins to believe in itself. It always creates the world in its own image; it cannot do otherwise; philosophy is this tyrannical impulse itself, the most spiritual Will to Power, the will to "creation of the world," the will to the causa prima.'  This is taken from Beyond Good and Evil by Friedrich Nietzsche.

What Command Do You Run to See the Host Variables That Ansible Natively Has Access to on the Servers In /etc/ansible/hosts File?

Problem scenario
You want to see the different variables that Ansible can leverage (e.g., for playbooks to inject host-specific data into files).  How do you find out what Ansible has access to on each server in /etc/ansible/hosts?

Solution
Run this command:
ansible all -m setup --tree /tmp/facts

How Do You Troubleshoot a Crontab Problem?

Problem scenario
You have modified the crontab (e.g., with sudo crontab -e), but the job is not running.  What can you do?

Possible Solution #1
A good troubleshooting technique of a cronjob is to configure it to have this job * * * * * env > /tmp/list.txt. You then analyze /tmp/list.txt to see if it is different from the results of running "env" manually. If the results are quite different you may want to consider using Ansible.  It can be easier to use Ansible to configure a cron job.  Ansible's supported cron module may work more reliably.  

To install and configure it, see this link if you are using CentOS/RHEL/Fedora, and this link if you are using SUSE.

Possible Solution #2
You may want to this this posting on Serverfault.com.

Possible Solution #3
This external site may help you.

Possible Solution #4
This site crontab.guru could also help.  It is a very good reference.

Possible Solution #5
To get the crontab job to execute as a human thinks it should, you may want to see this continualintegration.com posting. The problem may be both temporal and related to a triggering event.

How Do You Troubleshoot the openssl Error “getaddrinfo: Servname not supported for ai_socktype”?

Problem scenario
You use the openssl command, but you receive an error.  You run a command such as this:

openssl s_client -connect https://www.continualintegration.com:80

You get a message such as this:
getaddrinfo: Servname not supported for ai_socktype
connect:errno=0

What should you do to view the SSL certificates?

Solution
Run the command without the "http://".  Here is an example of the correct syntax:

openssl s_client -connect continualintegration.com:80

For Future Reference
OpenSSL uses SSL and TLS.  If you want books on the subject, you may click on one of the links below:

A Concise Guide to SSL/TLS for DevOps: 2nd Edition
Bulletproof SSL and TLS: Understanding and Deploying SSL/TLS and PKI to Secure Servers and Web Applications
Implementing SSL / TLS Using Cryptography and PKI
Network Security with OpenSSL: Cryptography for Secure Communications

How Do You Search a Directory in Linux for Files That Have Content That Match a Pattern?

Problem scenario
Linux novices call directories "folders."  You want to search all the directories and subdirectories for a string pattern.  How do you do this?

Solution
1.  Change directories into the directory where you want to start searching.

2.  Run this command:  grep patterntosearchfor * -ir

Replace "patterntosearchfor" with the pattern you want to find.  Use all lower case.  The "i" flag tells the Linux server to return case-insensitive matches.  The "r" flag tells the Linux server to search subdirectories (child directories) of the directory you were in.

How Do You Remove a File from a Git Repository so the Old Versions Are Eliminated?

Problem scenario
You accidentally uploaded a file with sensitive data (e.g., hard-coded credentials such as a database username and password) to a Git repository.  You want to eliminate it from the Git repository so all of its history are removed from the previous commits and it is unretrievable.  How do you do this?

Solution
WARNING:  This will delete data.  Some people rely on Git repos as a disaster recovery product.  Only do this if you know what you are doing or if the Git repo is not that important and can be restored from somewhere else.

1.  Change directories to be in the Git repository:  cd /path/to/git/nameOfrepo

2.  Remove the file that needs to be removed:  git rm filename

3.  Run this command:

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch subdir/path/foobar.txt' --prune-empty --tag-name-filter cat -- --all

# Replace "subdir/path" with the path from the Git repo to where the file is that needs to be eliminated.  This is relative to the directory you are currently in.  If the file is not in a subdirectory of the Git repo, you will not have anything for "subdir/path" -- not even a slash.

# Replace "foobar.txt" with the name of the file you want eliminated.

# If you receive an inexplicable error, try to do step #4 first, then do step #3.

4.  Run this command:  git commit -m "Eliminated a file"

5.  Run this command:  git push origin --force --all

6.  Run this command:  git push origin --force --tags

7.  There are strategies to avoid accidental commits.  The gitignore file may help you.  To learn more, see this link.

If you want a list of books on Git, see this link.