execute commands in a CoreOS cloud-config (e.g. to add swap) - digital-ocean

I see that unlike the standard cloud-config file, there is no runcmd option in a CoreOS cloud-config file. Currently, I enable swap on a CoreOS machine by adding the following to my cloud-config:
units:
- name: swap.service
command: start
content: |
[Unit]
Description=Turn on swap
[Service]
Type=oneshot
Environment="SWAPFILE=/1GiB.swap"
RemainAfterExit=true
ExecStartPre=/usr/sbin/losetup -f ${SWAPFILE}
ExecStart=/usr/bin/sh -c "/sbin/swapon $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
ExecStop=/usr/bin/sh -c "/sbin/swapoff $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
ExecStopPost=/usr/bin/sh -c "/usr/sbin/losetup -d $(/usr/sbin/losetup -j ${SWAPFILE} | /usr/bin/cut -d : -f 1)"
[Install]
WantedBy=local.target
Then after initializing my CoreOS image I have to ssh into the machine and run:
sudo fallocate -l 1024m /1GiB.swap && sudo chmod 600 /1GiB.swap \
&& sudo chattr +C /1GiB.swap && sudo mkswap /1GiB.swap
sudo reboot
before swap will be enabled (e.g. as evidenced by top).
It seems like I should be able to accomplish the latter commands in the cloud-config file itself, but I'm not clear on how I can run such commands without a runmcd field in cloud-config. Perhaps this can be done either by editing my swap.service unit or perhaps by adding another unit, but I haven't figured out quite how.
So, that leaves me with two questions: (1) Can this be done or will it always be necessary to run the last commands manually? (2) If the former, then how?

As pointed out in this answer to an issue on Github, you end up writing a unit to invoke the command of your choice. This answer, gives a good example of using an arbitrary command:
#cloud-config
....
coreos:
units:
- name: runcmd.service
command: start
content: |
[Unit]
Description=Creates a tmp foo file
[Service]
Type=oneshot
ExecStart=/bin/sh -c "touch /tmp/foo;"

#cboettig - thanks to your unit file example and #philibaker note, I got this going - basically the only thing I had to do was to change the ExecStartPre to:
ExecStartPre=/bin/bash -c "\
fallocate -l 2g $SWAPFILE && \
chmod 600 $SWAPFILE && \
chattr +C $SWAPFILE && \
mkswap $SWAPFILE && \
losetup -f $SWAPFILE"
and that includes the entire setup in the preexec step.

Related

Sending pcap file via packetgen dpdk

Sending a pcap file on port 0. I get the following error. Any fix would be appreciated!
The command used is:
sudo ./app/x86_64-native-linuxapp-gcc/pktgen -c 0X01 -n 1 --file-prefix=pg -w 4:00.1 -- -m 1.0 -T -P -s 0:~/Downloads/bigFlows.pcap
There are 2 obvious reasons for the failure.
Number of CPU cores for pktgen to work is 1 + number of ports in use
you have extra argument in comamnd executed in pktgen.
Checking the link, it show the command used is sudo ./app/x86_64-native-linuxapp-gcc/pktgen -c 0X01 -n 1 --file-prefix=pg -w 4:00.1 -- -m 1.0 -T -P -s 0:[~/Downloads/bigFlows.pcap]. You should not sue [] instead use 0:actual path to pcap.
Note: #SaifUllah during the live debug both core and pcap were show cased for you.

Docker image not executed by host bin/bash

I have a linux executable. I've built a docker image with centOS 7 which runs ok when executed directly from macOS terminal (macOS Mojave version 10.14.6). The image is built with:
Dockerfile: $ docker build -t my_testi .
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200504" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-05-04 00:00:00+01:00"
CMD ["/bin/bash"]
ADD executable /bin/
CMD /bin/bash cd /casedir && executable
I can execute this with command:$ docker run -ti -v /host/casedir/:/casedir my_testi executable /casedir/inputfile.txt. Now, I'm trying to get the docker image to run from a /bin/bash within C++.
Snippet in .cpp:
FILE *pipe;
std::string s="";
pipe = popen("/bin/bash", "w");
fprintf(pipe, "source ~/.bash_profile \n");
#if defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))
// On MacOX we run with docker
s += std::string("docker run -ti -v ") +
analysispath.parent_path().string() + std::string("/:/casedir my_testi executable /casedir/") +
inputfiles.back().filename().string(); // docker run -ti -v /host/casedir/:/casedir my_testi executable /casedir/inputfile.txt
#elif defined(__linux__)
// On Linux based systems link executable and run
s += std::string("ln -s ") + std::getenv("EXECUTABLE") + std::string(" executable\n");
s += std::string("./executable ") + inputfiles.back().filename().string() + std::string(" > executable_out") + std::string(" \n");
#endif
fprintf(pipe, "%s", s.c_str());
The problem is that bash in C++ code doesn't run the docker image or perhaps(?) doesn't wait for the command to execute. It jumps straight to next code block. What could be the issue here and how could I get C++ to wait the command is executed?
There are two problems which needed addressed. Firstly, the docker command had to be terminated with \n and it had to be run in non-interactive mode i.e. -t instead of -ti. Thus, the command changes to:
s += std::string("docker run -t -v ") +
analysispath.parent_path().string() + std::string("/:/casedir my_testi executable /casedir/") +
inputfiles.back().filename().string() + std::string("\n");

go unit test runs from %APPDATA%

I am trying to run some of my Go unit tests using "go test" but the test executable is built and run from my machine's %APPDATA%/local/temp directory. My PC has IT enforcement which blocks any unrecognized executable from being run other than from a pre-sanctioned directory (i.e C:/dev/projects"). All my Go source code are in that directory, including my *_test.go files. Is there a way to tell the Go test module to build and run from the current directory?
Yes you can.
Setting temp directory before executing the go test. By default temp directory environment variable gets evaluated in the order of TMP, TEMP, USERPROFILE, Windows directory; refer to msdn doc.
Basically it complies the go test under given temp directory and execute it.
C:\> cd dev\projects\src\mygotest
C:\dev\projects\src\mygotest>echo %CD%
C:\dev\projects\src\mygotest
C:\dev\projects\src\mygotest>set TMP=%CD%
C:\dev\projects\src\mygotest>go test -x
WORK=C:\dev\projects\src\mygotest\go-build306298926
mkdir -p $WORK\mygotest\_test\
mkdir -p $WORK\mygotest\_test\_obj_test\
cd C:\dev\projects\src\mygotest
"C:\\Go\\pkg\\tool\\windows_amd64\\compile.exe" -o "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test\\mygotest.a" -trimpath "C:\\dev\\projects\\src\\mygotest\\go-build306298926" -p main -complete -buildid 86cb7a423d355c7468ad98c4f8bffe77b68d2265 -D _/C_/dev/projects/src/mygotest -I "C:\\dev\\projects\\src\\mygotest\\go-build306298926" -pack "C:\\dev\\projects\\src\\mygotest\\sample.go" "C:\\dev\\projects\\src\\mygotest\\sample_test.go"
cd $WORK\mygotest\_test
"C:\\Go\\pkg\\tool\\windows_amd64\\compile.exe" -o "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test\\main.a" -trimpath "C:\\dev\\projects\\src\\mygotest\\go-build306298926" -p main -complete -D "" -I "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test" -I "C:\\dev\\projects\\src\\mygotest\\go-build306298926" -pack "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test\\_testmain.go"
cd .
"C:\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test\\mygotest.test.exe" -L "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test" -L "C:\\dev\\projects\\src\\mygotest\\go-build306298926" -w -extld=gcc -buildmode=exe "C:\\dev\\projects\\src\\mygotest\\go-build306298926\\mygotest\\_test\\main.a"
$WORK\mygotest\_test\mygotest.test.exe
Hello, playground
PASS
ok mygotest 0.526s
C:\dev\projects\src\mygotest>
Note: TMP set to current terminal session only, it doesn't affect system environment variable.
Important thing to note from above test output is WORK=C:\dev\projects\src\mygotest\go-build306298926.
Happy testing!

Append two new lines before additional text using sed

I've hit a bit of a stumper (for me). I'm attempting to insert two newline characters into the RHEL5 /etc/sysconfig/iptables file during our server build process (using kickstart post-installation scripts).
The specific sed command is:
${SED} -i "/-i lo/ a\
\n\n#Trusted Traffic\n-A INPUT -s 10.153.156.0/25,10.153.174.160/27 -d ${MGTIP} -m state --state NEW -j ACCEPT\n\n#Remote Access\n-A INPUT -s 10.120.80.0/21,10.152.80.0/21,10.153.193.0/24,172.18.1.0/24,${MGTNET}/${NUMBITS} -d ${MGTIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n#Backups\n-A INPUT -s 10.153.147.192/26 -d ${BKPIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n" ${IPTABLES}
This is actually part of a larger script. ${SED}and ${IPTABLES} are already set to the necessary values.
All of the newlines work with the exception of the first two. Or, more accurately, the second of the first two. Even the last two newlines after ACCEPT work. What happens with the first two newlines is that the first works, creating a newline after matching the iptables entry which contains -i lo. The second, however, simply inserts a literal 'n' prior to the #Trusted Traffic text.
It ends up looking like
(snip)
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
n#Trusted Traffic
-A INPUT (snip)
I've tried various methods of ensuring the second newline is inserted. I've used two blank lines instead of \n\n. I've used two newline characters on separate lines, I've used \\n\\n. Everything I've tried so far results in the same outcome: A literal 'n' being inserted instead of a second newline.
Does sed simply not work with two newline characters at the beginning of appended text? Is there a way to make this work that I'm simply ignorant of?
I don't see why it's not working either, but you can do this also with the substitute option instead of append:
${SED} -i "s%-i lo.*%&\n\n#Trusted Traffic\n-A INPUT -s 10.153.156.0/25,10.153.174.160/27 -d ${MGTIP} -m state --state NEW -j ACCEPT\n\n#Remote Access\n-A INPUT -s 10.120.80.0/21,10.152.80.0/21,10.153.193.0/24,172.18.1.0/24,${MGTNET}/${NUMBITS} -d ${MGTIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n#Backups\n-A INPUT -s 10.153.147.192/26 -d ${BKPIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n%" ${IPTABLES}
Interesting, I would have thought that one of your attempted solutions would work, but I am seeing the same behavior. Here is one potential solution:
${SED} -i -e "s/-i lo.*/\0\n\n/" -e "// a\
#Trusted Traffic\n-A INPUT -s 10.153.156.0/25,10.153.174.160/27 -d ${MGTIP} -m state --state NEW -j ACCEPT\n\n#Remote Access\n-A INPUT -s 10.120.80.0/21,10.152.80.0/21,10.153.193.0/24,172.18.1.0/24,${MGTNET}/${NUMBITS} -d ${MGTIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n#Backups\n-A INPUT -s 10.153.147.192/26 -d ${BKPIP} -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT\n\n" ${IPTABLES}
This works by first appending the two newlines to the end of the previous line, and then doing the append.
Not sure about portability, but try:
${SED} '/-i lo/ a\
\
\
'"#Trusted Traffic\\
-A INPUT -s 10.153.156...
"
This technique works on BSD sed. You can maintain double quotes throughout with:
${SED} "/-i lo/ a\\
\\
\\
#Trusted Traffic\\
-A INPUT -s 10.153.156...
"
In either case, there must be no whitespace between the backslash and the end of the line.

How to run the programe with parameters inside gdb?

Suppose I'm in gdb memcached,but want to run it as memcached -d -u root -m 50 -c 1024 -p 11051.
How to do this?
On the gdb prompt, juste type
run -d -u root -m 50 -c 1024 -p 11051
Alternativerly, you can also use the args parameter:
(gdb) help set args
Set argument list to give program being debugged when it is started.
Follow this command with any number of args, to be passed to the program.
so in your case:
set args -d -u root -m 50 -c 1024 -p 11051
run (or) start