Menu

Use DKtoolian

Dirk Krause
← Previous ↑ Home ↑ Live Systems Next →

Use DKtoolian to erase disk or partition

Overview

In the subsections below the dd program should produce a message “No space left on device”.

If there are other error messages about I/O errors, dd stopped at the error position and did not overwrite the remaining space on disk. You should use a real tool (a hammer or a drilling machine) to physically destroy the disk.

The device name /dev/sda is used as an example here. Replace it by the device name of the disk you want to retire.

Flash-based (SSD or USB stick)

dk-eradisk -b 1M | dd of=/dev/sda bs=1M conv=fdatasync

The block sizes of both commands (-b, bs) must match!

Traditional hard disk

dk-eradisk -b 4K | dd of=/dev/sda bs=4K conv=fdatasync

The block sizes of both commands (-b, bs) must match!

Flash-based (SSD or USB stick), paranoid

for i in 7 6 5 4 3 2 1 0
do
  dk-eradisk -p $i -b 1M | dd of=/dev/sda bs=1M conv=fdatasync
done

Due to different patterns used in the passes, each bit is toggled at least twice.

Traditional hard disk, paranoid

for i in 7 6 5 4 3 2 1 0
do
  dk-eradisk -p $i -b 4K | dd of=/dev/sda bs=4K conv=fdatasync
done

Use DKtoolian to clone computers

What is cloning?

If a site owns a number of equal PCs an administrator can install one PC as the “master”. After installation the entire disk contents or the contents of relevant partitions is transferred to all the other PCs to avoid individual installations on each PC.

Several methods are available:

  • An archive is a file or a set of files containing all information required to restore a set of files and directories. Most archive file formats use compression to reduce archive file size.
    • Some archive file formats — i.e. WIM — can be mounted as virtual disk drives.
    • Some archive file formats — i.e. WIM — require the archive(s) to be present as file to restore data.
       
  • An archive data stream is a special archive type. When restoring data no repositioning operations are used on input data, data is processed as received.
    The restoring programs can read the archive stream on standard input.
    Archive data streams can be processed in pipes, i.e. we can use compression and/or encryption on the sender side and the appropriate decryption and/or decompression on the recipient side.
    Examples are output files or data streams created by the tar or cpio program.
     
  • A disk image is a file or a set of files containing all information required to restore the data on a storage device or a disk volume.
    • A sector-by-sector copy is a full copy of the original media and can be used to restore structure and contents of the original media. A sector-by-sector copy contains all sectors including the unused sectors.
    • A used-sectors-only copy only includes the used sectors of the original media (boot sector, bootloader in out-of-partition sectors before first partition, used sectors from partitions).
    An image is created from the master PCs disk or a partition. Typically an image is saved on a portable disk or on a set of DVDs. After applying the image to a destination PC this PCs file system contents is an exact copy of the master PCs file system.
     
  • A disk image data stream is a special disk image type. When applying a disk image data stream no repositioning operations are used on input data stream, data is processed as received.
    The restoring programs can read the disk image data stream on standard input.
    Disk image data streams can be processed in pipes, i.e. we can use compression and/or encryption on the sender side and the appropriate decryption and/or decompression on the recipient side.
    Examples are data streams created by “ntfsclone --save-image” or “dd”.
     
  • A computer image is a file or a set of files containing all information required to restore the data on a complete computer. Typically it contains information about the disks in the computer, partition tables, boot sectors, boot loaders and all partitions contents.
    An example is the files set created by clonezilla.

For all methods shown above we can save data on an image server.
For data streams we can use dk-send/dk-recv, udp-sender/udp-receiver or netcat to transfer the data directly from the master PC to the image server or to the recipient(s). Compression is recommended to reduce network traffic.
Other methods require access to the data as files, so we can use either a portable disk, NFS or SMB file servers or — for clonezilla — SSH access.

A computer image, disk, image, image data stream, archive or archive data stream of a computer can also be used as system backup of the computer to avoid a complete OS+software re-installation i.e. after hardware problems, setup and software experiments…
Applying the system backup to the computer it was made from returns that computer to the timestamp the backup was made.
Note: In addition to the system backup typically only made in large intervals or before or after adding new software you need regular periodic data backup. So after a crash you can restore OS and software to a working state from the last working system backup and data to the most recent state from the data backup.
Data backup is out of the scope of this page, here we are dealing with system backup only.

Clone one master to multiple recipients

For data transmission from one sender to multiple recipients we have several choices:

Multiple TCP connections
One dk-send process listening on a TCP port number can accept multiple connection requests thus establishing multiple TCP connections.
Data is send over all connections.
The transmission time grows with the number of connections.

Multicast/broadcast transmission
Using udp-sender and udp-receiver data is sent using multicast or broadcast so all recipients receive the same UDP data packets. The transmission time does (nearly) not depend on the number of recipients.
It depends on your network infrastructure whether multicast or broadcast can be used. Broadcast traffic might disturb machines not involved in the transmission.

Clonezilla
Clonezilla can use Multicast/Broadcast too to distribute a computer image to multiple computers.
The Clonezilla server internally provides the involved services (DHCP/TFTP/NFS) to PXE boot clients and deploy images.
Unfortunately I did not find documentation how to use Clonezilla server co-operating with an existing DHCP server.
Deactivating the regular DHCP server in our network is not an option, so I did not test Clonezillas multicast/broadcast features.

Traditional hard disk vs. SSD

For traditional hard disks you can use all the methods shown below.

SSD and other FLASH-based storage devices differ significantly from traditional (spinning) disks.
I recommend to read How to damage a FLASH storage device and for german users the articles series about SSD on Linux in german language.

Short summary:

  • Avoid single sector or file system block access when writing to SSD.
    The good write size is the SSDs erase block size or integer multiples of that size. Write access must be aligned to the SSDs erase block size.
    I recommend 1048576 bytes or power-of-2 multiples.

  • If the SSD supports TRIM you should inform the SSDs controller which blocks of the file system are unused after cloning a partition or disk.

mount /dev/sda1 /mnt
fstrim -v /mnt
umount /dev/sda1

Example situation

In the examples below we have the following hosts involved:

  • 192.0.2.2
    Image master PC named “imas”.
    The example installation of the software is done on this PC and must be distributed to other PCs.
     
  • 192.0.2.100
    Image server named “isrv”
    This server is used to save disk images.
     
  • 192.0.2.10 ... 192.0.2.99
    PCs to install.

For FLASH-based storage devices (SSD drives, SD cards, USB memory sticks) the block size should be equal to the devices erase block size or integer multiples of that size. So 1048576 bytes (1M) is a good choice. For traditional spinning hard disk 4K would be sufficient.

The shell variables in the examples are only used to avoid overlong text lines. In a real installation one would concatenate the commands directly by pipes.

Entire hard disk, sector by sector

Direct cloning

Note: Although you can clone directly from one sender to multiple recipients I do not recommend to do so. If there is any problem during disk image data stream creation on the sender, you have a larger number of unusable PCs as result.
So I recommend to use direct cloning only from one source PC to one recipient PC. For cloning to multiple PCs you should first create the image and save it on an image server.

Simple cloning

On the image master PC run:

DD="dd if=/dev/sda bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
$DD | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $BS | $DD

Cloning with compression

On the image master PC run:

DD="dd if=/dev/sda bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
$DD | $GZ | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

Cloning with compression and encryption

On the image master PC run:

DD="dd if=/dev/sda bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
$DD | $GZ | $GPGC $GPGD | $DS

You are asked for a password. Keep the password, you need the same password on the clients for decryption.

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GPG  | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

Cloning using an image server

Simple cloning

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda bs=1M"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $BS | $DD

Cloning with compression

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda bs=1M"
GZ="gzip -9"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

Cloning with compression and encryption

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda bs=1M"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $GPGC $GPGD | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz.gpg
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz.gpg

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

Partition, sector by sector

Direct cloning

Note: Although you can clone directly from one sender to multiple recipients I do not recommend it. If there is any problem during disk image data stream creation on the sender, you have a larger number of unusable PCs as result.
So I recommend to use direct cloning only from one source PC to one recipient PC. For cloning to multiple PCs you should first create the image and save it on an image server.

Simple cloning

On the image master PC run:

DD="dd if=/dev/sda1 bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
$DD | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $BS | $DD

Cloning with compression

On the image master PC run:

DD="dd if=/dev/sda1 bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
$DD | $GZ | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

Cloning with compression and encryption

On the image master PC run:

DD="dd if=/dev/sda1 bs=1M"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
$DD | $GZ | $GPGC $GPGD | $DS

You are asked for a password. Keep the password, you need the same password on the clients for decryption.

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GPG  | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

Cloning using an image server

Simple cloning

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda1 bs=1M"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $BS | $DD

Cloning with compression

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda1 bs=1M"
GZ="gzip -9"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GZ | $BS | $DD

Cloning with compression and encryption

Transfer image from master PC to image server

On the master PC run:

DD="dd if=/dev/sda1 bs=1M"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $GPGC $GPGD | $DS

You are asked for a password. Keep the password, you will need it later on the recipients.

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz.gpg
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz.gpg

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
BS="dk-blks -b 1M"
DD="dd of=/dev/sda1 bs=1M conv=fdatasync"
$DR | $GPG | $GZ | $BS | $DD

NTFS partition, used sectors only

Note: Not recommended for SSD, see Traditional hard disk vs. SSD!

Direct cloning

Note: Although you can clone directly from one sender to multiple recipients I do not recommend it. If there is any problem during disk image data stream creation on the sender, you have a larger number of unusable PCs as result.
So I recommend to use direct cloning only from one source PC to one recipient PC. For cloning to multiple PCs you should first create the image and save it on an image server.

Simple cloning

On the image master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
$DD | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $DD

Cloning with compression

On the image master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
$DD | $GZ | $DS

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GZ | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GZ | $DD

Cloning with compression and encryption

On the image master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
DS="dk-send 9876 -n unlimited -a 192.0.2.0/255.255.255.0"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
$DD | $GZ | $GPGC $GPGD | $DS

You are asked for a password. Keep the password, you need the same password on the clients for decryption.

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.2 9876"
GPG="gpg -d"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GPG  | $GZ | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.2 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GPG | $GZ | $DD

Cloning using an image server

Simple cloning

Transfer image from master PC to image server

On the master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $DD

Cloning with compression

Transfer image from master PC to image server

On the master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
GZ="gzip -9"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $DS

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GZ | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GZ | $DD

Cloning with compression and encryption

Transfer image from master PC to image server

On the master PC run:

DD="ntfsclone --save-image -o - /dev/sda1"
GZ="gzip -9"
GPGC="gpg -c --cipher-algo TWOFISH --digest-algo SHA512"
GPGD="--s2k-mode 3 --s2k-digest-algo SHA512"
DS="dk-send 9876 -a 192.0.2.100/255.255.255.255
$DD | $GZ | $GPGC $GPGD | $DS

You are asked for a password. Keep the password, you will need it later on the recipients.

On the image server run:

dk-recv 192.0.2.2 9876 /home/joe/image.dat.gz.gpg
Distribute image from image server to recipients

On the image server run:

dk-send -n unlimited -a 192.0.2.0/255.255.255.0 9876 /home/joe/image.dat.gz.gpg

On the PCs to install — except the final one — run:

DR="dk-recv 192.0.2.100 9876"
GPG="gpg -d"
GZ="gzip -dc"
DD="ntfsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GPG | $GZ | $DD

On the final PC to install run:

DR="dk-recv 192.0.2.100 9876 -t"
GPG="gpg -d"
GZ="gzip -dc"
DD="ntsclone --restore-image --overwrite /dev/sda1 -"
$DR | $GPG | $GZ | $DD

← Previous ↑ Home ↑ Live Systems Next →

Related

Wiki: Live Systems

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.