Short version: We tried that, but it doesn't scale. Eventually the one person self-nominated as the sole arbiter of 'good behavior' can't keep up with everyone and has to delegate. When that happens, their subjects start complaining about inconsistent rules and their enforcement.

An extensive, written code allows people to have a chance of living up to that expectation, and understand what'll happen when they don't. This is especially important for volunteer-run organizations who don't have professional, paid enforcers.


Long version

The legal code is just that: code.

Worse, it's a code that is interpreted, not compiled, and how the lines are translated into actions changes a little every time you run through them. Any time the Supreme Interpreter issues a ruling on something, whole swaths of that code will be subject to new interpretations, which will have unpredictable side-effects. Side-effects that will trigger new code to try and handle the edge-cases.

The legal system as it exists in most countries is extensive, written, and impossible for one person to fully understand. This is why lawyers are hated, the legal system seems arbitrary, and anything fun always seems to be illegal. And if that wasn't enough, case-law is its own unwritten thing that handles edge-cases in the lack of a written code. It's no wonder we hate extensive codes of behavior.

That said, there are very good sociological reasons why a code-of-conduct like:

Be Excellent To Each Other

Is a bad code. Take, for example, a basic value judgment:

Murder is bad, and will be punished.

Pretty obvious, and common-sense. And unlike 'be excellent', is narrower in scope. And yet.

Is killing someone accidentally while driving still murder?
Is killing someone in self-defense in your home still murder, or something else?
What is the exact punishment for murder?
Do you punish accidental murders different than intentional ones?
Do you punish killers-of-children different than killers-of-adults?

And so on. This is how we end up with ideas like 'manslaughter' and many grades of murder, with different punishments for each. Without those umpty-hundred pages of legalese defining everything, the answer to all of the above questions would be in case lawwhich is inaccessible to most non-lawyers.

Short codes: Easy to understand in general. But the specifics of what it means to me are completely opaque.
Long codes: Hard to understand in general, but are much more discoverable. If I need to know what it means to me, I can find out.

Nation-states have converged on the long code for very good reasons. But what about volunteer-run organizations like SF conventions, tech-conferences, and open-source projects?

People are hard, let's just party.

Unlike nation-states, volunteer-run organizations like these aren't big enough or well funded enough to have a professional enforcement arm. Relying on peer enforcement is unavoidable, as is relying on untrained people for adjudicating misconduct. These projects can and will attract people quite willing to be enforcers, and are generally the kinds of assholes we want to avoid. The people running these things almost to a person want to avoid conflict, or as it's sometimes called, DRAMA.

If one of your goals is to provide a fun place to code, party, or discuss contentious genre issues, you need a way to bounce the assholes.

Bouncing an asshole is conflict, that thing everyone wants to avoid. When the conflict becomes egregious enough to be officially noticeable, Responsible People tend to respond in a few negative ways:

  • Pretend they didn't see it, in the hopes one of the other Responsible People will notice and do something.
  • Talk themselves into thinking that it wasn't as bad as all that.
  • Pretend they're not actually a Responsible Person, and hope the complainer doesn't notice.
  • Officially notice, but wimp out on actually causing displeasure in the complainant.
  • Hide behind a committee, most of the members of which will be doing one or more of the four previous points.

If you have a "be excellent" code of conduct, point number 2 is where all the Official Drama will go to die; leaving a whole bunch of 'petty highschool bulllshit' to get in the way of the coding, party, or genre discussions. You will have assholes among you, but that's better than being the specific person who ruined someone's day (even if they are an asshole).

If you have a written code with if this BAD then that HARM in it, it allows the drama-avoidant Responsible Person too look at it and say:

Oh shit, this totally applies. Fuckity fuck fuck.

And actually do something about it. Which means, as it was written down, they know what that 'something' is. They may still try to pretend they never saw anything and hope someone else does, but having it written down makes it more likely that the next Responsible Person will do something. It also means that the committee meeting is much more likely to act in consistent ways, and maybe actually bounce assholes.

This is why we keep pressing for details in those codes of conduct. It allows the Responsible People to hide behind the policy as a shield to deflect the displeasure of the punished, and actually provide meaningful direction for the culture of the volunteer-run organization. You deserve that.

Why I'm not moving to California

| 1 Comment

Many companies I would like to work for are based there and have their only offices there, so this stance limits who I can work for. Remote-friendly is my only option, and happily that segment has enough demand I can still find gainful employment in the largest IT market in the US. There are two big reasons for why I won't move to California:

  1. I couldn't stay married if I moved.
  2. The California political system is functionally broken.

Number one doesn't make for a long blog-post, so I'll skip it to focus on the second point.

A failure of democracy: the initiative system

Democracy goes to those who show up.

Government goes to those who show up, are well organized, and have funding.

The initiative process for those of you who aren't familiar with them, is a form of plebiscate. Many western US states have initiative processes, as they were a trendy topic when the western territories were applying to become states. They're seen as a more pure form of democracy than representative democracy, which is what the rest of the US political system is based on. If a group of citizens can gather enough signatures for a bit of legislation, they can get that legislation passed in the next election; in most cases, such legislation can not be overridden by the State legislature.

The intent here is to provide a check on the overriding power of the State legislature, which at the time had a tendency to be captured by industrial interests. Rail-barons and monopolists were a real thing, after all.

With the advent of modern media, a much larger percentage of the population is reachable with relatively little effort compared to the 1910's. In 1910, a special interest (be it a railroad, oil company, or anti-gambling crusader) found their biggest impact on public policy was by lobbying state legislators and other public officials. Best bang for their buck, and didn't require an army of canvassers and hawkers. That didn't stop grassroots organizers from trying to push public policy, they just weren't very good at it; 1914 had 46 initiatives on it, of which 6 passed.

Since the 1910's changes to the initiative process have been made to ensure only initiatives with broad enough public support would be put on the ballot, as voters were getting tired of spending half an hour to vote and way longer in voting-place lines. With modern media, scrounging enough signatures to get a special-interest initiative on the ballot is an intensive advertising campaign away. If an interest can get an initiative passed, the State Legislature can't do anything about it other than live with the impacts.

Democracy goes to those who show up, are organized, and have funding.

Initiative sponsors are the very special interests the initiative process was designed to oust. This leads to initiatives focusing on narrow pieces of government, that over time build a hodge-podge legal system that makes it hard to function.

Raising certain taxes requires a 2/3rds super-majority.
Oh, how about if we ensure budgets have a broad consensus, and require budget-bills be passed with a super-majority.
Education spending is the basis of a healthy population, protect that funding from budget-cuts.
Three felony strikes, and you're outta the public eye for life!
Okay, that's a lot of people serving life sentences, perhaps drug-offenders can get treatment instead.

And so on. It's the kind of code-smell (legal code is still code) that makes you itch to refactor, but refactoring requires going before a committee of managers, some of whom don't know how the system works anymore and are the kind of manager that others need to keep happy.

All of this leads to a government that has to jump through too many hoops, or require unreasonable levels of cooperation between the political parties, to be effective. I don't want to live in a place with government that broken.

There are calls for California to flush it all and rewrite it from scratch have a constitutional convention to deal with this mess, but it hasn't happened yet.

And then there is the Bay Area

To the tech industry, the rest of the state doesn't matter so I'm not going to talk about it.

Did you know that you can do local initiatives too? You bet. But when you get to local politics, only the most invested of interests show up, which selects for existing property owners looking to increase value. Not In My Back Yard is an impulse every city-council meeting has to grapple with. Due to the money involved in the Bay Area, ideas that sound good so long as you're not next door to them get little traction. The few that do end up getting passed face well funded lawsuits by property-owners looking to undo it.

Office-rents in SFO already exceed those of Manhattan. For residential housing, if you can get a mortgage, you're almost certain to be paying more than $2000/mo on it. For renters, over 40% of them are paying more than 30% of their income on the rent (based on US Census data from 2014). Non-census sources suggest rents are even higher, with 2BR units going for north of $3500 on average. To support a housing-payment of $3500/mo, you need to be making $140K/year at least in household-income. For those of us who are single-income families, even Bay Area salaries mean I'll be spending two or more hours a day commuting to work.

Also, San Francisco is the #1 renter-hostile market according to Forbes. San Jose and Oakland take the net two spots. Once you've found a place you can afford, there is zero guarantee it'll still be there in a year or you'll have the same rent.

In the way of big-city in-fill, unit sizes are getting smaller all the time as the available space shrinks.

Impacts to things people generally don't care about, like 401k contributions

There is a funny thing that happens when you make $140K/year, you start running into limits to how you can contribute to your retirement.

If you make more than $132K/year, and are single, you can't contribute to a Roth IRA. But that's a minor thing, since most people are married by the time they hit their 30's, and the limit for household is $189K/year.

The 2016 limit for 401k contributions is $18K. That sounds like a lot, but keep in mind that if you're earning $140K/year, that 18K is only 12.8% of your income. By the time you hit 40, you should be saving 10% or more for retirement. Employer matching contributions can help you get there (and are NOT subject to the contribution limits), but such contributions are few and far between in the startup space, and when they exist at all are not generous.

If you're paying over 30% of income on rent, paying another 10% for retirement is pretty hard.

This is the Federal Government's way of saying:

You will not be retiring in the Bay Area without extensive non-Retirement savings.

Yeah, not dong that.

Nope. I've never lived there. I don't have roots there. Migrating there to chase the labor market is a bad idea for me.

Thanks for reading.

Internet of Patches

| No Comments

This is a good recommendation:

As a sysadmin, I've been saying fuckno to things like Smart TVs and fridges. I do that game professionally, and I know what it takes to keep a fleet of software up to date. It ain't easy. Keeping firmware updated in things like... non-Nest internet attached thermostats (yes, they exist), the PC embedded in the fridge, the hub that runs your smart lighting, the firmware in your BluRay player, internet-attached talking dog toys... It's hard. And it only takes one for Evil People to get inside your crunchy exterior and chow down on everything else.

You can probably trust a company like Schlage to treat their software like a security-critical component of a network. You probably can't say the same about the internet-attached talking dog toy, even though they're likely on the same subnet. The same subnet as all of your iPads, MacBooks, and phones. Segmenting the network makes it harder for evil coming in on the, shall we say, vendor supported side from the more routine evils faced by general web-browsing.

Not that segmenting is easy to do, unfortunately.

InfluxDB queries, a guide

| No Comments

I've been playing with InfluxDB lately. One of the problems I'm facing is getting what I need out of it. Which means exploring the query language. The documentation needs some polishing in spots, so I may submit a PR to it once I get something worked up. But until then, enjoy some googlebait about how the SELECT syntax works, and what you can do with it.

Rule 1: Never, ever put a WHERE condition that involves 'value'. Value is not indexed. Doing so will cause table-scans, and for a database that can legitimately contain over a billion rows, that's bad. Don't do it.
Rule 2: No joins.

With that out of the way, have some progressively more complex queries to explain how the heck this all works!


Return a list of values.

Dump everything in a measurement, going back as far as you have data. You almost never want to do this

SELECT value FROM site_hits

The one exception to this rule, is if you're pulling out something like an event stream, where events are encoded as tags-values.

SELECT event_text, value FROM eventstream

Return a list of values from a measurement, with given tags.

One of the features of InfluxDB, is that you can tag values in a measurement. These function like extra fields in a database row, but you still can't join on them. The syntax for this should not be surprising.

SELECT value FROM site_hits WHERE webapp = 'api' AND environment = 'prod'

Return a list of values from a measurement, with given tags that match a regex.

Yes, you can use regexes in your WHERE clauses.

SELECT value FROM site_hits WHERE webapp =~ /^api_[a-z]*/ AND environment = 'prod'


That's cool and all, but the real power of InfluxDB comes with the aggregation functions and grouping. This is what allows you to learn what the max value was for a given measurement over the past 30 minutes, and other useful things. These yield time-series that can be turned into nice charts.

Return a list of values, grouped by application

This is the first example of GROUP BY, and isn't one you'll probably ever need to use. This will emit multiple time-series.

SELECT value FROM site_hits where webapp =~ /^api_[a-z]*/ AND environment = 'prod' GROUP BY webapp

Return a list of values, grouped by time into 10 minute buckets

When using time for a GROUP BY value, you must provide an aggregation function! This will add together all of the hits in the 10 minute bucket into a single value, returning a time-stream of 10 minute buckets of hits.

SELECT sum(value) FROM site_hits WHERE webapp =~ /^api_[a-z]*/ AND environment = 'prod' GROUP BY time(10m)

Return a list of values, grouped by both web-server and time into 10 minute buckets

This does the same thing as the previous, but will yield multiple time-series. Some graphing packages will helpfully chart multiple lines based on this single query. Handy, especially if servername changes on a daily basis as new nodes are added and removed.

SELECT sum(value) FROM site_hits WHERE webapp =~ /^api_[a-z]*/ AND environment = 'prod' GROUP BY time(10m), servername

Return a list of values, grouped by time into 10 minute buckets, for data receive in the last 24 hours.

This adds a time-based condition to the WHERE clause. To keep the line shorter, we're not going to group on servername.

SELECT sum(value) FROM site_hits WHERE webapp =~ /^api_[a-z]*/ AND environment = 'prod' AND time > now() - 24h GROUP BY time(10m)


There is one more trick InfluxDB can do, and this isn't documented very well. InfluxDB can partition data in a database into retention policies. There is a default retention policy on each database, and if you don't specify a retention-policy to query from, you are querying the default. All of the above examples are querying the default retention-policy.

By using continuous queries you can populate other retention policies with data from the default policy. Perhaps your default policy keeps data for 6 weeks at 10 second granularity, but you want to keep another policy for 1 minute granularity for six months, and another policy for 10 minute granularity for two years. These queries allow you to do that.

Querying data from a non-default retention policy is done like this:

Return 14 weeks of hits to API-type webapps, in 1 hour buckets

SELECT sum(value) FROM "6month".site_hits WHERE webapp =~ /api_[a-z]*/ AND environment = 'prod' AND time > now() - 14w GROUP BY time(1h)

The same could be done for "18month", if that policy was on the server.

The web of trust shrinks

| No Comments

http://techcrunch.com/2015/12/16/a-call-to-arms-against-mccarthy-2-0/

Legislation is passing Congress right now, with a promise of a signature, to add new exceptions to the Visa Waver Program for a broader class of visitors to the US:

  • Nationals of Iran, Sudan, Iraq, or Syria, regardless of any other passports they hold.
  • Anyone who has traveled to those four countries within the last five years.

Because, terrorism.

Iran and Syria have expansive rules for who may be considered a national, which means people who have never been inside one of those countries may be governed by this new rule. Among those are Steve Jobs family.

The EU is promising Dark Vengeance (well, firmly worded disappointed words, followed by a possible reciprocal attack on US entry).

Because Canada and Mexico both allow US citizens a visa-free entry, most Americans have zero idea how travel to a visa-requiring country works. Or even what is required. It's specific to each country, there is sometimes an application fee, being denied entry does not get you your money back, and more and more countries are requiring biometric data (fingerprints, eye-scans) as part of the application or entry processes. It introduces friction to international commerce and travel, which is why the US introduced the Visa Waver Program in the first place.

But, terrorism.

And trusting your neighbors well enough to police their own borders.

And dealing with domestic cries to vilify whole peoples.

We are seeing the continued erosion of the US web of trust. The EU used to be a prime partner in just about everything; we spent so much rebuilding Europe in the 1940's and 50's, those relationships don't die easy. And yet, here we are, about to say:

We trust you to tell us who are bad people. But these people will require us to do the determining, sorry.

It's throwing sand into the wheels of commerce, a point the EU ambassadors have made.

That trust is a big thing. Participation in the Visa Waver Program is why EU passports have biometric chips in them now. In the background Travelers from waver countries still have their details run through the same electronic background check that visa-countries require. A country can't get entry to the waver program unless you meet some heavy requirements, some of which are political ("shared democratic worldview").

By forcing people from these four countries to go in person to a US Embassy and obtain a tourist visa for entry, we are greatly increasing the effort it takes to travel here. Business people in, for example, London will need to add at least 7 days to their travel prep-time in order to get an appointment at an Embassy; there will be no hopping on a plane with three days notice to go to a meeting in New York.

This is pandering to the domestic crowd at the cost of our economic flexibility, with no significant increase in our security.

Burocracy ~= Automation

| No Comments

That was one of the big points in this morning's keynote by Mickey Dickerson. Laws and the federal system is designed to be a big hunk of automation, executed by humans. Failures in the processes are entirely predictable, and like CPUs, the human processors likely can't do much about it.

So, so true.

And also pointed out that the US Federal System is a huge open-source project kicked off a couple hundred years ago with 538 comitters at the moment. There are lessons in big open-source project management in here somewhere, I'm sure.

It turns out one of the biggest goals of the US Digital Service is to ferret out the worst of the bad automation and try to turn it around. Healthcare.gov was their first big project, and right now they're making inroads with the Veterans Administration. They're doing some other things they can't talk about yet because government, but this is all worthy cause kinds of things.

During my last job-hunt I considered applying, but didn't go there due to where I wanted to live and an unclear answer on if they'd take a remote worker. Still, this is good stuff and I wish them all the luck and support.

Security profiling: TSA

| No Comments

Being of a gender-nonconforming nature has revealed certain TSA truths to me.

Yes, they do profile.

It's a white-list, unlike the police profiling that gets people into trouble. There is a 'generic safe-traveler' that they compare everyone to. If you conform, you get the minimum screening everyone gets. If you don't conform, you get some extra attention. Some ways to earn extra attention:

  • Don't look like your government ID.
  • Wear your hair up, or in braids (they've seen those kung-fu movies too)
    • Yes, they put their gloved hands in your hair and feel round. Anyone with dreads knows this all too damn well.
  • Fly with a name other than the one on your government issued ID.
  • Have body-parts replaced with things, such as a prosthetic leg, or knee (if going through metal detectors).
  • Have junk when there shouldn't be junk (or so they think).
  • Have breasts when there shouldn't be breasts (or so they think).
  • Have breast prosthesis instead of actual breasts (mastectomy patients love this).
  • And many more.

Here is an exercize you can try the next time you fly in the US. When you get to the other side of the scanner (this only works for the porno-scanners, not the metal-detectors), while you are waiting for your stuff to come out of the X-ray machine, look at the back of the scanner. Watch the procedure. Maybe put your shoes on slow to catch it all. You'll notice something I've noticed:

There are always two officers back there, a man and a woman. When someone steps in to get scanned, they have to either hit a button to indicate the gender of the person being scanned, or are presented with a side-by-side with both genders and the officer has to chose which to look at. They have a second, maybe two, to figure out which body baseline to apply to you, and those of us who are genderqueer confuse things. I fail the too-much-junk test all the time and get an enhanced patdown in my inner-thighs.

Yes, but with PreCheck you can skip that.

This actually proves my point. By voluntarily submitting to enhanced screening, I can bypass the flight-day screen annoyances. It's admitting that I no longer fit the profile of 'generic safe traveler' and need to achieve 'specific safe traveler' status. That, or I can have my bits rearranged and conform that way. Whichever.

The H-1B and I-140 labor-market

| No Comments

A former employer of mine was a big user of H-1B and I-140 visa-workers. They were big enough we had international development centers, and often those employees came to the US HQ. As an Ops-type, this was pretty awesome since we had follow-the-sun support for our stuff. It also meant holidays in other countries impacted our operations in ways that I'd never experienced before. It was a very diverse workplace, which I enjoyed immensely.

However, the big flaw revealed itself when said company had a really bad quarter and decided to reorganize.

What 'reorganization' involved:

  • A near complete musical-chairs round in the Executive VP, and VP offices.
  • A restructuring of the company into completely new divisions.
  • Completely closing one of our foreign development offices.
  • A serious downsizing of the US workforce.

Layoffs

For those of us who are full citizens, we have a completely fluid job-market. This company was in one of the major tech-hubs (the DC metro area, a.k.a. NOVA, a.k.a. 'Ashburn VA', a.k.a. "us-east-1") where cloud-talent was experiencing a shortage and salaries were rising quickly. Unsurprisingly, a large percentage of our senior cloud-trained talent left the company rather than deal with working for a convulsing organization. Me and most other senior systems-engineer types had cold-calls from both Google and Amazon. Some of us took them up on that offer (not me).

It was during this time that I learned about how different the labor-market was for visa-workers.

Both the H-1B and I-140 visa require employer sponsorship. If you lose your employer, you need to get another job (transfer the visa sponsorship) within a specific time or you have to leave the US. Per my fellow coworkers, that time is four weeks. And that's four weeks to first-day-on-the-job, not four weeks to acceptance-letter-is-signed. Four weeks in which to do a complete job hunt with a company big enough to be able to deal with visas and the Department of Immigration. That is nearly impossible.

As a result, all of my coworkers here on visa were job-hunting just in case they got a layoff. All of them. Half of them had married (always other visa-workers) and bought houses here. Due to the DC metro area being one of the most expensive housing markets in the US, you need two full-time incomes in order to afford anything of any size; so having one of the earners leave the country was a recipe for financial disaster.

My department was one making buckets of money for the company, so we didn't take a layoff at all. Even so, we lost about a quarter of our people due to better offers coming in on that just-in-case job-hunt. The other quarter left due to not wanting to put up with the reorganizations.

Some visa-workers in other departments got layoffs. The rumor mill said they were offered a paid ticket back to their home country in addition to whatever other severance benefits they were giving out. No help with the expense of an international move.

Salaries

After the layoffs were done and the reorganizations had completed to the point that the org-chart wasn't being updated on a weekly basis, upper management got down to the serious business of trying to keep the people they had. Part of this effort was to rebase salaries to market averages. There were some big movements.

One coworker had been out of the job market for about seven years to raise her son. When she got back into it, she was hired on as an 'associate systems engineer' at a salary of around $70K/year. Fast-forward five years, and she was still at that job-title, but doing a senior systems-engineer's work and getting paid $73K. They reallocated her up to a 'lead systems engineer' title and a salary of $100K.

Another coworker was here on visa and hired as a 'systems engineer'. He was being paid $85K. The full citizen in the chair next to him, also a 'systems engineer', was being paid $102K. After discussing salaries one memorable afternoon (this is legal, don't let anyone tell you otherwise), we learned that all of our visa-people were underpaid versus the citizens. When the reallocation came around, most of this disparity went away.

Why did it get that bad?

Capitalism, of course. The job-market for visa-workers is limited to those companies with skilled enough HR departments to deal with immigration paperwork. This greatly reduces the number of companies they can work for, which in turn reduces upward pressure on salaries. It also means that those companies who have figured out the paperwork problem have access to a skilled job market with less salary pressure than the greater one, so they tend to go deep into it.

The other factor at play here is the internal raise process. As has been mentioned elsewhere, you get your best raises when you change companies. While salaries in the overall job market had been raising, internal ones were not raising as much. People who don't job-hunt until provoked were falling behind their peers and not noticing because talking salary is taboo.

How can we prevent this disparity?

By talking salaries more often. The visa job-market is fundamentally different than the one for full citizens, but our costs-of-living are still the same. By talking about salaries and visa-status the labor market's supply, us workers, can learn which companies are known to exploit visa workers and which are more likely to treat them the same as the citizens. It means being pushy during negotiations, but that's how you stop this kind of exploitation.

Groking audit

| No Comments

I've been working with Logstash lately, and one of the tasks I was given was attempting to improve parsing of audit.log entries. Turning things like this:

type=SYSCALL msg=audit(1445878971.457:6169): arch=c000003e syscall=59 success=yes exit=0 a0=c2c3a8 a1=c64bc8 a2=c34408 a3=7fff44e370f0 items=2 ppid=16974 pid=18771 auid=1004 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=5 comm="compiled_evil" exe="/home/justsomeuser/bin/compiled_evil" key="hinkystuff"

Into nice and indexed entries where we can make Kibana graphs of all commands caught with the hinkystuff audit ruleset.

The problem with audit.log entries is that they're not very regexible. Oh, they can be. But optional sometimes-there-sometimes-not fields suck a lot. Take for example, the SYSCALL above. Items a0 through a3 are arguments 1-3 of the syscall, and there may be 1 to 3 of them. Expressing that in regex/grok is trying.

So I made a thing:

Logstash-auditlog: Grok patterns and examples for parsing Audit settings with Logstash.

May it be useful.

Asynchronus brick walls

| No Comments

I had the dubious honor of running into a brick wall that has so far resisted my skill in both search-engines and asking for help. It went so far that I asked on StackOverflow and got nothing (12 views as of this writing).

http://stackoverflow.com/questions/33088971/dealing-with-recursion-sync-loops-in-coffeescript

So far, trying to do this thing in coffee has taken two days. This is not a language set up to deal with "do this procedure one or more times until you don't get a thing, and then continue with execution," It can be done, I have no doubt about that. I have simply failed to figure out how.

Yesterday I gave up and wrote a ruby script that did what I needed. It took 6 hours to get the features I needed, including various checks to make sure I'm not breaking things by doing it. It worked the way I needed it to, and it was awesome.

And unfortunately proved that I definitely need to figure out the 'one or more' thing in coffee, going forward. My solution to that may very well be 'shell out to an external script that can do that kind of thing and accept the results.'

I think I now know why the Amazon SDK for Javascript doesn't include paging support like the CLI tools written in python do.

Other Blogs

My Other Stuff

Monthly Archives