Wednesday, December 30, 2015

My Adventure With Docker on an Early Version Raspberry Pi: Part Two

Meet the Pi

This Pi I use for development and testing may be on the short list of systems to replace with one of the new Pi 2's; it has 512MB of RAM and an ARM 6 compatible processor running 700 MHz (according to cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq )

I also attached a 500GB USB drive because an SD card was just too small for testing applications and storing Git repositories.

This is my lunchbox development system. It literally lives in a little lunchbox; a take-home container for leftover food. I cut a small hole in it through which power, video and network cables are passed. Outside the container is a powered USB hub for the external mouse and keyboard. Most of the system is safely contained in the portable container. At one point I thought it would be nifty to attach a battery and mini-LCD to the box to create a really portable developer system. But that's a different topic.

The Pi is upgraded to the latest Raspbian from Wheezy to Jessie.

uname -a
Linux nyhq-bms-pi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux

I should note that the Pi has quite a bit of information gleaned from a Pi-specific command...

vcgencmd commands
commands="vcos, ap_output_control, ap_output_post_processing, vchi_test_init, vchi_test_exit, pm_set_policy, pm_get_status, pm_show_stats, pm_start_logging, pm_stop_logging, version, commands, set_vll_dir, led_control, set_backlight, set_logging, get_lcd_info, set_bus_arbiter_mode, cache_flush, otp_dump, test_result, codec_enabled, get_camera, get_mem, measure_clock, measure_volts, scaling_kernel, scaling_sharpness, get_hvs_asserts, measure_temp, get_config, hdmi_ntsc_freqs, hdmi_adjust_clock, hdmi_status_show, hvs_update_fields, pwm_speedup, force_audio, hdmi_stream_channels, hdmi_channel_map, display_power, read_ring_osc, memtest, dispmanx_list, get_rsts, schmoo, render_bar, disk_notify, inuse_notify, sus_suspend, sus_status, sus_is_enabled, sus_stop_test_thread, egl_platform_switch, mem_validate, mem_oom, mem_reloc_stats, file, vctest_memmap, vctest_start, vctest_stop, vctest_set, vctest_get"

That command, vcgencmd,  can give you information about your Raspberry Pi hardware speed, memory, temperature, etc. (handy tip!)

Let's Install Docker!

Most installations of Docker are running on Intel/Intel-compatible processors; Raspberries are running on ARM processors. Therefore Docker and Docker images on the Pi must be compiled for ARM processors. Therefore we need a Pi-specific Docker install. I adapted the steps from https://github.com/umiddelb/armhf/wiki/Get-Docker-up-and-running-on-the-RaspberryPi-(ARMv6)-in-four-steps-(Wheezy)

curl -sSL http://downloads.hypriot.com/docker-hypriot_1.9.1-1_armhf.deb >/tmp/docker-hypriot_1.9.1-1_armhf.deb
sudo dpkg -i /tmp/docker-hypriot_1.9.1-1_armhf.deb
rm -f /tmp/docker-hypriot_1.9.1-1_armhf.deb
sudo sh -c 'usermod -aG docker $SUDO_USER'
sudo systemctl enable docker.service

At that point I rebooted. Restarting is most likely not necessary but it helps put my mind at rest to test if the service comes back up at reboot.

After logging back in, I tested with a generic Pi image.

docker run -i -t resin/rpi-raspbian

That gave the following output:

Unable to find image 'resin/rpi-raspbian:latest' locally
latest: Pulling from resin/rpi-raspbian
26ee9e029db4: Pull complete
7fd99c655462: Pull complete
74aa4ff44e2e: Pull complete
703e52d2c09e: Pull complete
1994fd62cbe1: Pull complete
acbda1fdb360: Pull complete
e97a8531a526: Pull complete
Digest: sha256:ba2f4ba0272e3de62954456792f65fd7329d8ac306477667afbf04cd7360bc61
Status: Downloaded newer image for resin/rpi-raspbian:latest
root@cbe3d48cb02a:/#

It works! The -i sets the instance to interactive, and the -t connects it to a pseudo-tty. resin/rpi-raspbian is the rpi-raspbian image from the resin repository. Basically -i -t is why I was dropped into a command line inside the Docker container of resin/rpi-raspbian when it was done building.

What About Networking?

At this point it seemed the container mostly works. Networking was acting up. But how to see network functions? Docker images are very stripped down, running the minimal software for running your application. That helps trim the resource footprint of the running instances on your host. Unfortunately this also means that tools like Ping were missing from the image. Fortunately theres a way to copy files between the host and the containers.

docker ps

...lists the image names of running Docker instances. You'll need the container ID. Also,

docker network ls

...confirmed that Docker saw a bridge, null, and host network available to containers. Next I created a "staging ground" for files that would be used to batch into a Docker build.

mkdir einal_docker
cd einal_docker

From a session on the host (outside the container) I copied over files I wanted to insert into the running Docker instance. If I re-ran the docker run command, all my changes and alterations go away. I copied ifconfig to my staging directory, then while in the host I ran

docker cp ./ifconfig <containerID>:/home

...then from inside the Docker container I ran:

cd /home
./ifconfig

...and that gave these results:

root@<containerID>:/home# ./ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:828 (828.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

That IP address isn't within our networks, so Docker must be running with some kind of NAT. From what I could tell it wasn't hitting our DNS servers because it couldn't use apt-get to update from repos, instead throwing lookup errors.

To test this more, I copied Ping over. From the host:

cp /bin/ping .
docker cp ./ping <containerID>:/home

All attempts to ping returned a host unreachable error. ARGH! I closed out of the container using exit.

Let's Try Host Networking

Host networking can be explicitly set from the command line.

docker run --net="host" -i -t resin/rpi-raspbian

From the host, I ran "docker ps" and re-copied the ifconfig and ping executables from my staging directory into the new container. This showed more promising results!

docker0   Link encap:Ethernet  HWaddr 02:42:07:34:b7:bb
          inet6 addr: <clip> Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:39 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2208 (2.1 KiB)  TX bytes:648 (648.0 B)

eth0      Link encap:Ethernet  HWaddr b8:27:eb:60:50:ae
          inet addr:<clip>  Bcast:<clip> Mask:255.255.255.0
          inet6 addr: <clip>/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:160416 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5059 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:67957668 (64.8 MiB)  TX bytes:684671 (668.6 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Now the Docker container was sharing my Pi's network address, pinging addresses worked, and apt-get was able to run updates!

EINAL Likes Logs, and so do I: Persistent Data Storage

I like to log what my applications do. EINAL keeps track of files it deleted and activity it experiences, but Docker instances are ephemeral. If it's not logging to an outside database or data store, data will be lost.

The Docker answer to this is a Volume, where data is stored on the host in a persistent location. I exited the running container and tried launching a new one with a Volume flag specified.

docker run --net="host" -v /var/logs -i -t resin/rpi-raspbian

After that successfully ran, I ran the docker ps command to get the new container ID, then ran:

docker inspect <containerID>

That dumped quite a bit of information, but here was the important bit:

   "Mounts": [
        {
            "Name": "fde7c2e91bfacc32e0c41817a89a1f386a746cb203a8641940b7a7b9c3289847",
            "Source": "/var/lib/docker/volumes/fde7c2e91bfacc32e0c41817a89a1f386a746cb203a8641940b7a7b9c3289847/_data",
            "Destination": "/var/logs",
            "Driver": "local",
            "Mode": "",
            "RW": true
        }
    ],

This says that the directory /var/logs (which I specified in the docker run command) inside the Docker image is linked to the directory on the host starting with /var/lib/docker/volumes (next to the "source" label.) Source is on the host, destination is in the container. When the container stops running, the data in the source directory stays intact while everything else disappears. And yes, logs are actually in /var/log, not /var/logs. The directory was created automatically in the container so both appeared.

Because of ownership permissions, I had to use "sudo ls" to view the contents of the directory; it was empty. From inside the container, I ran:

cd /var/logs
echo “hello” > test.txt

Then on the host, I re-checked the directory; test.txt was found. I exited the running container ("docker ps" showed no running instances) and re-checked the host directory. Test.txt was still there.

Can I specify the destination on the host where volume data is stored? Turns out I can.

docker run --net="host" -v /mnt/mydrive/projects_docker/einal_docker/einal_docker_logs:/var/logs -i -t 

I created another test file inside the /var/logs directory inside the container, and this time it appeared in the /mnt/mydrive... directory! The specification of which directory is in the container and which is on the host is a little backwards to my way of thinking, but this works.

Let's Change Where Docker Stores Stuff

The SD card in the Pi isn't huge, and Docker is storing much of its data in /var/lib/docker. I have a larger drive mounted by default in /mnt/mydrive. I wanted to change Docker to store stuff on the big drive.

I removed the temporary test stuff I'd made so far and created a new directory on the large drive.

sudo mkdir /mnt/mydrive/docker_rootdir
sudo chown pi:pi /mnt/mydrive/docker_rootdir
sudo chmod 777 /mnt/mydrive/docker_rootdir

Docker keeps a list of configuration options in /etc/default/docker. I opened it up and looked for the line beginning with "DOCKER_OPTS=". In that list I added "--graph=/mnt/mydrive/docker_rootdir" and restarted the machine. The options in that file are passed to the Docker daemon and while a service restart should force it to re-read the options, I still like the restart to make sure everything comes up properly if the system shuts down.

I created another container instance with "docker run --net="host" -v /var/logs -i -t resin/rpi-raspbian" and re-checked, using "docker ps" and "docker inspect <containerID>", where it was storing files. Docker was now using my external drive!

After confirming Docker was switched over I removed the old storage files using

sudo rm -fr /var/lib/docker

In the next post I "Dockerize" EINAL!

Monday, December 28, 2015

My Adventure With Docker on an Early Version Raspberry Pi: Part One

Background

I've been working on a small program called EINAL (Email Is Not Always Loved.) The program logs into Gmail-based accounts and matches strings with senders or subject lines and deletes them. Why? Because while Gmail has filters that will send emails to the trash, there's no built-in mechanisms for actually removing the email. 

For some people that's fine. They archive the mail or stick it into the trash and ignore it. Then there are people like me who often has to check on something in the trash because someone had a question, and I don't use the Gmail interface where everything is found via a query and email storage is more or less modeled after the method an eight year old uses to organize his toys in the middle of the living room. Not to mention that I hate having extra storage taken on my various mail clients and my phone's email client when I literally have status emails several times an hour popping into my mailbox.

EINAL is pretty self-contained; it creates a subdirectory where the login credentials, subject lines and email sender lines are stored. Then there's another subdirectory under it where EINAL stores a logfile of activity and log of deleted emails, should I need to refer to a subject line that no longer exists in my mailbox. Because EINAL is written in Go, I don't need to worry about external dependencies.

The Goal

I created EINAL with two modes; one for single runs (good for testing and tuning, configuring the accounts to log into, or modifying the search strings) and one for "background use" where the application waits for you to log into it via SSH and enter the decryption phrase. At that point it will begin checking every X number of minutes for messages to delete from the mail accounts.

There are a few ways I pictured the "background" operation to work.

1) Run it as a daemon on a laptop; my personal system, my work computer, or, because EINAL was written in Go and was portable, perhaps my development Raspberry Pi computer at the office.

2) Run it as a user-application at login; I was thinking of trying to get it to run on one of my Macs as a startup application. 

3) Run it as an application in a VM.

4) Run it as a detached-from-terminal process on the dev/testing Pi.

Each had potential drawbacks.

1) If you create a daemon the "correct way", you know that it's a PITA to have the application properly reply to signals and behave in the weird environment processes find themselves in once they move from the world of a terminal to the realm of detached processes. This also limits portability to some degree. There are special libraries dedicated to assisting with daemonizing processes as well as special wrappers and whole posts dedicated to writing proper startup/shutdown scripts depending on the distro you're targeting.

2) I tried going through references on how to launch the application at startup on my Mac. EINAL needed at least the -background flag to run in background mode; running it as a startup item would just launch the application. I'd have to instead run a startup script, and then I'd have to tinker with that until the proper environment variables were set and working.

3) Running it as a VM is a nice sandbox method of isolating the environment in which EINAL runs and is semi-portable (depending on how large the virtual disk ended up.) Unfortunately unless I ran this on one of our company server farms, it would be rather resource intensive to run a whole operating system just to run my application. Also any restarts on the workstation would cause the VM to go down until someone intervened.

4) Running it on the Pi as a background process or in a detached Screen session was actually an appealing idea. Of course I'd become obsessed with finding a way to script the startup of the application and some way to notify me when it restarts so I'd know I have to log in to EINAL to give the encryption phrase. 

So far the fourth option sounds best. EINAL isn't a resource hog. it shouldn't take too much tinkering to get it running on the RPi. 

On Second Thought

Then it occurred to me that I might want to investigate something new that was becoming popular at the office; using Docker as a sandbox and deployment tool for EINAL. I should learn more about it; it was a way to (at least partially) automate deployment, and learning Docker should prove valuable as it's becoming popular in up-and-coming technologies.

And beside, it might be interesting to have Docker running on a Raspberry Pi.

In the next part, I discuss setting up Docker on my Raspberry Pi!

Sunday, December 20, 2015

Athens Teachers' War Against the Board: Public Relations

There was a recent rant going around Facebook about an "incident" at an elementary school in the Athens district. The rant was gaining traction in that it was a beautiful moment for anti-Muslim bigotry to be publicly paraded after the ranter claimed his child was subjected to 20 minutes of Muslim indoctrination and anti-Christian holiday...something. It's not worth really rehashing much at all.

I learned about it only because I was sent a message that a mutual friend on Facebook had posted information from a closed group dedicated to the elementary school's Parent-Teacher Group, a "social media response" to the allegations.

I wondered what the school's official response was; supposedly, according to the ranter, the school received many phone calls from numerous sources after his tirade. You would think there would have been an official response to an incident that had supposedly happened several days previous and had generated phone calls to the superintendent. But as of the time I'm writing this, you'd be wrong. I find nothing on the district's home page, where last year the school board had posted a list of arguments outlining why the teachers are grossly overpaid compared to the constantly toiling school administrators.

I suppose I shouldn't be surprised. Sources within the district say that it's not unusual for administrators to require teachers to address behavior issues of students with parents before administration will become involved. Calming an outraged mob of ill-informed Facebookers is only a stone's throw away from discussing behavior issues with the public if the school doesn't acknowledge the need for consistent handling of these issues through official channels.

Note: there was a newspaper story referring to a district statement. First, that guy's rant and backhanded apology was a story in the local paper?!? Really?!? Second, despite the story's claim, I can't find an official response on the school website, and the quotes in the story mirror the statement posted by the head teacher on the PTG Facebook page. Unless someone corrects me on where this statement came from and who authorized the wording, I'm calling shenanigans.

What struck me about the statement from the PTG Facebook page was how factual it was. It calmly, almost clinically, debunked the same batshit stupid ideas that still are tossed around about schools despite time and time again being denied, such as not saying the Pledge of Allegiance or allowing students to say "Merry Christmas". (Snopes.com needs to strike a deal with Facebook to auto filter that crap...please.)

The tone is much like the rare release from the teacher's Union in their ongoing contract negotiations. If you read what a certain board member characterized as a declaration of war, it was by far one of the most boring and dry declarations of war I've ever read. I mean, though apocryphal, at least John Hancock signed his "screw you" to Britain with such large strokes it could be read without spectacles. The Union's "demands" were tame and deferential. Contrast that with the bombastic tone of the mostly fictional allegations made by the father angry that his kid was learning about another culture, or the hyperbolic tone of the "pillar of the community" board member having a public tantrum and all but declaring war on those greedy, scheming teachers. The Union letter couched itself more heavily than my ten-year-old testing IKEA living room furniture displays.

Everything the Union releases is carefully crafted to be factual and straightforward; nothing is incendiary or opinionated. It's like being lectured by a Vulcan. The school board, on the other hand, has nothing to lose despite characterizing themselves as victims held hostage by their employees for the past three years. They have no problem going public with propaganda painting the non-community-member (and if you listen to them, probably not even really human) teachers as a boogyman army out for community members' wallets while contributing nothing to society--yet, many of the teachers live within the same communities as those they teach.

These recent incidents highlight a fundamental issue for the teachers; they have a serious PR problem. Yes, there are groups like the PTG that distribute information through a special Facebook page, but Facebook, like all social media, is an insular bubble. The very nature of social media means people seek out like-minded people. What do ninety percent of people you "friend" or "follow" in social media do when someone says something you don't like? Unfriend. Unfollow. Mute. Ban. Social media encourages you to pare down what information you're exposed to until these groups are echo chambers and followers hear what reinforces their established beliefs.

The job of public relations being farmed out to teachers is also treated as an afterthought; they're busy with actual schoolwork and busywork mandated by school administrators and state education requirements. But it's also a trap. Anyone who takes on this responsibility of informing the public about things the public is generally ignorant of while also shouldering the blame for backlash that it will inevitably incur is putting their job on the line. School officials tend to dislike situations that put them in a poor light, and there is simply no way to please everyone. Take as exhibit A the Facebook ranter's non-apology (the entire apology was yet another rant that, while technically an apology ["I said I was wrong at the end of these many paragraphs complaining about why the school was still truly at fault for following mandates which I explained through clever use of childish name calling!,"] totally deflected from an actual apology) where he still had numerous messages praising his post. These are people who will never be convinced the teachers (or the school) are not on some campaign to destroy America. Sharing information with the public and taking responsibility for the content is not an enviable position for a teacher when a hostile school board, principal, or acting superintendent is very willing to make an example of any pebble daring to make waves. It's telling that beyond press releases condemning teachers, the school board doesn't seem to work to clarify misunderstandings between the general public and the school, nor have I found a statement attributed to the acting superintendent defending his employees on the matter--only snippets of quotes in a newspaper article.

It does make sense if you look at it in the context of having someone who might do a decent job of clarifying issues while lacking the authority to be the "official" voice of the school; if that person screws up, he or she can be blamed by administrators and will be called to the carpet. It's another case of teachers being asked to do things unofficially; convenient to say this thing that has to get done requires them to step up for yet another thing not contractually required, but won't be recognized in the next argument where the board points out how overpaid teachers are compared to the minimum requirements they are contractually obligated to follow.

True media coverage of what the teachers do of benefit to the community...access to information outside of the insular social media circles...is rare. The politicized environment within the school discourages teachers from speaking because of the previously mentioned pebbles-making-waves problem; having bills to pay necessitates a job, and leadership within the school makes a point of emphasizing that, as one source told me, "There's no law preventing your boss from making your life miserable."

There are a few key moments that encourages coverage of the schools. The first is anything involving taxes. Taxes directly affect community members, and no one likes taxes. So when the community grumbles about paying them, especially (and understandably) people who don't have kids in the school, who better to blame than the schools? (I'll not mention the fact that governments underfund the schools, since people prefer to blame the most immediate and convenient entities to yell at.) School leadership blames teachers for high costs. They fail to mention that teachers make up the largest number of employees and, like in most businesses, employees tend to be the most expensive cost when it comes to expenditures.

The second is that spectacles sell. Everyone loves watching monkeys fling poo at the circus, and seeing articles declaring war on the teachers guarantees sales and clicks. I've mentioned the school board has nothing to lose and it's an open secret that retaliation within the schools happens if you make waves; the net result are the tactful and sanitized Union statements occasionally proffered to the media outlets while board press releases are plastered on the front of the school website.

It's sad that the teachers still do what "needs to be done" with hardly any acknowledgement. Technically they're supposed to be working under "work to rule" where they do exactly what is required by their contracts. It seems logical. "I'll show you how valuable I am with all this extra crap I do," the teacher says as another turd is hurled in his or her direction, missing by inches. "You criticize how little I'm required to do and get paid far too much for doing. I'll start doing only what's required."

But they don't.

If they worked only the time they are mandated to work, papers would never get corrected. Grades would never be entered. The workload they have requires working outside the hours they are paid to work. And if they actually did what the contract obligates, they'd be fired. Ironic.

But that wouldn't garner sympathy from a public who knows the school board justifies their distaste for academic "non-community-member" teachers.

Part of the ranter's tirade brought up the point that this was the same school that threw out lunches if kids couldn't pay. "Whatever happened with that? People were pretty pissed about it..." The school never recanted the policy of no-charging lunches. The same community that feels overburdened by the teaching staff continues to have a "paying for food" problem, sometimes to the tune of several thousand dollars. So the board decided to stop feeding those that continue to charge meals without paying for them.

I don't recall the Union pointing out that the Board was not feeding poor kids as a cost savings measure when the Board was doing what was best for the kids. I also don't recall the Union pointing out that students in schools that don't give peanut butter and jelly sandwiches to those who went without lunch were still getting lunches when they didn't pay because the teachers were paying for them. Yeah. Teachers didn't think it was right, they quietly paid for lunches for kids who can't pay for their own lunches. But I haven't seen that in the newspapers.

Nor have I seen the "dress down days" making headlines in the paper. Teachers get the opportunity to pay for the privilege of wearing a more comfortable outfit once a week and in exchange part of their salaries to a charity or cause. Unless there is a specific cause, it goes into funding a scholarship fund, but much of the funding goes to local charities such as Food for Thought, The Bridge or The Children's House. When a student, employee, or alumnus encounters a traumatic life-changing event, it's not unusual for the dress down day funds to go towards easing financial burdens for those in need.  Over the course of a school year, it is not uncommon for each building in the Athens district to raise thousands of dollars or to donate goods and services. Does the paper cover these donations? Rarely, unless it is submitted to the paper by those heading a particular cause.

Perhaps this lack of public relations is a result of what happens when there's little to no accountability in the school system, which is ironic given that the most hated mandates by the public...No Child Left Behind, Common Core, etc...are the result of a public crying for accountability in the school system. Teachers end up being the target for the accountability crosshairs since years of experience has taught them that administration doesn't believe in the idea that good managers shield their employees from issues not directly part of their jobs as teachers. Teachers are targeted under the guise of accountability for everything from how their students behave to what parents are upset over, things they have little actual control over. It's no wonder they are skittish in the face of public assaults from people who have no accountability for poo-flinging.

I think what the teachers need is a reporter who cares about the state of teaching in his or her community. I know that reporters typically care only about things that grab headlines for being outrageous or are so directly relevant to the paper's readers that a 5 year old wouldn't need the importance explained to them and I also understand that much of the importance of proper education doesn't become evident until little Bobby grows up and leaves because there are few jobs in the area that make a promising career...education is about investment in the future, after all, and most people are more concerned over the next weekend's football game or this years's school tax burden.

The public appreciates spectacle over substance. Of course reporters would pay attention to stories about poo-flinging over boring things like helping the needy in their own community. Newspapers love stories about people who seem to become mentally unhinged; it generates sales.

What the system needs, though, is a reporter willing to put a journalism degree to actual journalism use and dig in to figure out the facts behind the hyperbole when a board member declares war on his own employees. The community could really benefit from this theoretical journalist presenting the facts in small, simple, digestible chunks that even the community members ostensibly charged with holding administrators accountable for their actions would understand without using a dictionary. Sort of like an education-system version of Steven Brill, the journalist who exposed the utter insanity of our healthcare system with a great article that turned into a great book.

The teachers are already trapped within a system that won't allow for frank discussion. An outside journalist with a small column on the other hand could give information in local newspapers; a medium that is favored by people who often don't get news from insular social media groups, but could still inject information into those same groups. Best of all, as an outsider, that person would be as accountable as...well, most other community members who aren't under threat of losing his or her job if facts made an administrator or board member glow in a poor light.

The other option would be for the system to change, where teachers could talk to the public without fear of retribution. But judging from what I've seen and heard from others, there's little chance of that happening in any near-term timeframe. The field is too heavily skewed away from teachers having a voice of any significance; the Union, a body that is supposed to prevent just this kind of imbalance, is effectively gutted from legal erosion of Union power that is not just a problem for the local teacher's Union but Unions across the US and across multiple fields (it's not a coincidence that the loss of the middle class and growth of income inequality coincides with the loss of Union influence in America...)

Which is more likely? Probably neither. Most likely this fight, where poo is flung from one side and dodged on the other, where schools are generically blamed for rising taxes while the implicit reason is the greed of teachers taking priority over an economically depressed community, and the argument continues in the backdrop of a community where most new jobs are coming not from innovative markets but chain stores and chain restaurants...this fight will be won through attrition. Eventually one side will grow too weary to continue and the education system will continue to erode. But this could be the cynic in me speaking.

What do you think? How are the teachers perceived, in contrast to the school board? Does the community make distinctions among the administration, teachers, and board? Do you think the teachers have a public relations, and public image, problem?

I should add that all of this is my own opinion, my own point of view, I speak for myself and only myself, etc. etc...not that I should have to add disclaimers, but I know if I don't someone will come up with some stupid ideas that I frankly don't feel like addressing beyond this disclaimer.

Wednesday, December 9, 2015

Bootcamp + Windows 10...No Boot Device

Backstory:
My son has a not entirely new MacBook, and because of his relatively young age he likes video games. Because of this, he wanted to play games with Steam, and hated the limited selection of Steam games on OS X.

To solve this he used Bootcamp to install a retail copy of Windows 8.x. Everything seemed fine for some time. We've upgraded OS X, and Windows has been upgraded to Windows 10 Home. All still seemed fine.

At some point he wanted to reboot to Windows and test some screen recording software. "Dad, what does it mean when the screen is black and says there's no boot device?"

Dammit.

Symptoms:
OS X booted fine. Bootcamp still appeared as a volume that was readable under OS X. I could select it as a bootable volume when OS X was running. Upon startup with Bootcamp as the startup disk, the Mac booted to a black console with a Windows error saying there wasn't a usable boot disk and asking you to insert a bootable CD or disk and restart.

When you boot the Mac holding the Option key, the only bootable volumes that appeared were OS X and the recovery volume.

Therefore, the data/partition was intact, but something related to the Master Boot Record (or the hybrid used on the Mac to accommodate Windows with the disk partition scheme compatible on the Mac with its lack of BIOS) was damaged.

I tried booting the commercial Win8x disc and running a repair; Windows would say it repaired things, but upon restart it still threw an error.

I was going to reformat the partition and reinstall but then I realized we had upgraded to Windows 10 and the whole "install 8.x and run an upgrade to Windows 10" would be beyond painful with our crap Internet connection.

I really wanted to double down on my effort to save the partition.

I had run Disk Utility to check the drive. The drive was coming up fine, the OS X partition was healthy, and Disk Utility wouldn't even try to play with an NTFS partition hosting Windows. So the drive seems fine. It was most likely a data-level problem instead of a hardware problem.

(Note - yes, I know, backups. There weren't any. That is something I tell the family to do, and if they lose the data because of <reasons> then it's not my direct fault...they can ask about it and I can help set it up, but they have to be responsible for actually connecting a drive and running backups periodically, which with laptops means an actual effort on the user's part to run backups. Hybrid installations of OS X and Windows make it three times harder. In the end, there are no backups, it's their responsibility to do it even though I'd help if they ask, and I'm not spending significant portions of time chasing them down to do it...if they lose data after a problem, it's on them. Sorry.)

The fix:
He had no idea how this happened or if something had happened the last time he used Windows, but people who deal with troubleshooting other people's systems know that this isn't uncommon.

To make it worse, I had made the decision that since I'd reformat the partition and start over, it was a good time to finally do the OS X 10.11 from 10.10.5. The realization that he had Windows 10 installed (by the way, I checked the version from OS X by opening the Bootcamp partition, then drilling to C:\Windows\System32\ happened as I wrapped up the 10.11.1 install.

Why is that a big deal? Because changing things that affect the system are now a no-no. OS X 10.11 uses SIP (System Integrity Protection) to protect users from themselves; that can also affect programs that affect boot sector manipulation. I followed the steps I outline here once from a regular boot, and it said the write failed. So to save rehashing that attempt, I'll start with what I did to run it again and have it work.

DISCLAIMER - This is playing with your hard drive. Like, you could accidentally kill your system. What I'm saying is that if you don't mind reformatting your drive and reinstalling everything and potentially losing data, go ahead and do what I'm outlining here. But I strongly advise backups first. Not my fault if this bricks your system.

  1. Download and install some support software
    1. Download gptfdisk (my repair used 1.0.1)
    2. Run the pkg installer
    3. If you get the unidentified developer error, say ok and open your security system pref and tell it to run it there
  2. Disable SIP
    1. Boot to recovery mode (on startup, hold Command-R)
    2. Open a terminal (using the Utilities menu)
    3. Run the command csrutil disable in the terminal. Note: you can get the status of SIP using the command csrutil status
    4. Reboot, but boot back into recovery mode
  3. Let's Run a Repair
    1. In recovery mode, open two terminals
    2. In one terminal, run diskutil list
    3. There are instructions on the link above saying to first run gpt -r -vv show disk0 and fdisk /dev/disk0 for information about the drive...
      1. These give you more information, but the part I needed for later instructions was from diskutil list
      2. The instructions in the link also use "sudo" but recovery mode's Terminal is running as root (# in the prompt) that doesn't require sudo. Recovery mode also lists more mounted volumes in diskutil list than it did in regular running mode, but all I needed was disk0 with the Bootcamp partition in the numbered list.
    4. diskutil list will show the #, Type, Name, Size and Identifier of your partitions on each disk. I needed the partition (slice) marked Microsoft Basic Data BOOTCAMP, which was #4 in the list. Remember that far left number for the line marked BOOTCAMP.
    5. Because I'm in recovery mode, I have to run the gdisk executable from where it's installed. In the second terminal window, so I can use the first terminal window with diskutil's output for reference:
      1. mount
      2. look for the hard drive volume location (/dev/disk0). cd /Volumes/<hard drive>
      3. cd usr/local/bin
      4. ./gdisk /dev/disk0
    6. r <enter> for the recovery and transformation menu
    7. h <enter> to create a new hybrid MBR
    8. 4 <enter> to add partition 4 to the list (ENTER THE NUMBER FOR YOUR BOOTCAMP PARTITION...from diskutil list...HERE. For me it was 4.)
    9. y <enter> to place EFI GTP (oxEE) partition...good for GRUB...yolo...
    10. <enter> to accept default MBR hex code (07)
    11. y <enter> to set the bootable flag
    12. n <enter> because I have no more partitions to protect
    13. w <enter> to write partition table to the disk
    14. y <enter> to proceed
At this point I rebooted. I selected the Bootcamp volume as the startup disk within OS X, and rebooted again.

Windows booted and complained about an issue with startup (but I got farther along the boot process this time!); at that point, I ran a startup repair with Windows 10's builtin auto-repair process, after which it automatically restarted. Windows 10 then booted fine!

Once everything was booting fine, I booted back into recovery mode, opened a terminal, and ran csrutil enable along with a quick check using csrutil status to verify that SIP is running again. DON'T RUN WITHOUT SIP UNLESS YOU REALLY REALLY KNOW WHAT YOU'RE DOING. See the link above in my instructions for SIP to see the section on verifying that SIP is enabled.

Conclusion:
Something...a utility, an update, a chkdisk...munged the boot sector. Windows isn't expecting the hybrid nature of Bootcamp's boot sector to accommodate the EFI firmware instead of a BIOS, so it killed Windows boot sector while leaving the partition table information and data intact. 

I linked to the articles I used for guidance above in the instructions. I included a casual warning about not being responsible for destroying your data if you follow these instructions, and the linked set of instructions also warns of possible dire consequences by following the (similar) instructions. Make a backup. You could destroy your data, both Windows and OS X, when screwing with the boot sector on your hard disk.

Thursday, December 3, 2015

Athens, PA Union vs. School Board: I Think I See Your Problem

Front Page News

The teachers of the Athens school district have been working now for three years without a contract.

I think this article is probably the best highlight of why that has been the case.

Let's break this down.

What was the ultimatum?

“The AAEA faculty will allow the Athens Area School Board four weeks from the time state funds are allocated to the Athens Area School District to propose a reasonable contract settlement and begin to show an attempt to bargain in good faith,” the letter said. “If the school board fails to do so, AAEA faculty will reconvene to vote on a strike.”

After THREE YEARS of negotiating...where negotiations are held several months apart...the union is saying they want the board to show AN ATTEMPT to bargain IN GOOD FAITH. It's not even demanding a resolution. It's demanding an attempt to bargain in good faith. And the consequence? A vote on whether to strike. Not a guarantee of a strike. A vote on whether to do it.

It has the gravitas of threatening not to force your kid to eat their spinach at dinner.

So how does the board reply? Board member Jason Johnson said,

"If they want to go to war, let’s go to war."

That's very adult. Precisely the kind of person you want acting in good faith negotiations with another party.

Another newspaper quoted this school board member saying, "...it has been absolutely ridiculous...what we have to deal with on settling the contract. The people that we have doing this have worked hard - many hours, countless hours...doing everything they can, yet the teachers seem to think that they want everything and everything after that."

Proof of the quote
First...that quote doesn't make much sense. Just from a grammatical standpoint. I'm not sure if that's Johnson's fault or the article editor.

Second...he makes it sound like they've been toiling away at this contract nonstop against the relentlessly unwavering Union. He fails to mention that their "negotiations" rarely take place. According to what I could find, weeks, if not months, can go by before they get back together again for another session.

What I'd like to know is how much of the ~8,760 hours over the course of 3 years have you really spent working on the contract negotiations, Mr. Johnson? It shouldn't be hard to get an estimate, when these meetings are scheduled for an evening or two every few months. I'd be interested to know how much time has actually been spent trying to get the board's job done in providing their staff with a contract. How many times have there been delays in scheduling negotiation sessions? I'm fairly sure most of the board members would be angry working for an employer who isn't renewing their contracts in a timely fashion, but it's evident they don't mind doing this to their own staff.

He also said, in that same article, "If they want to do what they're saying, that's fine. Do not put us in the corner."

Because three years of voting down every concession offered by the Union is putting them in a corner.

Further, "If those children can't go to school, it's not us - it's the teachers." Completely disregarding the board's role in the lack of negotiations, and their refusal to meet for negotiations - except on the board's timetable.

For a group of adults, it seems beneath them to play the "Oh, they hold all the cards and are forcing us into a corner!" card. Especially when he also was quoted saying, "Again, we don't work for them - they work for us."

"What are they sacrificing? Nothing," he was further quoted.

Care to share the details of the offers? Because this sounds like you're telling the public the Union has offered nothing in these negotiations. I also find that hard to believe, that they offered - over the course of three years - no concessions.

I do believe that you have had the option of a fact finder. I believe you've had that option a couple of times. It's a third party that comes in and looks at both sides and presents a set of recommendations; as a third party they don't have a horse in the race. In theory, the report should be acceptable because it doesn't involve the Board's need to reinforce the idea that the educators are a waste of money nor the Union's desire to steal all your pie.

I also believe you, the Board, threw out both of those reports. Outrightly rejected them. How reasonable. As was in the Daily Review link:

"The AAEA accepted the first proposal, but rejected the second, as it contained ambiguous language. Both suggested compromises were rejected by the Athens Area School Board,” the letter said. “AAEA struggles to negotiate with the Athens Area School Board, as they even rejected the second proposal that included a significant decrease in benefits for teachers.”

Are you on the negotiating committee, Mr. Johnson? Because he goes on to say that, "I'm telling you, they will never get my vote...I'm tired of this garbage that has been in the paper stating how they are going to corner us."

Yes. Demanding that you negotiate in good faith is cornering you, especially when you promise you'll not pass a vote in their favor.

Again from the Review, from Mr. Johnson:

“They’re frustrated that the teachers are going to put in jeopardy the kids’ future, the kids’ time at school,” he said. “It’s the most important thing for these kids to get an education.”

This surely hints at the horror of these teachers holding the school hostage with a strike. Does Mr. Johnson actually know what a strike entails? What the limits are? Because at best, strikes are merely an inconvenience to the education of the students. If it were an actual, effective means to resolve the issue, they would have gone on strike far sooner than this over the course of THREE YEARS.

I mean...you're aware there are limits to a strike, correct? Because you have to provide 180 days of school to the students? A school board unwilling to negotiate in good faith...which is what supposedly led to your speech, when the Union requested this...doesn't hurt the kids' education. As outlined by the PSEA (Pennsylvania State Education Association), the Secretary of Education can order an injunction if the strike means the district can't provide 180 days of school by June 30. It also requires advisory arbitration when the strike will prevent 180 days of school by June 15.

Or you can submit to arbitration. That automatically ends the strike until one of you, the Board or the Union, rejects the results of arbitration.

AND this is on top of rules that require such things as 48 hour notice of the strike. In other words, you're not the powerless victim you make yourselves out to be. If you truly feel this is unfair, why not work with the fact finder reports? Why not enter arbitration, or binding arbitration?

Strikes aren't a magic solution. They're not even a very effective threat. The law has done quite a bit to hobble their effectiveness and put limitations on what can and can't be done by the Union in the event of a strike. The Athens Board's attempt to hyperbolize and distort the effect of a strike doesn't change the reality of the limitations of a strike. But we know what you did to the fact finder's reports...I'm guessing facts aren't a priority to a good headline grabber.

What I see is a board that is outrightly hostile to the educators. I see a Board that acts like the teachers aren't a part of the community you claim to serve and represent. I see a board that promotes the idea that the community should be hostile to the educators, creating barriers to negotiation rather than promoting good faith negotiation. I see someone who has blatantly admitted he won't vote for anything proposed by the Union. I see a board united in being unreasonable, as quoted by Board member Darci Baird, "Well said."

I see teachers that still put in far more hours than you claim they are required to put in. I see teachers working in a toxic environment where they get little support from the administrators you've hired. I see teachers who are anxious to leave...some have already left...the profession because, in part, of the management decisions you've made. I see a board that doesn't hold their administrators accountable while increasing pressure on teachers to meet impossible goals.

I see a board that employs dirty tactics in their manipulation of facts, as I pointed out in a previous blog post. And it did not escape notice that my wife, an educator for over a decade with the school, was suddenly under more scrutiny after that blog post went live and gained some attention among some people in the district. The fear of retaliation by the Board and administrators is an open secret in the school district now.

But keep saying this is all about the kids. The inaction on the part of the board over a span of 3 years shows how dedicated they are to working with their staff in creating an effective learning environment.

All of this is my own opinion, except where I quoted others. The images were from the 12/3/2015 "The Morning Times" article by Warren Howeler. The links to The Daily Review quotes are from...well, the link to The Daily Review.