How to enable interactive shell in Yocto for a BeagleBoneBlack? - beagleboneblack

I am having a yocto project which builds fine and runs as expected (on my BBB). The image is configured to autostart an application and print the output to the console (serial via FTDI). What I am trying to do in general is to disable the autostart application (already done) and instead run an interactive shell.
My question would now be, just in general, what do I need to do to enable the serial console prompt for my yocto image? Like enable additional features in local.conf or even machine features or simply add a shell to IMAGE_INSTALL? Hope someone can tell me some details about that.
My question would now be, just in general, what do I need to do to enable the serial console prompt for my yocto image? Like enable additional features in local.conf or even MACHINE_FEATURES or simply add a shell to IMAGE_INSTALL? Hope someone can tell me some details about that.
Appendix:
Here is my uEnv.txt:
bootpart=0:1
bootfile=zImage
console=ttyO0,115200n8
fdtaddr=0x88000000
fdtfile=zImage-${DTB_FILE}
loadaddr=0x82000000
mmcroot=/dev/mmcblk0p2 ro
mmcrootfstype=ext4 rootwait
optargs=consoleblank=0
mmcargs=setenv bootargs console=\${console} \${optargs} root=\${mmcroot}
rootfstype=\${mmcrootfstype}
loadfdt=run findfdtfile; load mmc \${bootpart} \${fdtaddr}
\${bootdir}/\${fdtfile}
loadimage=load mmc \${bootpart} \${loadaddr} \${bootdir}/\${bootfile}
uenvcmd=if run loadfdt; then echo Loaded \${fdtfile}; if run loadimage; then run mmcargs
bootz \${loadaddr} - \${fdtaddr}; fi; fi;

From what I see here, it is already enabled.
I don't have the opportunity now to build an image, but check UART is enabled in the uEnv.txt. This is not a Yocto specific problem, but a BBB one.

Related

Alternative to using --squash when building docker images on Windows using local files

We have some local installers and zip files that we use to build our docker images. It is easy to get this to work in a Dockerfile:
FROM mcr.microsoft.com/windows/nanoserver
COPY myinstaller.exe .
RUN myinstaller.exe; \
del myinstaller.exe
The problem here is that it produces a layer for the COPY line, which increases the size of the image. A common work-around for this is to have one RUN line, that downloads the file from the Internet, runs commands, and then deletes the installation file. The problem, as written above, is that the installers are on the local filesystem.
I found that there is a --squash command for docker:
docker build --squash -t mytestimage .
This does exactly what I want: It gives me an image without this extra installer file that is not necessary. To run this command, you need to enable experimental features though. There is also an open issue to simply remove this feature:
https://github.com/moby/moby/issues/34565
Is there some alternative way of using local installers in a Dockerfile when running on Windows, that doesn't involve setting up a server to provide the files?
We ended up setting up nginx to provide files when building. On our build server, the machine building our docker images and the server that has the installer files have a very good connection between them, so downloading huge files is not a real problem.
When it comes to --squash, it is bugged for Docker on Windows. Here is the relevant issue for it:
https://github.com/moby/moby/issues/31468
There is an issue to move --squash out of experimental, but it doesn't seem to have a lot of support:
https://github.com/moby/moby/issues/38657
The alternative that some people propose instead of --squash is multi stage build, discussion here:
https://github.com/moby/moby/issues/34565
There is an alternative to --squash, if you have local installer files, you don't want to set up a web server, and you would like your docker image to be small, and you are running Windows: Use mapped drives.
In Windows, you can share folders with other users on your network. Docker containers are like another computer that is running on your physical machine, and it can access these network drives.
First set up a new user, for example username share and password password1. Create a folder somewhere on your computer. Then right click it, click properties, and then go to the Sharing tab and click "Share". Find the user that you have just created, using the little dropdown menu and Find people ..., and share the folder with this user.
Create a folder somewhere for your test project. Create a batch file setupshare.bat that looks like this:
#echo off
for /f "tokens=2 delims=:" %%i in ('ipconfig ^| findstr "Default Gateway"') do (
set hostip=%%i
goto :end
)
:end
set hostip=%hostip: =%
net use O: \\%hostip%\vms /USER:share password1
The first part of this file is only to find the ip address that the docker container can use to access its host computer. It is not the most pretty thing I've ever put together, so let me know if there's a better way!
It uses a for-loop, as that is the way to save the output of a command to a variable in batch files. The command is ipconfig, and we pipe it to findstr and searches for Default Gateway. We need to use ^| instead of just | because it is in a for-loop. The first part of the for-loop divides each line from the command on the delimiter, which is : in this case, and we only take the second token. The for-loop only handles the first line, if there are multiple entries with a Default Gateway. This script doesn't work if there are multiple entries and the first one is not the correct one.
The line set hostip=%hostip: =% is to remove a space at the start of the string.
We then have the IP address that we want to use stored in hostip. We use this in the net use command, which will map O:\ to shared folder vms on the machine with IP hostip. We use the username share and the password password1. Note that this is a very bad way of handling passwords, as they kind of should be secret!
With a batch file like this, we can set up a Dockerfile in this way:
# escape=`
FROM mcr.microsoft.com/dotnet/core/sdk:3.0
COPY setupshare.bat .
RUN setupshare.bat && `
copy O:\file.txt file.txt
The RUN command will first call setupshare.bat that sets up the network share properly. We can then use any file that we shared, for example a huge installer, and install the things that we want. In this case I have only shared a test file file.txt to see that it works, so just change that line.
I would still advice everyone to just set up a little web server, for example nginx, and use the standard way of writing Dockerfiles, with downloading files and running it in the same RUN command. That's what people expect when they see a Dockerfile, and it should be a more robust solution.
We can also hope that the Docker people either makes a COPY command that can copy, run, and delete installers in the same layer, or that --squash is implemented properly.

Running installer within docker file without user interaction

I've been trying to have a docker file setup where it can install a specific ODBC driver I need in an application.
I use the following commands:
RUN cd /tmp/./client1201/
RUN ./setup
and it runs the installer without any problem. The issue is that It requires user input in order to proceed with some steps.
Is there any way I can make this silent? If so, is this some docker specific feature? Or it actually requires some sort of support from the installer itself in order to achieve this?
Thanks for any assistance
RUN echo "yes" | ./script.sh
This may work for you.

How to easily configure multiple u-boot variables

I need to change multiple u-boot environment variables every time I setup a new embedded device e.g. ip address, ethernet address, etc.
Typing at the terminal prompt is tedious, and, I don't know if it's my terminal, buy trying to cut and paste anything more than a few characters can result in errors. Changing them in a text editor and copying that file to a specific location in flash would be much better than the terminal.
Anyone have a good way to change multiple environment variables at once?
A script file is ideal for this situation. Its much better than copy & pasting for many commands and can handle much more complexity. You can enter all your commands into a text file and create a script image using mkimage (where myscript is the text file's name):
mkimage -T script -C none -n 'My Script' -d myscript myscript.img
Then you can simply load and execute myscript.img to perform all setup tasks for the device.
For example, to load and execute myscript.img from USB stick:
usb start && load usb 0:1 ${loadaddr} myscript.img && source ${loadaddr}
It is possible to add this load command to U-Boot's default environment so all you need to do is run the name of the command. You can even add logic to the default boot sequence to automatically perform the device setup if the USB device and script file are present. Depending on the U-Boot version, you can manipulate the default environment by either modifying the U-Boot source or by editing uEnv.txt (when supported).
Scripts are also useful for maintaining multiple setup configurations that would allow you to set the device up for one of many deployment or development configurations.
I have been able to use PuTTY to copy and paste my variables into U-Boot. You can separate the declarations by semicolons to if you want to do all of the variables at once, like this:
setenv ipaddr 192.168.1.5; setenv serverip 192.168.1.10;

interactive docker build from dockerfile?

I want to use a Dockerfile to build an image. However, commands will need user input as they run. Currently, the build is not successful because docker exits on user input. I know I can use the -i -t options on docker run command but I want to do that on a Dockerfile. How is that possible?
You can try with expect or a similar tool.
The easiest way to configure it is using the autoexpect tool, which lets you run the commands interactively and creates an expect script for you.
I couldn't get the rvmsudo stuff working (I haven't used it and didn't want to spend too much time with it) so I decided to use vi instead. First run autoexpect
$ autoexpect vi test
This will open vi and you can create or edit the file and save it. After exiting the vi you'll see your file test as well as an expect script script.exp.
You can then remove the test file and execute script.exp. It will recreate the same file using the same steps.
The autoexpect tool is great, but you may have to create a script from scratch if you need to have more control over what happens. E.g. if you don't want the script to work with the exact expected input.

iPad run with black screen in Jenkins

i configured out jenkins in way that it was launched under my account but when i build a project for my unit tests with KIF framework, Jenkins launches iPad simulator with black screen and nothing happens (jenkins also doesn't provide any useful information).
Can anyone advice to solution of this issue?
Please note that everything works just fine from command line.
Finally, i've found the solution need to use iPad Retina or iPad Retina (64-bit):
-destination OS=7.0,name=iPad Retina
So, the last supposed suggestion doesn't work either - need another solution.
Just ran into this myself. Following up on user2738882's self-answer, I have a fix for the pitfalls his solution has:
He's correct that it was occurring due to Jenkins being run as a launch daemon process. Daemon's are launched at start without login, but they aren't intended to have access to the UI. This is what causes the issue.
Unfortunately Jenkins defaults to installing as a launch daemon if you install via the Archive (.war).
The solution I went with is to move it over to a launch agent. To do so follow these steps:
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
sudo cp /Library/LaunchDaemons/org.jenkins-ci.plist /Users/<Path to Jenkins User>/Library/LaunchAgents/org.jenkins-ci.plist
Right click - > Get Info on the org.jenkins-ci.plist file
Change the read write permissions to all users (bottom)
Modify the plist file to change GroupName key value from "daemon" to "agent"
Right click -> Get Info again
Reset the file access to as it was before
sudo launchctl load /Users/<Path to Jenkins User>/Library/LaunchAgents/org.jenkins-ci.plist
The drawback of this approach is launch agents don't start until the user they're associated with logs in. In order to accommodate this I've configured my Jenkins user to login when the server starts up. To do this:
Open System Preferences
Open Groups & Users
Login Options
Set your Jenkins user as the Automatic Login:
This is obviously a security concern, but these machines should only ever be accessible on your local network and in a secure location anyway. Regardless I set the machine to show a screensaver as quickly as possible with a login.
The work-around that I see is that you can create AppleScript, which will run a simulator using terminal. Example:
do shell script "script"
where, script is your terminal command.
After script is created, add build step 'Execute shell script' to jenkins and write script which will run your AppleScript.
Example:
open /Applications/MyScript.app
The issue was in Jenkins and it was solved in the following way:
Stop the jenkins daemon via command:
sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
Start Jenkins as process via command:
sudo nohup java -jar /Applications/Jenkins/jenkins.war --httpPort=8080 --ajp13Port=8010
And it works perfectly!
But there is a pitfall, after launching Jenkins under your user, all jobs disappear and you need to create it once again.

Resources