For some obscure reason, Apple blocks me from accessing my own files with the Terminal. To allow Terminal to access all files and folders, I have to give Terminal the rights for “Full Disk Access” under “Security & Privacy
” in the “System Preferences
“.
Category Archives: Code
Delete locked files on macOS with the Terminal
Unlock the file:
chflags nouchg filename.txt
Options
-R
recursively change files-v
verbose
References
Transfer a Docker Image from Mac to Pi
TLDR
It didn’t work out. Don’t bother repeating it. It seems that with this way, the image is not of the correct architecture!
Aim
I’d like to transfer Docker images without depending on an external repository like Docker Hub.
Protocol
Check the images:
docker images
Save the image to a tar file:
docker save -o myImage.tar rolfsuter/testmultiarch:latest
Copy the tar file to the Pi:
scp myImage.tar pi@[IP]:myImage.tar
Connect to the Pi:
ssh pi@[IP]
List the current Docker images on the Pi:
sudo docker images
Load the image from the tar file:
sudo docker load -i myImage.tar
Check the image. Run:
sudo docker run --rm rolfsuter/testmultiarch:latest uname
Response:
standard_init_linux.go:211: exec user process caused "exec format error"
References
Exploring F# with .NET and Docker on Raspberry Pi
Recently, I got a Raspberry Pi 3 Model B. Now, I’d like to figure out, if I can run an F# server in a Docker container on it. I am aware that the currently installed Raspberry Pi OS is actually a 32-bit OS while the processor of my Pi has an 64-bit architecture. This has an impact if I’d like to install .NET directly on the OS. Since I intend to use Docker, I’ll sort that out later and just try to get it going.
Proof of principle
Try to run a container with .NET installed:
sudo docker run -it microsoft/dotnet:latest
Since I managed to spin up a .NET container, the next step is to create an F# console application and run it:
mkdir test
cd test
dotnet new console -lang "F#"
dotnet run
I am also able to run the dll file directy:
dotnet bin/Debug/netcoreapp2.1/test.dll
To exit the container and keep it running, I press [ctrl]
+ [p]
followed by [ctrl]
+ [q]
.
Bind mount a host directory
First I create in the current directory a folder hostFolder
containing a subfolder on the host system. I’ll mount hostFolder
into the container below.
mkdir hostFolder
mkdir hostFolder/subfolder
Then I create a container from the image microsoft/dotnet:latest
. Using the -v
flag, I mount the hostFolder
into the /targetFolder
in the container. Note that the directory targetFolder
is created in the root directory (/
). The term "${PWD}"/hostFolder
determines the path of the hostFolder to mount with ${PWD}
being the current working directory. The part after the colon :
with the path /targetFolder
defines the mount point in the container. The -w
flag determines the working directory in the container. Thus, I get directly into the /targetFolder/subFolder
directory in the container.
sudo docker run -it \
-v "${PWD}"/hostFolder:/targetFolder \
-w /targetFolder/subfolder \
microsoft/dotnet:latest
For testing I create a test file within the subfolder
on the container and see it on the host system.
sudo docker run -it -v "${PWD}"/Source/Repos/Lab/TestApp:/TestApp -w /TestApp microsoft/dotnet:latest
Add a Dockerfile
A Dockerfile describes how Docker creates an image and runs it. However, I’d like to develop on my Mac and try to setup the docker image there. Thus, I’ll setup a SAFE stack app on my Mac in another post.
References
Working with Docker
Here are some notes about working with Docker. On my Raspberry Pi I need to run all commands as sudo
.
First of all, do not confuse the different terms. An image is like a blueprint that serves to generate containers. The containers are then the actual instance that you can start or stop.
List images
docker images
List containers
- Show the running containers:
docker ps
- Show all containers:
docker ps -a
- Use the
container
command. I don’t know it it differs from theps
command above. The output seems to be the same.
docker container ls
Start a container
- List the available containers (see above)
- Get the container ID to start
- Run
docker start [Container ID]
e.g.
docker start 725dc751823b
Exit a container without stopping it
If started a container with the docker run
options -i
and -t
, you can detach from it and leave it running:
- Press
[Ctrl]
+[p]
followed by[Ctrl]
+[q]
Connect/attach to a running container
docker attach [Container ID]
References
Run Pi-hole in a Docker container on a Raspberry Pi
I set up Pi-hole on a Raspberry Pi already a while ago and it is running fine. These are my notes that I took during installation. Unfortunately, the lack some details…
- Download the ‘
docker_run.sh
‘ script from https://github.com/pi-hole/docker-pi-hole/blob/master/docker_run.sh - Transfer the script to the Raspberry Pi
scp docker_run.sh pi@[IP]:docker_run.sh
- Connect with SSH to the Raspberry Pi
- run the script
sudo sh docker_run.sh
The script starts well but then encounters an issue after running the container:
Starting up pihole container docker_run.sh: 19: [: healthy: unexpected operator
.docker_run.sh: 19: [: healthy: unexpected operator
.docker_run.sh: 19: [: healthy: unexpected operator
.docker_run.sh: 19: [: healthy: unexpected operator
List all Docker containers
sudo docker container ls
Check the container
sudo docker inspect [Container ID]
Set the password for Pi-hole
Search the log file for the password
sudo docker logs pihole
References
Git: Remove ignored files
You can ignore files in git from being added to the repository by putting a .gitignore
file into place. It might however happen that the .gitignore
file seems not work. This is the case if you have already included the files in the git repository index.
To resolve the issue, you can perform these commands in your project directory containing the .git
folder:
$ git rm -r --cached .
$ git add .
$ git commit -am "Remove ignored files"
- First, remove all the files from the git index. Don’t worry, this does not remove the actual local files.
- Then add back all files. The
.gitignore
file controls that git does not add the files to ignore. - Finally, commit the changes.
References
Define the assembly information of an F# .NET Core app
There are several options to define the assembly information of an .NET Core app in F#:
.fsproj
fileDirectory.Build.props
file- When running
dotnet build
ordotnet publish
:-p:Version=a.b.c.d
The information of the .fsproj
file seems to have priority over Directory.Build.props
file. You can place the Directory.Build.props
file in the project folder or the solution folder.
.fsproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Version>1.0.0.0</Version>
<FileVersion>1.0.0.0</FileVersion>
<Product>MyApp</Product>
<Copyright>Copyright © 2020 by myself</Copyright>
</PropertyGroup>
<ItemGroup>
...
Directory.Build.props file
<Project>
<PropertyGroup>
<Version>1.0.0.0</Version>
<FileVersion>1.0.0.0</FileVersion>
<Product>MyApp</Product>
<Copyright>Copyright © 2020 by myself</Copyright>
</PropertyGroup>
</Project>
Check the assembly version
The simple way
- Run:
cat MyApp.dll
- Check the last lines. They contain the assembly information
The convenient way
Install the versioninfo tool and run it on the .dll:
dotnet tool install --global dotnet-versioninfo
versioninfo MyApp.dll
References
Debug an F# .NET Core app in VS Code on macOS
Press ‘F5’
The F5
button is the magic button to start debugging. However, if you start debugging the first time, you need to set up VisualStudio Code first. You need to setup a launch.json
file to start debugging and a tasks.json
file to first run the process.
Setup
- Press
F5
- Select
.NET Core
- VS Code generates the
launch.json
file in the.vscode
folder and opens it.
- Edit the
launch.json
file - Insert the configuration entry within the selected square brackets of the ‘configuration’ section
- Press
Ctrl
+Space Bar
- Select
.NET: Launch .NET Core Console App
- Enter the path to the application
.dll
file in theprogram
attribute:"${workspaceFolder}/src/MailBoxTransformer/bin/Debug/netcoreapp3.1/MailBoxTransformer.dll"
- The path differs from the original template because the project is within the
src
sub-folder.
- Press
- Press
F5
again - VS Code now complains that it does not find the
build
task defined in thepreLaunchTask
attribute of thelaunch.json
file - Select
Configure Task
- Select
Create tasks.json file from template
- Choose the
.NET Core Executes .NET core build command
template
- VS Code generates the
tasks.json
file in the.vscode
folder and opens it.
- Edit the
tasks.json
file - If the
.fsproj
file is not in the main folder - Insert the path of the directory containing the
.fsproj
file as an additional argument fordotnet build
."${workspaceFolder}/src/MailBoxTransformer",
- To see the logs of the build task in the console (optional):
- Change the
presentation
attribute in thetasks.json
file
from"silent"
to"always"
- Change the
- Press
F5
again - VS Code runs
- The
dotnet build
process - The app
- The
- Add the
launch.json
and thetasks.json
files located in the.vscode
folder to your source control system (e.g. git).
You are now able to start the build process and the app itself from within VS Code. Now you can set break points and debug your app. I have included the complete launch.json
and the tasks.json
files below. Have fun!
launch.json
- Located in the
.vscode
folder
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/MailBoxTransformer/bin/Debug/netcoreapp3.1/MailBoxTransformer.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
}
]
}
tasks.json
- Located in the
.vscode
folder
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
"${workspaceFolder}/src/MailBoxTransformer",
// Ask dotnet build to generate full paths for file names.
"/property:GenerateFullPaths=true",
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "always"
},
"problemMatcher": "$msCompile"
}
]
}
References
Create an F# .NET Core app on macOS
Create a console app with the CLI
dotnet new console -lang "F#" -o src/MyConsoleApp
Run the app in the terminal
The easy way: Move first to the folder with the .fsproj
file and then use dotnet run
without any arguments:
cd src/MyConsoleApp
dotnet run
If you want to start the app from a location different than the one containing the .fsproj
file, you need to enter the argument --project
with the path to the .fsproj
file.
dotnet run --project src/MyConsoleApp/MyConsoleApp.fsproj