Smokes your problems, coughs fresh air.

Author: halfgaar (Page 11 of 26)

Halfgaar is Wiebe. Wiebe is a contributing author on this weblog. He also has a lot of stuff (such as long, in-depth articles) on his personal website.

Wiebe's day job is as a senior software developer and system administrator at YTEC.

In his free time, he built the free, open-source FlashMQ software. Together with Jeroen and Rowan, he is now building a managed MQTT hosting business around his open masterpiece.

Often used Eagle parts and packages

Everytime I work with Eagle, I need to dig deep to remember which libraries and packages I used. Here’s a memory aid:

  • Pinheaders for flatcable: library con-lstb
  • Pinheaders for PC-fan like connectors: con-molex
  • Big single pin connectors: testpad or wirepad.
  • Fuse holder: lib: fuse, package: SH22,5A
  • Connector ‘printkroonsteen’: lib con-ptr500, part ak500/3 ak500/2 etc
  • Smaller footprint for high current diode: package diode, part DIODE-DO41-7.6

More to come…

Adding a disk to a RAID5 array on a 3Ware array with tw_cli

I wanted to know if I could extend the size of a RAID5 array on the 3Ware 9650SE, so I tried something.

I first had this:

# tw_cli /c0 show
Unit  UnitType  Status         %RCmpl  %V/I/M  Stripe  Size(GB)  Cache  AVrfy
------------------------------------------------------------------------------
u0    RAID-5    OK             -       -       256K    5587.9    RiW    ON
 
VPort Status         Unit Size      Type  Phy Encl-Slot    Model
------------------------------------------------------------------------------
p0    OK             u0   1.82 TB   SATA  0   -            ST32000542AS
p1    OK             u0   1.82 TB   SATA  1   -            ST32000542AS
p2    OK             u0   1.82 TB   SATA  2   -            ST32000542AS
p3    OK             u0   1.82 TB   SATA  3   -            ST32000542AS
p4    OK             -    1.82 TB   SATA  4   -            ST32000542AS
 
Name  OnlineState  BBUReady  Status    Volt     Temp     Hours  LastCapTest
---------------------------------------------------------------------------
bbu   On           Yes       OK        OK       OK       0      xx-xxx-xxxx

A 4 disk raid 5 and one extra disk.

Then I did this:

# tw_cli /c0/u0 migrate type=raid5 disk=4
Sending migration message to /c0/u0 ... Done.

Then I have this:

# tw_cli /c0/u0 show
 
Unit     UnitType  Status         %RCmpl  %V/I/M  Port  Stripe  Size(GB)
------------------------------------------------------------------------
u0       Migrator  MIGRATING      -       0%      -     -       -
 
su0      RAID-5    OK             -       -       -     256K    5587.9
su0-0    DISK      OK             -       -       p0    -       1862.63
su0-1    DISK      OK             -       -       p1    -       1862.63
su0-2    DISK      OK             -       -       p2    -       1862.63
su0-3    DISK      OK             -       -       p3    -       1862.63
su0/v0   Volume    -              -       -       -     -       50
su0/v1   Volume    -              -       -       -     -       5537.9
 
du0      RAID-5    OK             -       -       -     256K    7450.54
du0-0    DISK      OK             -       -       p0    -       1862.63
du0-1    DISK      OK             -       -       p1    -       1862.63
du0-2    DISK      OK             -       -       p2    -       1862.63
du0-3    DISK      OK             -       -       p3    -       1862.63
du0-4    DISK      OK             -       -       p4    -       1862.63
du0/v0   Volume    -              -       -       -     -       N/A
du0/v1   Volume    -              -       -       -     -       N/A

su0 and du0 are probably source and destination, giving me a new and bigger u0 at the end. But this is going to take a week to migrate, so I won’t know for a while… (edit: I contacted 3Ware support and they said the change in size is only seen after driver reload, which means a reboot in most cases).

Create a remote repository and branch with bzr

Create a shared remote bzr repository:

bzr init-repo --no-trees sftp://development@server.example.com/srv/bzr/project/
bzr init sftp://development@server.example.com/srv/bzr/project/trunk
bzr co sftp://development@server.example.com/srv/bzr/project/trunk project 

The docs all create a repos in /srv/bzr in which branches are created, but to me, it seems illogical to put all your projects in one repository. So, I create one per project.

Executing system commands from PHP with SUID executable.

If you want to execute system commands from something like PHP, you need a SUID executable which you can call from your PHP scripts. This is such a script. It could be extended to support parameters for the commands you want to execute, but that would be an enormous security risk, because then anybody can execute any command. If you need something as flexible as that, you need to think about adding some kind of security restrictions, like a list of allowed commands.

When writing this, it occurred to me how unnecessary this all is. I will explain below. First, I will describe the old way.

Here is the c source code, as written for our backup script, bsbackup.sh:

// Wrapper for the bsbackup.sh shell script, to be able to run it as root when
// started from a webserver, for example. Set the resulting executable to SUID
// root.
 
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
 
int main(int argc, char *argv[], char *envp[])
{
    int set_uid_result;
    int effective_user_id;
    int execute_script_error;
    char* script;
 
    effective_user_id = geteuid();
 
    // Set real and effective user ID
    set_uid_result = setreuid(effective_user_id, effective_user_id);
 
    if (set_uid_result != 0)
    {
        printf("Failed to set user id\n");
        return 1;
    }
 
    script = "/usr/local/sbin/bsbackup.sh";
 
    // This does not return on success.
    execve(script, argv, envp);
    execute_script_error = errno;
 
    // Show a fancy error message.
    error(execute_script_error, execute_script_error, script);
 
    // Shouldn't be necceary, but you never know.
    return 1;
}

To compile:

gcc -o bsbackup bsbackup.c

You can then run this inside PHP:

// The 2>&1 makes all error messages appear on stdout, for easy capturing.
passthru('/usr/local/sbin/bsbackup usb_backup 2>&1');

As I said, when writing this, it all became very clear to me that it is quite useless. One can also install sudo, run visudo and put this in (assuming your webserver runs as www-data, like on (Debian and Ubuntu):

www-data ALL = NOPASSWD: /usr/local/sbin/bsbackup.sh

Then in PHP, just run this:

passthru('sudo /usr/local/sbin/bsbackup.sh usb_backup 2>&1');

I haven’t tested whether specifying the parameters after the script in the passthru actually works, but I think so. If not, you can just write a wrapper script around the command you’re going to execute.

See what you like best 🙂

Configuring a Power DNS superslave server

Power DNS, as opposed to Bind, has the option to be a superslave. This means that it will initiate any zone transfer from trusted hosts, avoiding the need to configure each zone on both master and slave.

Power DNS has separate back-ends, of which you must choose one. I chose mysql, and I use the generic mysql engine (this is different, and better, than normal MySQL, or something like that…).

First install Power DNS:

aptitute -P install pdns-server pdns-backend-mysql

Then create a database and user:

create database pdns character set utf8;
grant all on pdns.* to 'pdns'@'localhost' identified by 'password';

Then create this schema (found it in the Power DNS docs):

create table domains (
 id    INT auto_increment,
 name    VARCHAR(255) NOT NULL,
 master    VARCHAR(128) DEFAULT NULL,                                                                                                                    
 last_check  INT DEFAULT NULL,                                                                                                                           
 type    VARCHAR(6) NOT NULL,                                                                                                                            
 notified_serial INT DEFAULT NULL,                                                                                                                       
 account         VARCHAR(40) DEFAULT NULL,                                                                                                               
 primary key (id)                                                                                                                                        
)type=InnoDB;                                                                                                                                            
                                                                                                                                                         
CREATE UNIQUE INDEX name_index ON domains(name);                                                                                                         
                                                                                                                                                         
CREATE TABLE records (                                                                                                                                   
  id              INT auto_increment,                                                                                                                    
  domain_id       INT DEFAULT NULL,
  name            VARCHAR(255) DEFAULT NULL,
  type            VARCHAR(6) DEFAULT NULL,
  content         VARCHAR(255) DEFAULT NULL,
  ttl             INT DEFAULT NULL,
  prio            INT DEFAULT NULL,
  change_date     INT DEFAULT NULL,
  primary key(id),
  CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE
)type=InnoDB;
 
CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
 
create table supermasters (
  ip VARCHAR(25) NOT NULL, 
  nameserver VARCHAR(255) NOT NULL, 
  account VARCHAR(40) DEFAULT NULL
);
 
GRANT SELECT ON supermasters TO pdns;
GRANT ALL ON domains TO pdns;
GRANT ALL ON records TO pdns;

Then create /etc/powerdns/pdns.d/pdns-mysql-backend with this in it:

launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=pdns
gmysql-password=password
gmysql-dbname=pdns

Then insert a supermaster:

insert into supermasters values ('1.2.3.4','ns1.example.com','identifiername');

Lastly, don’t forget to enable slave mode in /etc/powerdns/pdns.conf:

slave=yes

Roos Roos Loon installation and configuration weirdness

Because Roos Roos Loon has always been an application that stored its data files in the program files directory, special measures had to be taken to make sure the data files are backed up. I wanted them on a network drive. To that end, I always installed the entire program on a network drive.

But I just found out that Loon 2010 had put its data files somewhere in Documents and Settings, even though the program was stored on the network. I guess this was the first version that separated the data and program paths. However, it did so without telling me. The reason it didn’t tell me, might be because of a bug I found in 2011.

For 2010 I just changed a regkey in “currentuser\software\vb and vba\Roos Roos” or something. 2011 I was installing on another machine and I decided to reinstall it to have it nicely from scratch.

And that’s were it started to be weird. Where it asked me where to put the data files the first time I had installed it, it didn’t this time, even when I removed the aforementioned regkey on this computer. It didn’t even want to start after the reinstall anymore, until I pointed it to the 2011 data files I had deleted when removing the program. I would think it would recreate them, as they were empty anyway, but it didn’t.

I think Loon 2011 not asking for the datapath and Loon 2010 not doing it either, may be related. Perhaps if there already is Roos Roos stuff on the machine, it skips that question (being a bug).

Therefore, I suspect that when 2012 is released, it may put its datafiles in the datapath for 2011. I have to watch that.

Finding junction files in Windows 7 and exclude them with DeltaCopy

Windows 7 has a sort of hard link, a junction file, which it uses to link the old location “Documents and Settings” to /Users/. Because of all this junctioning, you can’t just copy files with a Cygwin program like Deltacopy, because it will hang in infinite loop and copy a whole lot of things twice.

To identify junction files, run:

dir /AL /s

Here is an example exclude list for deltacopy for a standard windows 7 machine. Path names are specified assuming every user dir is supplied as separate dir to copy (because there are references to root, like ‘/Mijn documenten’:

--delete-excluded --exclude "/Application Data" --exclude "**/Downloads" --exclude "**/AppData/Local/Application Data" --exclude "/Local Settings" --exclude "**/Temporary Internet Files" --exclude "**/Flash Player" --exclude "**/Temp" --exclude "**/VirtualStore" --exclude "NTUSER.DAT*" --exclude "UsrClass.dat*" --exclude "ntuser.dat*" --exclude "parent.lock" --exclude "/Mijn documenten"  --exclude "/Mijn afbeeldingen" --exclude "/Mijn muziek" --exclude "/Mijn video's"

The ‘Mijn Documenten’ and such is a link to other dirs, so it doesn’t skip them. Be sure not to use these statements when running this on Windows XP…

Bash script template

#!/bin/bash
#
# Author: Wiebe Cazemier (wiebe@halfgaar.net)
#
# Template bash script, for when you need something overengineerd :)
 
# Hack prevention
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
 
# Error codes
wrong_params=5
interrupted=99
default_error=1
 
# Function to echo in color. Don't supply color for normal color.
echo_color()
{
  message="$1"
  color="$2"
 
  red_begin="\033[01;31m"
  green_begin="\033[01;32m"
  yellow_begin="\033[01;33m"
  color_end="\033[00m"
 
  # Set color to normal when there is no color
  [ ! "$color" ] && color_begin="$color_end"
 
  if [ "$color" == "red" ]; then
    color_begin="$red_begin"
  fi
 
  if [ "$color" == "green" ]; then
    color_begin="$green_begin"
  fi
 
  if [ "$color" == "yellow" ]; then
    color_begin="$yellow_begin"
  fi
 
  echo -e "${color_begin}${message}${color_end}"
}
 
end()
{
  message="$1"
  exit_status="$2"
 
  if [ -z "$exit_status" ]; then
    exit_status="0"
  fi
 
  if [ ! "$exit_status" -eq "0" ]; then
    echo_color "$message" "red"
  else
    echo_color "$message" "green"
  fi
 
  if [ "$exit_status" -eq "$wrong_params" ]; then
    dohelp
  fi
 
  exit $exit_status
}
 
# Define function to call when SIGTERM is received
trap "end 'Interrupted' $interrupted" 1 2 3 15
 
dohelp()
{
  echo ""
  echo "Example script"
  echo ""
  echo "help = todo"
 
  # Exit because you don't want the script to do anything after displaying help
  exit 
}
 
 
while [ -n "$*" ]; do
  flag=$1
  value=$2
 
  case "$flag" in
    "--option1")
      option1=$value
      shift
    ;;
    "--help")
      dohelp
    ;;
    "--")
      break
    ;;
    *)
      end "unknown option $flag. Type --help" "$wrong_params"
    ;;
  esac
 
  shift
done
 
if [ -z "$option1" ]; then
  end "option1 not given" $wrong_params
fi

« Older posts Newer posts »

© 2024 BigSmoke

Theme by Anders NorenUp ↑