Showing posts with label Technology. Show all posts
Showing posts with label Technology. Show all posts

Thursday, January 10, 2019

SysAdmin 101

SysAdmin 101 cover
This book explores system administrator fundamentals. These days, DevOps has made even the job title “system administrator” seem a bit archaic, much like the “systems analyst” title it replaced. These DevOps positions are rather different from typical sysadmin jobs in the past in that they have a much larger emphasis on software development far beyond basic shell scripting. As a result, they often are filled with people with software development backgrounds without much prior sys- admin experience. In the past, sysadmins would enter the role at a junior level and be mentored by a senior sysadmin on the team, but in many cases currently, companies go quite a while with cloud outsourcing before their first DevOps hire. As a result, DevOps engineers might be thrust into the role at a junior level with no mentor around apart from search engines and Stack Overflow posts. In this book, I expound on some of the lessons I’ve learned through the years that might be obvious to longtime sysadmins but may be news to someone just coming into this position.
·   0

More Roman Numerals and Bash

When in Rome: finishing the Roman numeral converter script.
In my last article, I started digging in to a classic computer science puzzle: converting Roman numerals to Arabic numerals. First off, it more accurately should be called Hindu-Arabic, and it's worth mentioning that it's believed to have been invented somewhere between the first and fourth century—a counting system based on 0..9 values.
The script I ended up with last time offered the basics of parsing a specified Roman numeral and converted each value into its decimal equivalent with this simple function:

mapit() {
   case $1 in
     I|i) value=1 ;;
     V|v) value=5 ;;
     X|x) value=10 ;;
     L|l) value=50 ;;
     C|c) value=100 ;;
     D|d) value=500 ;;
     M|m) value=1000 ;;
      * ) echo "Error: Value $1 unknown" >&2 ; exit 2 ;;
   esac
}

Then I demonstrated a slick way to use the underutilized seq command to parse a string character by character, but the sad news is that you won't be able to use it for the final Roman numeral to Arabic numeral converter. Why? Because depending on the situation, the script sometimes will need to jump two ahead, and not just go left to right linearly, one character at a time.
Instead, you can build the main loop as a while loop:

while [ $index -lt $length ] ; do

    our code

    index=$(( $index + 1 ))
done

There are two basic cases to think about in terms of solving this algorithmic puzzle: the subsequent value is greater than the current value, or it isn't—for example, IX versus II. The first is 9 (literally 1 subtracted from 10), and the second is 2. That's no surprise; you'll need to know both the current and next values within the script.
Sharp readers already will recognize that the last character in a sequence is a special case, because there won't be a next value available. I'm going to ignore the special case to start with, and I'll address it later in the code development. Stay tuned, sharpies!
Because Bash shell scripts don't have elegant in-line functions, the code to get the current and next values won't be value=mapit(romanchar), but it'll be a smidge clumsy with its use of the global variable value:

mapit ${romanvalue:index-1:1}
currentval=$value

mapit ${romanvalue:index:1}
nextval=$value

It's key to realize that in the situation where the next value isn't greater than the current value (for example, MC), you can't automatically conclude that the next value isn't going to be part of a complex two-value sequence anyway. Like this: MCM. You can't just say M=1000 and C=500, so let's just convert it to 1500 and process the second M when we get to it. MCM=1900, not 2500!
The basic logic turns out to be pretty straightforward:

if [ $nextval -gt $currentval ] ; then
  sum=$(( $sum + $nextval - $currentval ))
else
  sum=$(( $sum + currentval ))
fi
Done!
Or, um, not. The problem with the conditional code above is that in the situation where you've referenced both the current and next value, you need to ensure that the next value isn't again processed the next time through the loop.
In other words, when the sequence "CM" is converted, the M shouldn't be converted yet again the second time through the loop.
This is precisely why I stepped away from the for loop, so you can have some passes through the loop be a +1 iteration but others be a +2 iteration as appropriate.
With that in mind, let's add the necessary line to the conditional statement:

if [ $nextval -gt $currentval ] ; then
  sum=$(( $sum + $nextval - $currentval ))
  index=$(( $index + 1 ))
else
  sum=$(( $sum + currentval ))
fi

Remember that the very bottom of the while loop still has the index value increment +1. The above addition to the conditional statement is basically that when the situation of next > current is encountered, the script will process both values and jump ahead an extra character.
This means that for any given Roman numeral, the number of times through the loop will be equal to or less than the total number of characters in the sequence.
Which means the problem is now solved except for the very last value in the sequence. What happens if it isn't part of a next-current pair? At its most simple, how do you parse "X"?
That turns out to require a bunch of code to sidestep both the conversion of nextval from the string (which will fail as it's reaching beyond the length of the string) and any test reference to nextval.
That suggests a simple solution: wrap the entire if-then-else code block in a conditional that tests for the last character:

if [ $index -lt $length ] ; then
  if-then-else code block
else
  sum=$(( $sum + $currentval ))
fi

That's it. By George, I think you've got it! Here's the full while statement, so you can see how this fits into the overall program logic:

while [ $index -le $length ] ; do

  mapit ${romanvalue:index-1:1}
  currentval=$value

  if [ $index -lt $length ] ; then
    mapit ${romanvalue:index:1}
    nextval=$value

    if [ $nextval -gt $currentval ] ; then
      sum=$(( $sum + $nextval - $currentval ))
      index=$(( $index + 1 ))
    else
      sum=$(( $sum + $currentval ))
    fi
  else
    sum=$(( $sum + $currentval ))
  fi

  index=$(( $index + 1 ))

done

It turns out not to be particularly complex after all. The key is to recognize that you need to parse the Roman number in a rather clumped manner, not letter by letter.
Let's give this script a few quick tests:

$ sh roman.sh DXXV
Roman number DXXV converts to Arabic value 525
$ sh roman.sh CMXCIX
Roman number CMXCIX converts to Arabic value 999
$ sh roman.sh MCMLXXII
Roman number MCMLXXII converts to Arabic value 1972

Mission accomplished.
·   0

Childhood’s End: Attackers Increasingly Take Aim at Linux Systems

Childhood̢۪s End Cover
Like the wide-eyed humans who mistakenly trust their benevolent alien overlords in Arthur C. Clarke’s science-fiction classic, Linux users the world over are beginning to awaken to the reality that their malware- free utopian childhood is rapidly coming to an end.
A startling increase in malware, ransomware and malicious code targeting Linux systems of all shapes and sizes since 2015 means the days of believing it’s “just a Windows thing” are over. One study found that Linux malware now accounts for more than 35% of all malware, and anyone not taking Linux security threats seriously can face real—and expensive—problems.
·   0

The State of Desktop Linux 2019

A snapshot of the current state of Desktop Linux at the start of 2019—with comparison charts and a roundtable Q&A with the leaders of three top Linux distributions. I've never been able to stay in one place for long—at least in terms of which Linux distribution I call home. In my time as a self-identified "Linux Person", I've bounced around between a number of truly excellent ones. In my early days, I picked up boxed copies of S.u.S.E. (back before they made the U uppercase and dropped the dots entirely) and Red Hat Linux (before Fedora was a thing) from store shelves at various software outlets. Side note: remember when we used to buy Operating Systems—and even most software—in actual boxes, with actual physical media and actual printed manuals? I still have big printed manuals for a few early Linux versions, which, back then, were necessary for getting just about everything working (from X11 to networking and sound). Heck, sometimes simply getting a successful boot required a few trips through those heavy manuals. Ah, those were the days. Debian, Ubuntu, Fedora, openSUSE—I spent a good amount of time living in the biggest distributions around (and many others). All of them were fantastic. Truly stellar. Yet, each had their own quirks and peculiarities. As I bounced from distro to distro, I developed a strong attachment to just about all of them, learning, as I went, to appreciate each for what it was. Just the same, when asked which distribution I recommend to others, my brain begins to melt down. Offering any single recommendation feels simply inadequate. Choosing which one to call home, even if simply on a secondary PC, is a deeply personal choice. Maybe you have an aging desktop computer with limited RAM and an older, but still absolutely functional, CPU. You're going to need something light on system resources that runs on 32-bit processors. Or, perhaps you work with a wide variety of hardware architectures and need a single operating system that works well on all of them—and standardizing on a single Linux distribution would make it easier for you to administer and update all of them. But what options even are available? To help make this process a bit easier, I've put together a handy set of charts and graphs to let you quickly glance and find the one that fits your needs (Figures 1 and 2). "" Figure 1. Distribution Comparison Chart I "" Figure 2. Distribution Comparison Chart II But, let's be honest, knowing that a particular system meets your hardware needs (and preferences) simply is not enough. What is the community like? What's in store for the future of this new system you are investing in? Do the ideals of its leadership match up with your own? In the interests of helping to answer those questions, I sat down with the leaders of three of the most prominent Linux distros of the day: Chris Lamb: Debian Project Leader Daniel Fore: elementary Founder Matthew Miller: Fedora Project Leader Each of these systems is unique, respected and brings something truly valuable to the world. I asked all three leaders the exact same questions—and gave each the chance to respond to each other. The topics are all over the place and designed to help show the similarities and differences between the distributions, both in terms of goals and culture. Note that the Fedora project leader, Matthew Miller, was having an unusually busy time (both for work and personally), but he still made time to answer as many questions as he could. That, right there, is what I call dedication. Bryan (LJ): Introduce your Linux distribution (the short, elevator-pitch version—just a few sentences) and your role within it. Daniel (elementary): elementary is focused on growing the market for open-source software and chipping away at the share of our closed-source competitors. We believe in providing a great user experience for both new users and pro users, and putting a strong emphasis on security and privacy. We build elementary OS: a consumer-focused operating system for desktops and notebooks. My role at elementary is as Founder and CEO. I work with our various teams (like design, development, web and translation teams) to put together a cohesive vision, product roadmap and ensure that we're following an ethical path to sustainable funding. Chris (Debian): The Debian Project, which celebrated its 25th birthday this year, is one of the oldest and largest GNU/Linux distributions and is run on an entirely volunteer basis. Not only does it have stellar reputation for stability and technical excellence, it has a unwavering philosophical stance on free software (i.e., it comes with no proprietary software pre-installed and the main repository is only free software). As it underpins countless derivative distributions, such as Ubuntu, et al., it is uniquely poised and able to improve the Free Software world as a whole. The Debian Project Leader (DPL) is a curious beast. Far from being a BDFL—the DPL has no authoritative or deciding say in technical matters—the project leader is elected every year to a heady mix of figurehead, spokesperson and focus/contact point, but the DPL is also responsible for the quotidian business of keeping the project moving with respect to reducing bureaucracy and smoothing any and all roadblocks to Debian Developers' productivity. Matthew (Fedora): The Fedora distribution brings all of the innovation of thousands of upstream projects and hundreds of thousands of upstream developers together into a polished operating system for users, with releases on a six-month cadence. We're a community project tied together through the shared project mission and through the "four Fs" of our foundations: Freedom, Friends, Features and First. Something like 3,000 people contribute directly to Fedora in any given year, with a core active group of around 400 people participating in any given week. We just celebrated the 15th anniversary of our first release, but our history goes back even further than that to Red Hat Linux. I'm the Fedora Project Leader, a role funded by Red Hat—paying people to work on the project is the largest way Red Hat acts as a sponsor. It's not a dictatorial role; mostly, I collect good ideas and write short persuasive essays about them. Leadership responsibility is shared with the Fedora Council, which includes both funded roles, members selected by parts of the community and at-large elected representatives. Bryan (LJ): With introductions out of the way, let's start with this (perhaps deceptively) simple question: How many Linux distributions should there be? And why? Daniel (elementary): As long as there are a set of users who aren't getting their needs met by existing options, there's a purpose for any number of distros to exist. Some come and some go, and many are very very niche, but that's okay. I think there's a lot of people who are obsessed with trying to have some dominant player take a total monopoly, but in every other market category, it's immediately apparent how silly that idea is. You wouldn't want a single clothing manufacturer or a single restaurant chain or a single internet provider (wink hint nudge) to have total market dominance. Diversity and choice in the marketplace is good for customers, and I think it's no different when it comes to operating systems. Matthew (Fedora): [Responding to Daniel] Yes, I agree exactly. That said, creating an entirely from scratch distro is a lot of work, and a lot of it not very interesting work. If you've got something innovative at the how-we-put-the-OS-together level (like CoreOS), there's room for that, but if you're focused higher up the stack, like a new desktop environment or something else around user experience, it makes the most sense to make a derivative of one of the big community-powered distros. There's a lot of boring hard work, and it makes sense to reuse rather than carry those same rocks to the top of a slightly different hill. In Fedora, we're aiming to make custom distro creation as easy as possible. We have "spins", which are basically mini custom distros. This is stuff like the Python Classroom Lab or Fedora Jam (which is focused on musicians). We have a framework for making those within the Fedora project—I'm all about encouraging bigger, broader sharing and collaboration in Fedora. But if you want to work outside the project—say, you really have different ideas on free and open-source vs. proprietary software—we have Fedora Remixes that let you do that. Chris (Debian): The competing choice of distributions is often cited as a reason preventing Linux from becoming mainstream as it robs the movement of a consistent and focused marketing push. However, philosophical objections against monopolistic behaviour granted, the diversity and freedom that this bazaar of distributions affords is, in my view, paradoxically exactly why it has succeeded. That people are free—but more important, feel free—to create a new distribution as a means to try experimental or outlandish approaches to perceived problems is surely sufficient justification for some degree of proliferation or even duplication of effort. In this capacity, Debian's technical excellence, flexibility and deliberate lack of a top-down direction has resulted in it becoming the base underpinning countless derivatives, clearly and evidently able to provide the ingredients to build one's "own" distribution, often without overt credit. Matthew wrote: "if you want to work outside the project—say, you really have different ideas on free and open source vs. proprietary software—we have Fedora Remixes that let you do that." Given that, I would be curious to learn how you protect your reputation if you encourage, or people otherwise use your infrastructure, tools and possibly even your name to create and distribute works that are antithetical to the cause of software and user freedom? Bryan (LJ): Thinking about it from a slightly different angle—how many distros would be TOO many distros? Daniel (elementary): More than the market can sustain I guess? The thing about Linux is that it powers all kinds of stuff. So even for one non-technical person, they could still end up running a handful of distros for their notebook, their router, their phone someday, IoT devices, etc. So the number of distros that could exist sustainably could easily be in the hundreds or thousands, I think. Chris (Debian): If I may be so bold as to interpret this more widely, whilst it might look like we have "too many" distributions, I fear this might be misunderstanding the reasons why people are creating these newer offerings in the first place. Apart from the aforementioned distros created for technical experimentation, someone spinning up their own distribution might be (subconsciously!) doing it for the delight and satisfaction in building something themselves and having their name attached to it—something entirely reasonable and justifiable IMHO. To then read this creation through a lens of not being ideal for new users or even some silly "Linux worldwide domination" metric could therefore even be missing the point and some of the sheer delight of free software to begin with. Besides, the "market" for distributions seems to be doing a pretty good job of correcting itself. Bryan (LJ): Okay, since you guys brought it up, let's talk about world domination. How much of what you do (and what your teams do) is influenced by a desire to increase marketshare (either of your distribution specifically or desktop Linux in general)? Daniel (elementary): When we first started out, elementary OS was something we made for fun out of a desire to see something exist that we felt didn't yet. But as the company, and our user base, has grown, it's become more clear that our mission must be about getting open-source software in the hands of more people. As of now, our estimated userbase is somewhere in the hundreds of thousands with more than 75% of downloads coming from users of closed-source operating systems, so I think we're making good progress toward that goal. Making the company mission about reaching out to people directly has shaped the way we monetize, develop products, market and more, by ensuring we always put users' needs and experiences first. Chris (Debian): I think it would be fair to say that "increasing market share" is not an overt nor overly explicit priority for Debian. In our 25-year history, Debian has found that if we just continue to do good work, then good things will follow. That is not to say that other approaches can't work or are harmful, but chasing potentially chimeric concepts such as "market share" can very easily lead to negative outcomes in the long run. Matthew (Fedora): A project's user base is directly tied to its ability to have an effect in the world. If we were just doing cool stuff but no one used it, it really wouldn't matter much. And, no one really comes into working on a distro without having been a user first. So I guess to answer the question directly for me at least, it's pretty much all of it—even things that are not immediately related are about helping keep our community healthy and growing in the long term. Bryan (LJ): The three of you represent distros that are "funded" in very different ways. Fedora being sponsored (more or less) by Red Hat, elementary being its own company and Debian being, well, Debian. I would love to hear your thoughts around funding the work that goes into building a distribution. Is there a "right" or "ideal" way to fund that work (either from an ethical perspective or a purely practical one)? Chris (Debian): Clearly, melding "corporate interests" with the interests of a community distribution can be fraught with issues. I am always interested to hear how other distros separate influence and power particularly in terms of increasing transparency using tools such as Councils with community representation, etc. Indeed, this question of "optics" is often highly under-appreciated; it is simply not enough to be honest, you must be seen to be honest too. Unfortunately, whilst I would love to be able to say that Debian is by-definition free (!) of all such problems by not having a "big sister" company sitting next to it, we have a long history of conversations regarding the role of money in funding contributors. For example, is it appropriate to fund developers to do work that might not not be done otherwise? And if it is paid for, isn't this simply a feedback loop that effectively ensures that this work will cease to within the remit of volunteers. There are no easy answers and we have no firm consensus, alas. Daniel (elementary): I'm not sure that there's a single right way, but I think we have the opinion that there are some wrong ways. The biggest questions we're always trying to ask about funding are where it's coming from and what it's incentivizing. We've taken a hard stance that advertising income is not in the interest of our users. When companies make their income from advertising, they tend to have to make compromises to display advertising content instead of the things their users actually want to see, and oftentimes are they incentivized to invade their users' privacy in order to target ads more effectively. We've also chosen to avoid big enterprise markets like server and IoT, because we believe that since companies will naturally be incentivized to work on products that turn a profit, that making that our business model would result in things like the recent Red Hat acquisition or in killing products that users love, like Ubuntu's Unity. Instead, we focus on things like individual sales of software directly to our users, bug bounties, Patreon, etc. We believe that doing business directly with our users incentivizes the company to focus on features and products that are in the benefit of those paying customers. Whenever a discussion comes up about how elementary is funded, we always make a point to evaluate if that funding incentivizes outcomes that are ethical and in the favor of our users. Regarding paying developers, I think elementary is a little different here. We believe that people writing open-source software should be able to make a living doing it. We owe a lot to our volunteer community, and the current product could not be possible without their hard work, but we also have to recognize that there's a significant portion of work that would never get done unless someone is being paid to do it. There are important tasks that are difficult or menial, and expecting someone to volunteer their time to them after their full work day is a big ask, especially if the people knowledgeable in these domains would have to take time away from their families or personal lives to do so. Many tasks are also just more suited to sustained work and require the dedicated attention of a single person for several weeks or months instead of some attention from multiple people over the span of years. So I think we're pretty firmly in the camp that not only is it important for some work to be paid, but the eventual goal should be that anyone writing open-source code should be able to get paid for their contributions. Chris (Debian): Daniel wrote: "So I think we're pretty firmly in the camp that not only is it important for some work to be paid, but the eventual goal should be that anyone writing open-source code should be able to get paid." Do you worry that you could be creating a two-tier community with this approach? Not only in terms of hard influence (eg. if I'm paid, I'm likely to be able to simply spend longer on my approach) but moreover in terms of "soft" influence during discussions or by putting off so-called "drive-thru" contributions? Do you do anything to prevent the appearance of this? Matthew (Fedora): Chris wrote: "Do you worry that you could be creating a two-tier community with this approach?" Yeah, this is a big challenge for us. We have many people who are paid by Red Hat to work on Fedora either full time or as part of their job, and that gives a freedom to just be around a lot more, which pretty much directly translates to influence. Right now, many of the community-elected positions in Fedora leadership are filled by Red Hatters, because they're people the community knows and trusts. It takes a lot of time and effort to build up that visibility when you have a different day job. But there's some important nuances here too, because many of these Red Hatters aren't actually paid to work on Fedora at all—they're doing it just like anyone else who loves the project. Daniel (elementary): Chris wrote: "Do you worry that you could be creating a two-tier community with this approach?" It's possible, but I'm not sure that we've measured anything to this effect. I think you might be right that employees at elementary can have more influence just as a byproduct of having more time to participate in more discussions, but I wouldn't say that volunteers' opinions are discounted in any way or that they're underrepresented when it comes to major technical decisions. I think it's more that we can direct laborafter design and architecture decisions have been discussed. As an example, we recently had decided to make the switch from CMake to Meson. This was a group discussion primarily led by volunteers, but the actual implementation was then largely carried out by employees. Chris (Debian): Daniel wrote: "Do you worry that you could be creating a two-tier community with this approach? ... It's possible, but I'm not sure that we've measured anything to this effect." I think it might be another one of those situations where the optics in play is perhaps as important as the reality. Do you do anything to prevent the appearance of any bias? Not sure how best to frame it hypothetically, but if I turned up to your project tomorrow and learned that some developers were paid for their work (however fairly integrated in practice), that would perhaps put me off investing my energy. Bryan (LJ): What do you see as the single biggest challenge currently facing both your specific project—and desktop Linux in general? Daniel (elementary): Third-party apps! Our operating systems are valuable to people only if they can use them to complete the tasks that they care about. Today, that increasingly means using proprietary services that tie in to closed-source and non-native apps that often have major usability and accessibility problems. Even major open-source apps like Firefox don't adhere to free desktop standards like shipping a .desktop file or take advantage of new cross-desktop metadata standards like AppStream. If we want to stay relevant for desktop users, we need to encourage the development of native open-source apps and invest in non-proprietary cloud services and social networks. The next set of industry-disrupting apps (like DropBox, Sketch, Slack, etc.) need to be open source and Linux-first. Chris (Debian): Third-party apps/stores are perhaps the biggest challenge facing all distributions within the medium- to long-term, but whilst I would concede there are cultural issues in play here, I believe they have some element of being technical challenges or at least having some technical ameliorations. More difficult, however, is that our current paradigms of what constitutes software freedom are becoming difficult to square with the increased usage of cloud services. In the years ahead we may need to revise our perspectives, ideas and possibly even our definitions of what constitutes free software. There will be a time when the FLOSS community will have to cease the casual mocking of "cloud" and acknowledge the reality that it is, regardless of one's view of it, here to stay. Matthew (Fedora): For desktop Linux, on the technical side, I'm worried about hardware enablement—not just the work dealing with driver compatibility and proprietary hardware, but more fundamentally, just being locked out. We've just seen Apple come out with hardware locked so Linux won't even boot—even with signed kernels. We're going to see more of that, and more tablets and tablet-keyboard combos with similar locked, proprietary operating systems. A bigger worry I have is with bringing the next generation to open source—a lot of Fedora core contributors have been with the project since it started 15 years ago, which on the one hand is awesome, but also, we need to make sure that we're not going to end up with no new energy. When I was a kid, I got into computers through programming BASIC on an Apple ][. I could see commercial software and easily imagine myself making the same kind of thing. Even the fanciest games on offer—I could see the pixels and could use PEEK and POKE to make those beeps and boops. But now, with kids getting into computers via Fortnite or whatever, that's not something one can just sit down and make an approximation of as a middle-school kid. That's discouraging and makes a bigger hill to climb. This is one reason I'm excited about Fedora IoT—you can use Linux and open source at a tinkerer's level to make something that actually has an effect on the world around you, and actually probably a lot betterthan a lot of off-the-shelf IoT stuff. Bryan (LJ): Where do you see your distribution in five years? What will be its place be in the broader Linux and computing world? Chris (Debian): Debian naturally faces some challenges in the years ahead, but I sincerely believe that the Project remains as healthy as ever. We are remarkably cherished and uniquely poised to improve the free software ecosystem as a whole. Moreover, our stellar reputation for technical excellence, stability and software freedom remains highly respected where losing this would surely be the beginning of the end for Debian. Daniel (elementary): Our short-term goals are mostly about growing our third-party app ecosystem and improving our platform. We're investing a lot of time into online accounts integration and working with other organizations, like GNOME, to make our libraries and tooling more compelling. Sandboxed packaging and Wayland will give us the tools to help keep our users' data private and to keep their operating system stable and secure. We're also working with OEMs to make elementary OS more shippable and to give users a way to get an open-source operating system when they buy a new computer. Part of that work is the new installer that we're collaborating with System76 to develop. Overall, I'd say that we're going to continue to make it easier to switch away from closed-source operating systems, and we're working on increasing collaborative efforts to do that. Bryan (LJ): When you go to a FOSS or Linux conference and see folks using Mac and Windows PCs, what's your reaction? Is it a good thing or a bad thing when developers of Linux software primarily use another platform? Chris (Debian): Rushing to label this as a "good" or "bad" thing can make it easy to miss the underlying and more interesting lessons we can learn here. Clearly, if everyone was using a Linux-based operating system, that would be a better state of affairs, but if we are overly quick to dismiss the usage of Mac systems as "bad", then we can often fail to understand why people have chosen to adopt the trade-offs of these platforms in the first place. By not demonstrating sufficient empathy for such users as well as newcomers or those without our experience, we alienate potential users and contributors and tragically fail to communicate our true message. Basically, we can be our own worst enemy sometimes. Daniel (elementary): Within elementary, we strongly believe in dogfood, but I think when we see someone at a conference using a closed-source operating system, it's a learning opportunity. Instead of being upset about it or blaming them, we should be asking why we haven't been able to make a conversion. We need to identify if the problem is a missing product, feature, or just with outreach and then address that. Bryan (LJ): How often do you interact with the leaders of other distributions? And is that the right amount? Chris (Debian): Whilst there are a few meta-community discussion groups around, they tend to have a wider focus, so yes, I think we could probably talk a little more, even just as a support group or a place to rant! More seriously though, this conversation itself has been fairly insightful, and I've learned a few things that I think I "should" have known already, hinting that we could be doing a better job here. Daniel (elementary): With other distros, not too often. I think we're a bit more active with our partners, upstreams and downstreams. It's always interesting to hear about how someone else tackles a problem, so I would be interested in interacting more with others, but in a lot of cases, I think there are philosophical or technical differences that mean our solutions might not be relevant for other distros. Bryan (LJ): Is there value in the major distributions standardizing on package management systems? Should that be done? Can that be done? Chris (Debian): I think I would prefer to see effort go toward consistent philosophical outlooks and messaging on third-party apps and related issues before I saw energy being invested into having a single package management format. I mean, is this really the thing that is holding us all back? I would grant there is some duplication of effort, but I'm not sure it is the most egregious example and—as you suggest—it is not even really technically feasible or is at least subject to severe diminishing returns. Daniel (elementary): For users, there's a lot of value in being able to sideload cross-platform, closed-source apps that they rely on. But outside of this use case, I'm not sure that packaging is much more than an implementation detail as far as our users are concerned. I do think though that developers can benefit from having more examples and more documentation available, and the packaging formats can benefit from having a diverse set of implementations. Having something like Flatpak or Snap become as well accepted as SystemD would probably be good in the long run, but our users probably never noticed when we switched from Upstart, and they probably won't notice when we switch from Debian packages.
·   0

Unit Testing in the Linux Kernel

Brendan Higgins recently proposed adding unit tests to the Linux kernel, supplementing other development infrastructure such as perf, autotest and kselftest. The whole issue of testing is very dear to kernel developers' hearts, because Linux sits at the core of the system and often has a very strong stability/security requirement. Hosts of automated tests regularly churn through kernel source code, reporting any oddities to the mailing list. Unit tests, Brendan said, specialize in testing standalone code snippets. It was not necessary to run a whole kernel, or even to compile the kernel source tree, in order to perform unit tests. The code to be tested could be completely extracted from the tree and tested independently. Among other benefits, this meant that dozens of unit tests could be performed in less than a second, he explained. Giving credit where credit was due, Brendan identified JUnit, Python's unittest.mock and Googletest/Googlemock for C++ as the inspirations for this new KUnit testing idea. Brendan also pointed out that since all code being unit-tested is standalone and has no dependencies, this meant the tests also were deterministic. Unlike on a running Linux system, where any number of pieces of the running system might be responsible for a given problem, unit tests would identify problem code with repeatable certainty. Daniel Vetter replied extremely enthusiastically to Brendan's work. In particular, he said, "Having proper and standardized infrastructure for kernel unit tests sounds terrific. In other words: I want." He added that he and some others already had been working on a much more specialized set of unit tests for the Direct Rendering Manager (DRM) driver. Brendan's approach, he said, would be much more convenient than his own more localized efforts. Dan Williams was also very excited about Brendan's work, and he said he had been doing a half-way job of unit tests on the libnvdimm (non-volatile device) project code. He felt Brendan's work was much more general-purpose, and he wanted to convert his own tests to use KUnit. Tim Bird replied to Brendan's initial email as well, saying he thought unit tests could be useful, but he wanted to make sure the behaviors were correct. In particular, he wanted clarification on just how it was possible to test standalone code. If the code were to be compiled independently, would it then run on the local system? What if the local system had a different hardware architecture from the system for which the code was intended? Also, who would maintain unit tests, and where would the tests live, within the source tree? Would they clutter up the directory being tested, or would they live far away in a special directory reserved for test code? And finally, would test code be easier to write than the code being tested? In other words, could new developers cut their teeth on a project by writing test code, as a gateway to helping work on a given driver or subsystem? Or would unit tests have to be written by people who had total expertise in the area already? Brendan attempted to address each of those issues in turn. To start, he confirmed that the test code was indeed extracted and compiled on the local system. Eventually, he said, each test would compile into its own completely independent test binary, although for the moment, they were all lumped together into a single user-mode-linux (UML) binary. In terms of cross-compiling test code for other architectures, Brendan felt this would be hard to maintain and had decided not to support it. Tests would run locally and would not depend on architecture-specific characteristics. In terms of where the unit tests would live, Brendan said they would be in the same directory as the code being tested. So every directory would have its own set of unit tests readily available and visible. The same person maintaining the code being tested would maintain the tests themselves. The unit tests, essentially, would become an additional element of every project. That maintainer would then presumably require that all patches to that driver or subsystem pass all the unit tests before they could be accepted into the tree. In terms of who was qualified to write unit tests for a given project, Brendan explained: In order to write a unit test, the person who writes the test must understand what the code they are testing is supposed to do. To some extent that will probably require someone with some expertise to ensure that the test makes sense, and indeed a change that breaks a test should be accompanied by an update to the test. On the other hand, I think understanding what pre-existing code does and is supposed to do is much easier than writing new code from scratch, and probably doesn't require too much expertise. Brendan added that unit tests would probably reduce, rather than increase, a maintainer's workload. In spite of representing more code overall: Code with unit tests is usually cleaner, the tests tell me exactly what the code is supposed to do, and I can run the tests (or ideally have an automated service run the tests) that tell me that the code actually does what the tests say it should. Even when it comes to writing code, I find that writing code with unit tests ends up saving me time. Overall, Brendan was very pleased by all the positive interest, and said he planned to do additional releases to address the various technical suggestions that came up during the course of discussion. No voices really were raised in opposition to any of Brendan's ideas. It appears that unit tests may soon become a standard part of many drivers and subsystems. Note: if you're mentioned above and want to post a response above the comment section, send a message with your response text to ljeditor@linuxjournal.com.
·   0

Removing Duplicate PATH Entries: Reboot

In my first post on removing duplicate PATH entries I used an AWK one-liner. In the second post I used a Perl one-liner, or more accurately, I tried to dissect a Perl one-liner provided by reader Shaun. Shaun had asked that if I was willing to use AWK (not Bash), why not use Perl? It occurred to me that one might also ask: why not just use Bash? So, one more time into the void. For those who made it through the second post, don't worry; this one should be mercifully short by comparison. And although I could make it a one-liner by using lots of semicolons, I won't do that either. The approach remains pretty much the same as in the AWK and Perl versions of the code: split the path on colons, use an associative array to determine whether a path element has been seen before, and then join the non-duplicate path elements back together with colons. Note that I incorrectly stated in my previous posts that empty path elements also could be eliminated in this process. In reality, empty path elements are the same as putting "." in your path; it means the current directory. This error on my part was pointed out in a comment to the second post. I guess I should have read the man page. To split the PATH into its individual elements, I'll change bash's record separator to a colon and then assign the PATH variable to an array: IFS=: ipaths=($PATH) Note the assignment to IFS on the same line as the assignment to the array; if you haven't seen this before, it's standard bash syntax: A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator. Now that I have the path elements in the paths variable, I crank up an associative array and test each element to see if it's in the array (again, remember that in bash, array elements that don't exist will evaluate to blank): declare -A a # Need to declare the array as associative for p in "${ipaths[@]}" do [[ -z "${a[$p]}" ]] && a[$p]=1 && opaths+=":$p" done The loop steps through each path element in the ipaths array and creates the new path in a variable named opaths. The body of the loop tests to see if the current path element's array entry is blank ([[ -z"${a[$p]}" ]]), which means that the path has not been seen before. If it hasn't been seen before, it sets the path element's array entry to something non-blank (a[$p]=1) and then adds the path element, the variable containing the output path opaths+=":$p" (colons added here). Unfortunately, that fails for blank path elements: blank associative array keys are not allowed in bash. To fix that, I'll use a separate variable to determine if a blank path has been seen before. Another option would be to change "::" to something like "*CURRENT_DIR*" before processing the path and then change it back afterward. The new loop looks like this: declare -A a for p in "${ipaths[@]}" do if [[ -z "$p" ]]; then [[ -z "$currdir" ]] && currdir=1 && opaths+=":" else [[ -z "${a[$p]}" ]] && a[$p]=1 && opaths+=":$p" fi done Since all the output paths are preceded by a colon, even the first one, the final output path needs to have the first colon removed. I do this with a simple substring evaluation: export PATH="${opaths:1}" Short and sweet. It's not as short as the Perl version or the original AWK version, but I could just put the code above into a bash function and pretend this version is really short: export PATH="$(remove_path_dupes)" I can only hope that this is the last time I write about removing duplicates from the PATH variable, but I can't make any guarantees. Edit: the following is an addendum to my original post. A comment by a reader "pepa65" on the previous posts suggested another all-bash solution, and quite frankly, it's a much slicker solution than mine: IPATH='/usr/bin:/usr/local/bin::/usr/bin:/some folder/j:' OPATH=$(n= IFS=':'; for e in $IPATH; do [[ :$n == *:$e:* ]] || n+=$e:; done; echo "${n:0: -1}") echo $IPATH echo $OPATH To make it a bit easier to see, I'll unroll the part inside the command substitution (the $(...) expression): n= IFS=':' for e in $IPATH do [[ :$n == *:$e:* ]] || n+=$e: done echo "${n:0: -1}" Rather than using an associative array to see if a path element is in the output path, it simply uses a globcomparison to see if the path element is already found in the output path variable. At first you may be wondering why this even works, because in the section on pathname expansion (aka glob), the bash man page states: After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern... And we certainly don't want the asterisks in the pattern to expand to a list of filenames. But that's not a concern, because in the section about [[ expression ]] evaluation, the man page states: ... Word splitting and pathname expansion are not performed on the words between the [[ and ]] ... So pathname expansion does not happen. To get to why it actually works, continue reading the [[expression ]] section, and a bit further down you'll see: When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching, as if the extglob shell option were enabled. ... Note that like the bash regular expression operator =~, when pattern matching is involved, these operators are not symmetric, so the following won't work:
·   0