How to Get TinyTinyRSS Categories

in

If you are using TinyTinyRSS and want a hierarchic subscription list you need to explicitely enable categories from the preferences! Ensure to enable the "Enables feed categories" check box. Then save and open the "Feeds" tab which now allows you to add categories. All existing feeds are presented in category "Uncategorized".

Preferences Screenshot

Missing Roles in "knife node show" Output

Sometimes the knife output can be really confusing:

$ knife node show myserver
Node Name:   myserver1
Environment: _default
FQDN:        myserver1
IP:          
Run List:    role[base], role[mysql], role[apache]
Roles:       base, nrpe, mysql
Recipes:     [...]
Platform:    ubuntu 12.04
Tags:        

Noticed the difference in "Run List" and "Roles"? The run list says "role[apache]", but the list of "Roles" has no Apache. This is because of the role not yet being run on the server. So a

ssh root@myserver chef-client

Solves the issue and Apache appears in the roles list.

The learning: do not use "knife node show" to get the list of configured roles!

How To Debug PgBouncer

When you use Postgres with pgbouncer when you have database problems you want to have a look at pgbouncer too. To inspect pgbouncer operation ensure to add at least one user you defined in the user credentials file (e.g. on Debian per-default /etc/pgbouncer/userlist.txt) to the "stats_users" key in pgbouncer.ini:

stats_users = myuser

Now reload pgbouner and use this user "myuser" to connect to pgbouncer with psql by requesting the special "pgbouncer" database:

psql -p 6432 -U myuser -W pgbouncer

At the psql prompt list the supported pgbouncer commands with

SHOW HELP;

PgBouncer will present all statistics and configuration options:

pgbouncer=# SHOW HELP;
NOTICE:  Console usage
DETAIL:  
	SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|VERSION
	SHOW STATS|FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM
	SET key = arg
	RELOAD
	PAUSE []
	SUSPEND
	RESUME []
	SHUTDOWN

The "SHOW" commands are all self-explanatory. Very useful are the "SUSPEND" and "RESUME" commands when you use pools.

MySQL Dump Skip Event Table

If your MySQL backup tool or self-written script complains about an event table than you have run into an issue caused by newer MySQL versions (>5.5.30) that introduced a new table "events" in the internal schema.

If you run into this you need to decide wether you want to include or exclude the new events table when dumping your database.

To skip: Due to a MySQL bug #68376 you have two choices. You can check documentation and add the logical option

--skip-events

which will cause the event table not to be exported. But the warning won't go away. To also get rid of the warning you need to use this instead:

--events --ignore-table=mysql.events

And of course you can also choose just to dump the events table: Add the option

--events

to your "mysqldump" invocation. If you use a tool that invokes "mysqldump" indirectly check if the tool allows to inject additional parameters.

/etc/sudoers.d Pitfalls

From the sudoers manpage:

[...] sudo will read each file in /etc/sudoers.d, skipping file names 
that end in ~ or contain a . character to avoid causing problems with 
package manager or editor temporary/backup files. [...]

This mean if you have a Unix user like "lars.windolf" you do not want to create a file

/etc/sudoers.d/lars.windolf

The evil thing is neither sudo nor visudo warns you about the mistake and the rules just do not work. And if you have some other definition files with the same rule and just a file name without a dot you might wonder about your sanity :-)

How to Get Flash Working with WebkitGTK3

With the switch to GTK3 all Webkit using applications like Epiphany, Liferea, devhelp, yelp and others lost Flash support. The reason is that Linux-Flash is GTK2 only! And of course there won't be new releases from Adobe ever. So we have the following compatibility situation for Liferea

Release
Line
Uses Flash Status
1.6
1.8
GTK2 + WebkitGTK2 any native Flash Works
1.10 GTK3 + WebkitGTK3 v1.8 32bit native Flash Broken
1.10 GTK3 + WebkitGTK3 v1.8 64bit native Flash Broken
1.10 GTK3 + WebkitGTK3 v1.8 32bit Flash + nspluginwrapper Works
1.10 GTK3 + WebkitGTK3 v2.0 any native Flash Works

The WebkitGTK+ solution for the Flash problem was implemented in version 2.0 by having a second process linked against GTK2 to run browser plugins while Webkit itself is linked to GTK3. This makes Flash work again.

But the currently widely distributed WebkitGTK3 v1.8 does not have this feature yet and fails to use the native flash.

nspluginwrapper Workaround

The only workaround is to use nspluginwrapper to run the 32bit version of Flash. This is guaranteed to work on 64bit platforms. It might not work on 32bit hardware, sometimes also because nspluginwrapper is not available there. The steps to install it are:

  1. Install nspluginwrapper. On Debian
    apt-get install nspluginwrapper
  2. Download 32bit Flash .tar.gz from Adobe
  3. Extract /usr files according to the Adobe instructions
  4. In the tarball directory run
    nspluginwrapper -i -a -v -n libflashplayer.so

    to install the plugin

Now all WebkitGTK3 using applications should be able to run Flash. Ensure to restart them and check command line output for any plugin errors.

Upgrading to WebkitGTK3 2.0

If you can try upgrading to WebkitGTK3 2.0 (e.g. Debian Experimental).

Liferea Sync Support Status (TinyTinyRSS, TheOldReader, Feedly, AOL Reader, Digg Reader)

There is slow progress in the world of news aggregation services. Since the last post on possible sync implementations I was able to submit API access requests for AOL Reader and Feedly. There is a chance that the request for AOL Reader will be successful. The unexpected thing with AOL is that they require OAuth2 authentication which Liferea does not yet support. Still it will be possible to add it.

My clear favourites are still AOL and Digg. With two 3rd party hosters and one self-hosted solution (TinyTinyRSS) Liferea would provide a reasonable set of choices.

Name API Status Implementation Status
Google Reader Deprecated Implemented, Now Useless
TinyTinyRSS Published. Implemented, Stable
TheOldReader Published. Implemented, Experimental
AOL Reader Published API Key Requested
Digg Reader Planned 1) %
NewsBlur Published Not Planned.
Feedly Secret 2) API Access Requested

1) Digg has announced they will be implementing Google Reader API and hope is they open it up
2) Feedly has announced there will be a public API with v17

TheOldReader Sync Implemented

I originally intended to make AOL Reader work, but failed due to the undocumented and propably not yet published authentication API. I'll ask AOL about it, but if anyone knows please drop me a mail.

So I could not work on AOL Reader, so I choose to work on TheOldReader (http://theoldreader.com) which I found very pleasant and stable. The API is close to Google Reader with the only limitation that it sometimes only has JSON support and no XML. As we use JSON already for TinyTinyRSS synching I could build on existing code.

So git master now has working experimental TheOldReader support!

This will be released soon with the initial 1.10 release.

So Liferea now has the following online synchronization support:

Name Status Import Google Reader
Google Reader Deprecated %
TinyTinyRSS Implemented, Stable No
TheOldReader Implemented, Experimental No
AOL Reader Planned, API not complete Yes
Digg Reader Planned, API not public Yes
NewsBlur Not Planned, API too different Yes
Feedly I registered Liferea as interested Client Yes

On the long term I'd like to support to new Google Reader clones to give Liferea users some choice along with TinyTinyRSS for the self-hosting choice.

Detecting a Dark Theme in GTK

When implementing an improved unread news counter rendering for Liferea if found it necessary to detect wether there is a light or dark GTK theme active. The reason for this was that I didn't want to use the foreground and background colors which are often black and something very bright. So instead from the GtkStyle struct which looks like this

typedef struct {
  GdkColor fg[5];
  GdkColor bg[5];
  GdkColor light[5];
  GdkColor dark[5];
  GdkColor mid[5];
  GdkColor text[5];
  GdkColor base[5];
  GdkColor text_aa[5];          /* Halfway between text/base */
[...]

I decided to use the "dark" and "bg" colors with "dark" for background and "bg" for the number text. For a light standard theme this results mostly to a white number on some shaded background. This is how it looks (e.g. the number "4" behind the feed "Boing Boing"):

Inverse Colors For Dark Theme Are Hard!

The problem is when you use for example the "High Contrast Inverse" dark theme. Then "dark" suddenly is undistinguishable from "bg" which makes sense of course. So we need to choose different colors with dark themes. Actually the implementation uses "bg" as foreground and "light" for background.

How to Detect Dark Themes

To do the color switching I first googled for a official GTK solution but found none. If you know of one please let me know! For the meantime I implemented the following simple logic:

	gint		textAvg, bgAvg;

	textAvg = style->text[GTK_STATE_NORMAL].red / 256 +
	        style->text[GTK_STATE_NORMAL].green / 256 +
	        style->text[GTK_STATE_NORMAL].blue / 256;

	bgAvg = style->bg[GTK_STATE_NORMAL].red / 256 +
	        style->bg[GTK_STATE_NORMAL].green / 256 +
	        style->bg[GTK_STATE_NORMAL].blue / 256;

	if (textAvg > bgAvg)
		darkTheme = TRUE;

As "text" color and "background" color should always be contrasting colors the comparison of the sum of their RGB components should produce a useful result. If the theme is a colorful one (e.g. a very saturated red theme) it might sometimes cause the opposite result than intended, but still background and foreground will be contrasting enough that the results stays readable, only the number background will not contrast well to the widget background.

For light or dark themes the comparison should always work well and produce optimal contrast. Now it is up to the Liferea users to decide wether they like it or not.

Most Important Redis Commands for Sysadmins

When you encounter a Redis instance and you quickly want to learn about the setup you just need a few simple commands to peak into the setup. Of course it doesn't hurt to look at the official full command documentation, but below is a listing just for sysadmins.

Accessing Redis

First thing to know is that you can use "telnet" (usually on default port 6397)

telnet localhost 6397

or the Redis CLI client

redis-cli

to connect to Redis. The advantage of redis-cli is that you have a help interface and command line history.

Scripting Redis Commands

For scripting just pass commands to "redis-cli". For example:

$ redis-cli INFO | grep connected
connected_clients:2
connected_slaves:0
$

Server Statistics

The statistics command is "INFO" and will give you an output as following:

$ redis-cli INFO
redis_version:2.2.12
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
process_id:8353
uptime_in_seconds:2592232
uptime_in_days:30
lru_clock:809325
used_cpu_sys:199.20
used_cpu_user:309.26
used_cpu_sys_children:12.04
used_cpu_user_children:1.47
connected_clients:2
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:6596112
used_memory_human:6.29M
used_memory_rss:17571840
mem_fragmentation_ratio:2.66
use_tcmalloc:0
loading:0
aof_enabled:0
changes_since_last_save:0
bgsave_in_progress:0
last_save_time:1371241671
bgrewriteaof_in_progress:0
total_connections_received:118
total_commands_processed:1091
expired_keys:441
evicted_keys:0
keyspace_hits:6
keyspace_misses:1070
hash_max_zipmap_entries:512
hash_max_zipmap_value:64
pubsub_channels:0
pubsub_patterns:0
vm_enabled:0
role:master
db0:keys=91,expires=88

Changing Runtime Configuration

The command

CONFIG GET *

gives you a list of all active configuration variables you can change. The output might look like this:

redis 127.0.0.1:6379> CONFIG GET *
 1) "dir"
 2) "/var/lib/redis"
 3) "dbfilename"
 4) "dump.rdb"
 5) "requirepass"
 6) (nil)
 7) "masterauth"
 8) (nil)
 9) "maxmemory"
10) "0"
11) "maxmemory-policy"
12) "volatile-lru"
13) "maxmemory-samples"
14) "3"
15) "timeout"
16) "300"
17) "appendonly"
18) "no"
19) "no-appendfsync-on-rewrite"
20) "no"
21) "appendfsync"
22) "everysec"
23) "save"
24) "900 1 300 10 60 10000"
25) "slave-serve-stale-data"
26) "yes"
27) "hash-max-zipmap-entries"
28) "512"
29) "hash-max-zipmap-value"
30) "64"
31) "list-max-ziplist-entries"
32) "512"
33) "list-max-ziplist-value"
34) "64"
35) "set-max-intset-entries"
36) "512"
37) "slowlog-log-slower-than"
38) "10000"
39) "slowlog-max-len"
40) "64"

Note that keys and values are alternating and you can change each key by issuing a "CONFIG SET" command like:

CONFIG SET timeout 900

Such a change will be effective instantly. When changing values consider also updating the redis configuration file.

Multiple Databases

Redis has a concept of separated namespaces called "databases". You can select the database number you want to use with "SELECT". By default the database with index 0 is used. So issuing

redis 127.0.0.1:6379> SELECT 1
OK
redis 127.0.0.1:6379[1]>

switches to the second database. Note how the prompt changed and now has a "[1]" to indicate the database selection.

To find out how many databases there are you might want to run redis-cli from the shell:

$ redis-cli INFO | grep ^db
db0:keys=91,expires=88
db1:keys=1,expires=0

Dropping Databases

To drop the currently selected database run

FLUSHDB

to drop all databases at once run

FLUSHALL

Checking for Replication

To see if the instance is a replication slave or master issue

redis 127.0.0.1:6379> INFO
[...]
role:master

and watch for the "role" line which shows either "master" or "slave".

Starting with version 2.8 the "INFO" command also gives you per slave replication status looking like this

slave0:ip=127.0.0.1,port=6380,state=online,offset=281,lag=0

Enabling Replication

If you quickly need to set up replication just issue

SLAVEOF <IP> <port>

on a machine that you want to become slave of the given IP. It will immediately get values from the master. Note that this instance will still be writable. If you want it to be read-only change the redis config file (only available in most recent version, e.g. not on Debian).

To revert the slave setting run

SLAVEOF NO ONE

Dump Database Backup

As Redis allows RDB database dumps in background, you can issue a dump at any time. Just run:

BGSAVE

When running this command Redis will fork and the new process will dump into the "dbfilename" configured in the Redis configuration without the original process being blocked. Of course the fork itself might cause an interruption.

Use "LASTSAVE" to check when the dump file was last updated. For a simple backup solution just backup the dump file.

If you need a synchronous save run "SAVE" instead of "BGSAVE".

Listing Connections

Starting with version 2.4 you can list connections with

CLIENT LIST

and you can terminate connections with

CLIENT KILL <IP>:<port>

Monitoring Traffic

The propably most useful command compared to memcached where you need to trace network traffic is the "MONITOR" command which will dump incoming commands in real time.

redis 127.0.0.1:6379> MONITOR
OK
1371241093.375324 "monitor"
1371241109.735725 "keys" "*"
1371241152.344504 "set" "testkey" "1"
1371241165.169184 "get" "testkey"

Checking for Keys

If you want to know if an instance has a key or keys matching some pattern use "KEYS" instead of "GET" to get an overview.

redis 127.0.0.1:6379> KEYS test*
1) "testkey2"
2) "testkey3"
3) "testkey"

On production servers use "KEYS" with care as you can limit it and it will cause a full scan of all keys!

Syndicate content Syndicate content