Debian Brasil: Oficina de tradu o do Manual do(a) Administrador(a) Debian em 13 de junho

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def parse_plain_text_body(text): lines = text.splitlines() for i, line in enumerate(lines): if line == 'Reply to this email directly or view it on GitHub:': return lines[i + 1].split('#')[0] if (line == 'For more details, see:' and lines[i + 1].startswith('https://code.launchpad.net/')): return lines[i + 1] try: (field, value) = line.split(':', 1) except ValueError: continue if field.lower() == 'merge request url': return value.strip() return None |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | pub fn parse_plain_text_body(text: &str) -> Option<String> let lines: Vec<&str> = text.lines().collect(); for (i, line) in lines.iter().enumerate() if line == &"Reply to this email directly or view it on GitHub:" return Some(lines[i + 1].split('#').next().unwrap().to_string()); if line == &"For more details, see:" && lines[i + 1].starts_with("https://code.launchpad.net/") return Some(lines[i + 1].to_string()); if let Some((field, value)) = line.split_once(':') if field.to_lowercase() == "merge request url" return Some(value.trim().to_string()); None |
1 2 3 4 5 6 7 8 9 10 11 12 13 | use pyo3::prelude::*; #[pyfunction] fn parse_plain_text_body(text: &str) -> Option<String> janitor_mail_filter::parse_plain_text_body(text) #[pymodule] pub fn _mail_filter(py: Python, m: &PyModule) -> PyResult<()> m.add_function(wrap_pyfunction!(parse_plain_text_body, m)?)?; Ok(()) |
1 2 3 4 5 6 7 8 9 10 11 12 | [package] name = "mailfilter-py" version = "0.0.0" authors = ["Jelmer Vernoo <jelmer@jelmer.uk>"] edition = "2018" [lib] crate-type = ["cdylib"] [dependencies] janitor-mail-filter = path = "../mailfilter" pyo3 = version = ">=0.14", features = ["extension-module"] |
1 2 3 4 5 6 7 8 9 | #!/usr/bin/python3 from setuptools import setup from setuptools_rust import RustExtension, Binding setup( rust_extensions=[RustExtension( "janitor._mailfilter", "crates/mailfilter-py/Cargo.toml", binding=Binding.PyO3)], ) |
1 | from ._mailfilter import parse_plain_text_body |
The Debian Janitor is an automated system that commits fixes for (minor) issues in Debian packages that can be fixed by software. It gradually started proposing merges in early December. The first set of changes sent out ran lintian-brush on sid packages maintained in Git. This post is part of a series about the progress of the Janitor. Kali Linux have been running their own instance of the Janitor for the last year, under the kali-bot user on GitLab. Their web site has some excellent documentation explaining how the bot works. Both projects share some common components - the core janitor codebase, Silver-Platter and the various codemods (lintian-brush and deb-new-upstream). The site and some of the review logic is different for Kali. The Kali bot has several campaigns:
The last campaign doesn t exist in the Debian janitor, and pulls in new changes from packages that have been imported from other distributions.For more information about the Janitor s lintian-fixes efforts, see the landing page.
Publisher: | Penguin Books |
Copyright: | 2005 |
ISBN: | 1-4406-2476-3 |
Format: | Kindle |
Pages: | 835 |
On one thing, however, all were agreed resisters and politicians alike: "planning". The disasters of the inter-war decades the missed opportunities after 1918, the great depression that followed the stock-market crash of 1929, the waste of unemployment, the inequalities, injustices and inefficiencies of laissez-faire capitalism that had led so many into authoritarian temptation, the brazen indifference of an arrogant ruling elite and the incompetence of an inadequate political class all seemed to be connected by the utter failure to organize society better. If democracy was to work, if it was to recover its appeal, it would have to be planned.It's one thing to be familiar with the basic economic and political arguments between degrees of free market and planned economies. It's quite another to understand how the appeal of one approach or the discredit of another stems from recent historical experience, and that's what a good history can provide. Judt does not hesitate to draw these sorts of conclusions, and I'm sure some of them are controversial. But while he's opinionated, he's rarely ideological, and he offers no grand explanations. His discussion of the Yugoslav Wars stands out as an example: he mentions various theories of blame (a fraught local ethnic history, the decision by others to not intervene until the situation was truly dire), but largely discards them. Judt's offered explanation is that local politicians saw an opportunity to gain power by inflaming ethnic animosity, and a large portion of the population participated in this process, either passively or eagerly. Other explanations are both unnecessarily complex and too willing to deprive Yugoslavs of agency. I found this refreshingly blunt. When is more complex analysis a way to diffuse responsibility and cling to an ideological fantasy that the right foreign policy would have resolved a problem? A few personal grumblings do creep in, particularly in the chapters on the 1970s (and I think it's not a coincidence that this matches Judt's own young adulthood, a time when one is prone to forming a lot of opinions). There is a brief but stinging criticism of postmodernism in scholarship, which I thought was justified but probably incomplete, and a decidedly grumpy dismissal of punk music, which I thought was less fair. But these are brief asides that don't detract from the overall work. Indeed, they, along with the occasional wry asides ("respecting long-established European practice, no one asked the Poles for their views [on Poland's new frontiers]") add a lot of character. Insofar as this book has a thesis, it's in the implications of the title: Europe only exited the postwar period at the end of the 20th century. Political stability through exhaustion, the overwhelming urgency of economic recovery, and the degree to which the Iron Curtain and the Cold War froze eastern Europe in amber meant that full European recovery from World War II was drawn out and at times suspended. It's only after 1989 and its subsequent upheavals that European politics were able to move beyond postwar concerns. Some of that movement was a reemergence of earlier European politics of nations and ethnic conflict. But, new on the scene, was a sense of identity as Europeans, one that western Europe circled warily and eastern Europe saw as the only realistic path forward.
What binds Europeans together, even when they are deeply critical of some aspect or other of its practical workings, is what it has become conventional to call in disjunctive but revealing contrast with "the American way of life" the "European model of society".Judt also gave me a new appreciation of how traumatic people find the assignment of fault, and how difficult it is to wrestle with guilt without providing open invitations to political backlash. People will go to great lengths to not feel guilty, and pressing the point runs a substantial risk of creating popular support for ideological movements that are willing to lie to their followers. The book's most memorable treatment of this observation is in the epilogue, which traces popular European attitudes towards the history of the Holocaust through the whole time period. The largest problem with this book is that it is dense and very long. I'm a fairly fast reader, but this was the only book I read through most of my holiday vacation and it still took a full week into the new year to finish it. By the end, I admit I was somewhat exhausted and ready to be finished with European history for a while (although the epilogue is very much worth waiting for). If you, unlike me, can read a book slowly among other things, that may be a good tactic. But despite feeling like this was a slog at times, I'm very glad that I read it. I'm not sure if someone with a firmer grounding in European history would have gotten as much out of it, but I, at least, needed something this comprehensive to wrap my mind around the timeline and fill in some embarrassing gaps. Judt is not the most entertaining writer (although he has his moments), and this is not the sort of popular history that goes out of its way to draw you in, but I found it approachable and clear. If you're looking for a solid survey of modern European history with this type of high-level focus, recommended. Rating: 8 out of 10
War and Peace (1867) Leo Tolstoy It's strange to think that there is almost no point in reviewing this novel: who hasn't heard of War and Peace? What more could possibly be said about it now? Still, when I was growing up, War and Peace was always the stereotypical example of the 'impossible book', and even start it was, at best, a pointless task, and an act of hubris at worst. And so there surely exists a parallel universe in which I never have and will never will read the book... Nevertheless, let us try to set the scene. Book nine of the novel opens as follows:
On the twelfth of June, 1812, the forces of Western Europe crossed the Russian frontier and war began; that is, an event took place opposed to human reason and to human nature. Millions of men perpetrated against one another such innumerable crimes, frauds, treacheries, thefts, forgeries, issues of false money, burglaries, incendiarisms and murders as in whole centuries are not recorded in the annals of all the law courts of the world, but which those who committed them did not at the time regard as being crimes. What produced this extraordinary occurrence? What were its causes? [ ] The more we try to explain such events in history reasonably, the more unreasonable and incomprehensible they become to us.Set against the backdrop of the Napoleonic Wars and Napoleon's invasion of Russia, War and Peace follows the lives and fates of three aristocratic families: The Rostovs, The Bolkonskys and the Bezukhov's. These characters find themselves situated athwart (or against) history, and all this time, Napoleon is marching ever closer to Moscow. Still, Napoleon himself is essentially just a kind of wallpaper for a diverse set of personal stories touching on love, jealousy, hatred, retribution, naivety, nationalism, stupidity and much much more. As Elif Batuman wrote earlier this year, "the whole premise of the book was that you couldn t explain war without recourse to domesticity and interpersonal relations." The result is that Tolstoy has woven an incredibly intricate web that connects the war, noble families and the everyday Russian people to a degree that is surprising for a book started in 1865. Tolstoy's characters are probably timeless (especially the picaresque adventures and constantly changing thoughts Pierre Bezukhov), and the reader who has any social experience will immediately recognise characters' thoughts and actions. Some of this is at a 'micro' interpersonal level: for instance, take this example from the elegant party that opens the novel:
Each visitor performed the ceremony of greeting this old aunt whom not one of them knew, not one of them wanted to know, and not one of them cared about. The aunt spoke to each of them in the same words, about their health and her own and the health of Her Majesty, who, thank God, was better today. And each visitor, though politeness prevented his showing impatience, left the old woman with a sense of relief at having performed a vexatious duty and did not return to her the whole evening.But then, some of the focus of the observations are at the 'macro' level of the entire continent. This section about cities that feel themselves in danger might suffice as an example:
At the approach of danger, there are always two voices that speak with equal power in the human soul: one very reasonably tells a man to consider the nature of the danger and the means of escaping it; the other, still more reasonably, says that it is too depressing and painful to think of the danger, since it is not in man s power to foresee everything and avert the general course of events, and it is therefore better to disregard what is painful till it comes and to think about what is pleasant. In solitude, a man generally listens to the first voice, but in society to the second.And finally, in his lengthy epilogues, Tolstoy offers us a dissertation on the behaviour of large organisations, much of it through engagingly witty analogies. These epilogues actually turn out to be an oblique and sarcastic commentary on the idiocy of governments and the madness of war in general. Indeed, the thorough dismantling of the 'great man' theory of history is a common theme throughout the book:
During the whole of that period [of 1812], Napoleon, who seems to us to have been the leader of all these movements as the figurehead of a ship may seem to a savage to guide the vessel acted like a child who, holding a couple of strings inside a carriage, thinks he is driving it. [ ] Why do [we] all speak of a military genius ? Is a man a genius who can order bread to be brought up at the right time and say who is to go to the right and who to the left? It is only because military men are invested with pomp and power and crowds of sychophants flatter power, attributing to it qualities of genius it does not possess.Unlike some other readers, I especially enjoyed these diversions into the accounting and workings of history, as well as our narrow-minded way of trying to 'explain' things in a singular way:
When an apple has ripened and falls, why does it fall? Because of its attraction to the earth, because its stalk withers, because it is dried by the sun, because it grows heavier, because the wind shakes it, or because the boy standing below wants to eat it? Nothing is the cause. All this is only the coincidence of conditions in which all vital organic and elemental events occur. And the botanist who finds that the apple falls because the cellular tissue decays and so forth is equally right with the child who stands under the tree and says the apple fell because he wanted to eat it and prayed for it.Given all of these serious asides, I was also not expecting this book to be quite so funny. At the risk of boring the reader with citations, take this sarcastic remark about the ineptness of medicine men:
After his liberation, [Pierre] fell ill and was laid up for three months. He had what the doctors termed 'bilious fever.' But despite the fact that the doctors treated him, bled him and gave him medicines to drink he recovered.There is actually a multitude of remarks that are not entirely complimentary towards Russian medical practice, but they are usually deployed with an eye to the human element involved rather than simply to the detriment of a doctor's reputation "How would the count have borne his dearly loved daughter s illness had he not known that it was costing him a thousand rubles?" Other elements of note include some stunning set literary pieces, such as when Prince Andrei encounters a gnarly oak tree under two different circumstances in his life, and when Nat sha's 'Russian' soul is awakened by the strains of a folk song on the balalaika. Still, despite all of these micro- and macro-level happenings, for a long time I felt that something else was going on in War and Peace. It was difficult to put into words precisely what it was until I came across this passage by E. M. Forster:
After one has read War and Peace for a bit, great chords begin to sound, and we cannot say exactly what struck them. They do not arise from the story [and] they do not come from the episodes nor yet from the characters. They come from the immense area of Russia, over which episodes and characters have been scattered, from the sum-total of bridges and frozen rivers, forests, roads, gardens and fields, which accumulate grandeur and sonority after we have passed them. Many novelists have the feeling for place, [but] very few have the sense of space, and the possession of it ranks high in Tolstoy s divine equipment. Space is the lord of War and Peace, not time.'Space' indeed. Yes, potential readers should note the novel's great length, but the 365 chapters are actually remarkably short, so the sensation of reading it is not in the least overwhelming. And more importantly, once you become familiar with its large cast of characters, it is really not a difficult book to follow, especially when compared to the other Russian classics. My only regret is that it has taken me so long to read this magnificent novel and that I might find it hard to find time to re-read it within the next few years.
Coming Up for Air (1939) George Orwell It wouldn't be a roundup of mine without at least one entry from George Orwell, and, this year, that place is occupied by a book I hadn't haven't read in almost two decades Still, the George Bowling of Coming Up for Air is a middle-aged insurance salesman who lives in a distinctly average English suburban row house with his nuclear family. One day, after winning some money on a bet, he goes back to the village where he grew up in order to fish in a pool he remembers from thirty years before. Less important than the plot, however, is both the well-observed remarks and scathing criticisms that Bowling has of the town he has returned to, combined with an ominous sense of foreboding before the Second World War breaks out. At several times throughout the book, George's placid thoughts about his beloved carp pool are replaced by racing, anxious thoughts that overwhelm his inner peace:
War is coming. In 1941, they say. And there'll be plenty of broken crockery, and little houses ripped open like packing-cases, and the guts of the chartered accountant's clerk plastered over the piano that he's buying on the never-never. But what does that kind of thing matter, anyway? I'll tell you what my stay in Lower Binfield had taught me, and it was this. IT'S ALL GOING TO HAPPEN. All the things you've got at the back of your mind, the things you're terrified of, the things that you tell yourself are just a nightmare or only happen in foreign countries. The bombs, the food-queues, the rubber truncheons, the barbed wire, the coloured shirts, the slogans, the enormous faces, the machine-guns squirting out of bedroom windows. It's all going to happen. I know it - at any rate, I knew it then. There's no escape. Fight against it if you like, or look the other way and pretend not to notice, or grab your spanner and rush out to do a bit of face-smashing along with the others. But there's no way out. It's just something that's got to happen.Already we can hear psychological madness that underpinned the Second World War. Indeed, there is no great story in Coming Up For Air, no wonderfully empathetic characters and no revelations or catharsis, so it is impressive that I was held by the descriptions, observations and nostalgic remembrances about life in modern Lower Binfield, its residents, and how it has changed over the years. It turns out, of course, that George's beloved pool has been filled in with rubbish, and the village has been perverted by modernity beyond recognition. And to cap it off, the principal event of George's holiday in Lower Binfield is an accidental bombing by the British Royal Air Force. Orwell is always good at descriptions of awful food, and this book is no exception:
The frankfurter had a rubber skin, of course, and my temporary teeth weren't much of a fit. I had to do a kind of sawing movement before I could get my teeth through the skin. And then suddenly pop! The thing burst in my mouth like a rotten pear. A sort of horrible soft stuff was oozing all over my tongue. But the taste! For a moment I just couldn't believe it. Then I rolled my tongue around it again and had another try. It was fish! A sausage, a thing calling itself a frankfurter, filled with fish! I got up and walked straight out without touching my coffee. God knows what that might have tasted of.Many other tell-tale elements of Orwell's fictional writing are in attendance in this book as well, albeit worked out somewhat less successfully than elsewhere in his oeuvre. For example, the idea of a physical ailment also serving as a metaphor is present in George's false teeth, embodying his constant preoccupation with his ageing. (Readers may recall Winston Smith's varicose ulcer representing his repressed humanity in Nineteen Eighty-Four). And, of course, we have a prematurely middle-aged protagonist who almost but not quite resembles Orwell himself. Given this and a few other niggles (such as almost all the women being of the typical Orwell 'nagging wife' type), it is not exactly Orwell's magnum opus. But it remains a fascinating historical snapshot of the feeling felt by a vast number of people just prior to the Second World War breaking out, as well as a captivating insight into how the process of nostalgia functions and operates.
Howards End (1910) E. M. Forster Howards End begins with the following sentence:
One may as well begin with Helen s letters to her sister.In fact, "one may as well begin with" my own assumptions about this book instead. I was actually primed to consider Howards End a much more 'Victorian' book: I had just finished Virginia Woolf's Mrs Dalloway and had found her 1925 book at once rather 'modern' but also very much constrained by its time. I must have then unconsciously surmised that a book written 15 years before would be even more inscrutable, and, with its Victorian social mores added on as well, Howards End would probably not undress itself so readily in front of the reader. No doubt there were also the usual expectations about 'the classics' as well. So imagine my surprise when I realised just how inordinately affable and witty Howards End turned out to be. It doesn't have that Wildean shine of humour, of course, but it's a couple of fields over in the English countryside, perhaps abutting the more mordant social satires of the earlier George Orwell novels (see Coming Up for Air above). But now let us return to the story itself. Howards End explores class warfare, conflict and the English character through a tale of three quite different families at the beginning of the twentieth century: the rich Wilcoxes; the gentle & idealistic Schlegels; and the lower-middle class Basts. As the Bloomsbury Group Schlegel sisters desperately try to help the Basts and educate the rich but close-minded Wilcoxes, the three families are drawn ever closer and closer together. Although the whole story does, I suppose, revolve around the house in the title (which is based on the Forster's own childhood home), Howards End is perhaps best described as a comedy of manners or a novel that shows up the hypocrisy of people and society. In fact, it is surprising how little of the story actually takes place in the eponymous house, with the overwhelming majority of the first half of the book taking place in London. But it is perhaps more illuminating to remark that the Howards End of the book is a house that the Wilcoxes who own it at the start of the novel do not really need or want. What I particularly liked about Howards End is how the main character's ideals alter as they age, and subsequently how they find their lives changing in different ways. Some of them find themselves better off at the end, others worse. And whilst it is also surprisingly funny, it still manages to trade in heavier social topics as well. This is apparent in the fact that, although the characters themselves are primarily in charge of their own destinies, their choices are still constrained by the changing world and shifting sense of morality around them. This shouldn't be too surprising: after all, Forster's novel was published just four years before the Great War, a distinctly uncertain time. Not for nothing did Virginia Woolf herself later observe that "on or about December 1910, human character changed" and that "all human relations have shifted: those between masters and servants, husbands and wives, parents and children." This process can undoubtedly be seen rehearsed throughout Forster's Howards End, and it's a credit to the author to be able to capture it so early on, if not even before it was widespread throughout Western Europe. I was also particularly taken by Forster's fertile use of simile. An extremely apposite example can be found in the description Tibby Schlegel gives of his fellow Cambridge undergraduates. Here, Timmy doesn't want to besmirch his lofty idealisation of them with any banal specificities, and wishes that the idea of them remain as ideal Platonic forms instead. Or, as Forster puts it, to Timmy it is if they are "pictures that must not walk out of their frames." Wilde, at his most weakest, is 'just' style, but Forster often deploys his flair for a deeper effect. Indeed, when you get to the end of this section mentioning picture frames, you realise Forster has actually just smuggled into the story a failed attempt on Tibby's part to engineer an anonymous homosexual encounter with another undergraduate. It is a credit to Forster's sleight-of-hand that you don't quite notice what has just happened underneath you and that the books' reticence to honestly describe what has happened is thus structually analogus Tibby's reluctance to admit his desires to himself. Another layer to the character of Tibby (and the novel as a whole) is thereby introduced without the imposition of clumsy literary scaffolding. In a similar vein, I felt very clever noticing the arch reference to Debussy's Pr lude l'apr s-midi d'un faune until I realised I just fell into the trap Forster set for the reader in that I had become even more like Tibby in his pseudo-scholarly views on classical music. Finally, I enjoyed that each chapter commences with an ironic and self-conscious bon mot about society which is only slightly overblown for effect. Particularly amusing are the ironic asides on "women" that run through the book, ventriloquising the narrow-minded views of people like the Wilcoxes. The omniscient and amiable narrator of the book also recalls those ironically distant voiceovers from various French New Wave films at times, yet Forster's narrator seems to have bigger concerns in his mordant asides: Forster seems to encourage some sympathy for all of the characters even the more contemptible ones at their worst moments. Highly recommended, as are Forster's A Room with a View (1908) and his slightly later A Passage to India (1913).
The Good Soldier (1915) Ford Madox Ford The Good Soldier starts off fairly simply as the narrator's account of his and his wife's relationship with some old friends, including the eponymous 'Good Soldier' of the book's title. It's an experience to read the beginning of this novel, as, like any account of endless praise of someone you've never met or care about, the pages of approving remarks about them appear to be intended to wash over you. Yet as the chapters of The Good Soldier go by, the account of the other characters in the book gets darker and darker. Although the author himself is uncritical of others' actions, your own critical faculties are slowgrly brought into play, and you gradully begin to question the narrator's retelling of events. Our narrator is an unreliable narrator in the strict sense of the term, but with the caveat that he is at least is telling us everything we need to know to come to our own conclusions. As the book unfolds further, the narrator's compromised credibility seems to infuse every element of the novel even the 'Good' of the book's title starts to seem like a minor dishonesty, perhaps serving as the inspiration for the irony embedded in the title of The 'Great' Gatsby. Much more effectively, however, the narrator's fixations, distractions and manner of speaking feel very much part of his dissimulation. It sometimes feels like he is unconsciously skirting over the crucial elements in his tale, exactly like one does in real life when recounting a story containing incriminating ingredients. Indeed, just how much the narrator is conscious of his own concealment is just one part of what makes this such an interesting book: Ford Madox Ford has gifted us with enough ambiguity that it is also possible that even the narrator cannot find it within himself to understand the events of the story he is narrating. It was initially hard to believe that such a carefully crafted analysis of a small group of characters could have been written so long ago, and despite being fairly easy to read, The Good Soldier is an almost infinitely subtle book even the jokes are of the subtle kind and will likely get a re-read within the next few years.
Anna Karenina (1878) Leo Tolstoy There are many similar themes running through War and Peace (reviewed above) and Anna Karenina. Unrequited love; a young man struggling to find a purpose in life; a loving family; an overwhelming love of nature and countless fascinating observations about the minuti of Russian society. Indeed, rather than primarily being about the eponymous Anna, Anna Karenina provides a vast panorama of contemporary life in Russia and of humanity in general. Nevertheless, our Anna is a sophisticated woman who abandons her empty existence as the wife of government official Alexei Karenin, a colourless man who has little personality of his own, and she turns to a certain Count Vronsky in order to fulfil her passionate nature. Needless to say, this results in tragic consequences as their (admittedly somewhat qualified) desire to live together crashes against the rocks of reality and Russian society. Parallel to Anna's narrative, though, Konstantin Levin serves as the novel's alter-protagonist. In contrast to Anna, Levin is a socially awkward individual who straddles many schools of thought within Russia at the time: he is neither a free-thinker (nor heavy-drinker) like his brother Nikolai, and neither is he a bookish intellectual like his half-brother Serge. In short, Levin is his own man, and it is generally agreed by commentators that he is Tolstoy's surrogate within the novel. Levin tends to come to his own version of an idea, and he would rather find his own way than adopt any prefabricated view, even if confusion and muddle is the eventual result. In a roughly isomorphic fashion then, he resembles Anna in this particular sense, whose story is a counterpart to Levin's in their respective searches for happiness and self-actualisation. Whilst many of the passionate and exciting passages are told on Anna's side of the story (I'm thinking horse race in particular, as thrilling as anything in cinema ), many of the broader political thoughts about the nature of the working classes are expressed on Levin's side instead. These are stirring and engaging in their own way, though, such as when he joins his peasants to mow the field and seems to enter the nineteenth-century version of 'flow':
The longer Levin mowed, the more often he felt those moments of oblivion during which it was no longer his arms that swung the scythe, but the scythe itself that lent motion to his whole body, full of life and conscious of itself, and, as if by magic, without a thought of it, the work got rightly and neatly done on its own. These were the most blissful moments.Overall, Tolstoy poses no didactic moral message towards any of the characters in Anna Karenina, and merely invites us to watch rather than judge. (Still, there is a hilarious section that is scathing of contemporary classical music, presaging many of the ideas found in Tolstoy's 1897 What is Art?). In addition, just like the earlier War and Peace, the novel is run through with a number of uncannily accurate observations about daily life:
Anna smiled, as one smiles at the weaknesses of people one loves, and, putting her arm under his, accompanied him to the door of the study.... as well as the usual sprinkling of Tolstoy's sardonic humour ("No one is pleased with his fortune, but everyone is pleased with his wit."). Fyodor Dostoyevsky, the other titan of Russian literature, once described Anna Karenina as a "flawless work of art," and if you re only going to read one Tolstoy novel in your life, it should probably be this one.
variable "hcloud_token" sensitive = true provider "hcloud" token = var.hcloud_token resource "hcloud_server" "web03" name = "web03" server_type = "cpx11" image = "debian-11" datacenter = "nbg1-dc3" resource "hcloud_rdns" "rdns4-web03" server_id = hcloud_server.web03.id ip_address = hcloud_server.web03.ipv4_address dns_ptr = "web03.luffy.cx" resource "hcloud_rdns" "rdns6-web03" server_id = hcloud_server.web03.id ip_address = hcloud_server.web03.ipv6_address dns_ptr = "web03.luffy.cx"
import App, TerraformStack, Fn from "cdktf"; import HcloudProvider from "./.gen/providers/hcloud/provider"; import * as hcloud from "./.gen/providers/hcloud"; class MyStack extends TerraformStack constructor(scope: Construct, name: string) super(scope, name); const hcloudToken = new TerraformVariable(this, "hcloudToken", type: "string", sensitive: true, ); const hcloudProvider = new HcloudProvider(this, "hcloud", token: hcloudToken.value, ); const web03 = new hcloud.server.Server(this, "web03", name: "web03", serverType: "cpx11", image: "debian-11", datacenter: "nbg1-dc3", provider: hcloudProvider, ); new hcloud.rdns.Rdns(this, "rdns4-web03", serverId: Fn.tonumber(web03.id), ipAddress: web03.ipv4Address, dnsPtr: "web03.luffy.cx", provider: hcloudProvider, ); new hcloud.rdns.Rdns(this, "rdns6-web03", serverId: Fn.tonumber(web03.id), ipAddress: web03.ipv6Address, dnsPtr: "web03.luffy.cx", provider: hcloudProvider, ); const app = new App(); new MyStack(app, "cdktf-take1"); app.synth();
cdktf synth
generates a configuration file for Terraform, terraform
plan
previews the changes, and terraform apply
applies them. Now that you
have a general-purpose language, you can use functions.
bernat.ch
zone with this snippet of code:
D("bernat.ch", REG_NONE, DnsProvider(DNS_BIND, 0), DnsProvider(DNS_GANDI), DefaultTTL('2h'), FastMailMX('bernat.ch', subdomains: ['vincent'] ), WebServers('@'), WebServers('vincent');
new Route53Zone(this, "bernat.ch", providers.aws) .sign(dnsCMK) .registrar(providers.gandiVB) .www("@", servers) .www("vincent", servers) .www("media", servers) .fastmailMX(["vincent"]);
Route53Zone()
creates a new zone hosted by Route 53,sign()
signs the zone with the provided master key,registrar()
registers the zone to the registrar of the domain and sets up DNSSEC,www()
creates A
and AAAA
records for the provided name pointing to the web servers,fastmailMX()
creates the MX
records and other support records to direct emails to Fastmail.fastmailMX()
function. It generates a few records
and returns the current zone for chaining:
fastmailMX(subdomains?: string[]) (subdomains ?? []) .concat(["@", "*"]) .forEach((subdomain) => this.MX(subdomain, [ "10 in1-smtp.messagingengine.com.", "20 in2-smtp.messagingengine.com.", ]) ); this.TXT("@", "v=spf1 include:spf.messagingengine.com ~all"); ["mesmtp", "fm1", "fm2", "fm3"].forEach((dk) => this.CNAME( $ dk ._domainkey , $ dk .$ this.name .dkim.fmhosted.com. ) ); this.TXT("_dmarc", "v=DMARC1; p=none; sp=none"); return this;
Makefile
automatically installs Pulumi using a curl sh
pattern and does not work with /bin/sh
. There is a lack of
interest for community-based contributions4 or even for providers for
smaller players.
environment.systemPackages = with pkgs; [ bat htop liboping mg mtr ncdu tmux ];
services.nginx = enable = true; package = (pkgs.nginxStable.override withStream = false; modules = with pkgs.nginxModules; [ brotli ipscrub ]; openssl = pkgs.openssl_1_1; );
services.nginx.package = pkgs.nginxStable.overrideAttrs (old: patches = oldAttrs.patches ++ [ # HTTP/2: reject zero length headers with PROTOCOL_ERROR. (pkgs.fetchpatch url = https://github.com/nginx/nginx/commit/dbdd[ ].patch; sha256 = "a48190[ ]"; ) # HTTP/2: limited number of DATA frames. (pkgs.fetchpatch url = https://github.com/nginx/nginx/commit/94c5[ ].patch; sha256 = "af591a[ ]"; ) # HTTP/2: limited number of PRIORITY frames. (pkgs.fetchpatch url = https://github.com/nginx/nginx/commit/39bb[ ].patch; sha256 = "1ad8fe[ ]"; ) ]; );
common.nix
contains the configuration to be applied to any host
(SSH, users, common software packages), web.nix
contains the
configuration for the web servers, isso.nix
runs Isso into a
systemd container.
/etc/nixos/configuration.nix
file. After modifying it, you have to run nixos-rebuild switch
. Nix fetches
all possible dependencies from the binary cache and builds the remaining
packages. It creates a new entry in the boot loader menu and activates the new
configuration.
To manage several nodes, there exists several options, including NixOps,
deploy-rs, Colmena, and morph. I do not know all of them, but from
my point of view, the differences are not that important. It is also possible to
build such a tool yourself as Nix provides the most important building blocks:
nix build
and nix copy
. NixOps is one of the first tools available but I
encourage you to explore the alternatives.
NixOps configuration is written in Nix. Here is a simplified configuration
to deploy znc01.luffy.cx
, web01.luffy.cx
, and web02.luffy.cx
, with the
help of the server
and web
functions:
let server = hardware: name: imports: deployment.targetHost = "$ name .luffy.cx"; networking.hostName = name; networking.domain = "luffy.cx"; imports = [ (./hardware/. + "/$ hardware .nix") ] ++ imports; ; web = hardware: idx: imports: server hardware "web$ lib.fixedWidthNumber 2 idx " ([ ./web.nix ] ++ imports); in network.description = "Luffy infrastructure"; network.enableRollback = true; defaults = import ./common.nix; znc01 = server "exoscale" [ ./znc.nix ]; web01 = web "hetzner" 1 [ ./isso.nix ]; web02 = web "hetzner" 2 [];
flake.nix
and
flake.lock
at the root of some repositories.
As a short example, here is the flake.nix
content shipped with Snimpy, an
interactive SNMP tool for Python relying on libsmi, a C library:
inputs = nixpkgs.url = "nixpkgs"; flake-utils.url = "github:numtide/flake-utils"; ; outputs = self, ... @inputs: inputs.flake-utils.lib.eachDefaultSystem (system: let pkgs = inputs.nixpkgs.legacyPackages."$ system "; in # nix build packages.default = pkgs.python3Packages.buildPythonPackage name = "snimpy"; src = self; preConfigure = ''echo "1.0.0-0-000000000000" > version.txt''; checkPhase = "pytest"; checkInputs = with pkgs.python3Packages; [ pytest mock coverage ]; propagatedBuildInputs = with pkgs.python3Packages; [ cffi pysnmp ipython ]; buildInputs = [ pkgs.libsmi ]; ; # nix run + nix shell apps.default = type = "app"; program = "$ self.packages."$ system ".default /bin/snimpy"; ; # nix develop devShells.default = pkgs.mkShell name = "snimpy-dev"; buildInputs = [ self.packages."$ system ".default.inputDerivation pkgs.python3Packages.ipython ]; ; );
nix run github:vincentbernat/snimpy
runs Snimpy,nix shell github:vincentbernat/snimpy
provides a shell with Snimpy ready-to-use,nix build github:vincentbernat/snimpy
builds the Python package, tests included, andnix develop .
provides a shell to hack around Snimpy when run from a fresh checkout.9flake.nix
file to set up a shell with Terraform and
CDKTF installed and with the appropriate environment variables to automate my
infrastructure.
Terraform is already packaged in nixpkgs. However, I need to apply a patch
on top of the Gandi provider. Not a problem with Nix!
terraform = pkgs.terraform.withPlugins (p: [ p.aws p.hcloud p.vultr (p.gandi.overrideAttrs (old: src = pkgs.fetchFromGitHub owner = "vincentbernat"; repo = "terraform-provider-gandi"; rev = "feature/livedns-key"; hash = "sha256-V16BIjo5/rloQ1xTQrdd0snoq1OPuDh3fQNW7kiv/kQ="; ; )) ]);
package.json
file with all the dependencies
needed, including the ones to use TypeScript as the language to define
infrastructure:
"name": "cdktf-take1", "version": "1.0.0", "main": "main.js", "types": "main.ts", "private": true, "dependencies": "@types/node": "^14.18.30", "cdktf": "^0.13.3", "cdktf-cli": "^0.13.3", "constructs": "^10.1.151", "eslint": "^8.27.0", "prettier": "^2.7.1", "ts-node": "^10.9.1", "typescript": "^3.9.10", "typescript-language-server": "^2.1.0"
yarn.lock
file that can be
used directly to declare a derivation containing all the dependencies:
nodeEnv = pkgs.mkYarnModules pname = "cdktf-take1-js-modules"; version = "1.0.0"; packageJSON = ./package.json; yarnLock = ./yarn.lock; ;
cdktfProviders = pkgs.stdenvNoCC.mkDerivation name = "cdktf-providers"; nativeBuildInputs = [ pkgs.nodejs terraform ]; src = nix-filter root = ./.; include = [ ./cdktf.json ./tsconfig.json ]; ; buildPhase = '' export HOME=$(mktemp -d) export CHECKPOINT_DISABLE=1 export DISABLE_VERSION_CHECK=1 export PATH=$ nodeEnv /node_modules/.bin:$PATH ln -nsf $ nodeEnv /node_modules node_modules # Build all providers we have in terraform for provider in $(cd $ terraform /libexec/terraform-providers; echo */*/*/*); do version=''$ provider##*/ provider=''$ provider%/* echo "Build $provider@$version" cdktf provider add --force-local $provider@$version cat done echo "Compile TS JS" tsc ''; installPhase = '' mv .gen $out ln -nsf $ nodeEnv /node_modules $out/node_modules ''; ;
devShells.default = pkgs.mkShell name = "cdktf-take1"; buildInputs = [ pkgs.nodejs pkgs.yarn terraform ]; shellHook = '' # No telemetry export CHECKPOINT_DISABLE=1 # No autoinstall of plugins export CDKTF_DISABLE_PLUGIN_CACHE_ENV=1 # Do not check version export DISABLE_VERSION_CHECK=1 # Access to node modules export PATH=$PWD/node_modules/.bin:$PATH ln -nsf $ nodeEnv /node_modules node_modules ln -nsf $ cdktfProviders .gen # Credentials for p in \ njf.nznmba.pbz/Nqzvavfgengbe \ urgmare.pbz/ivaprag@oreang.pu \ ihyge.pbz/ihyge@ivaprag.oreang.pu; do eval $(pass show $(echo $p tr 'A-Za-z' 'N-ZA-Mn-za-m') grep '^export') done eval $(pass show personal/cdktf/secrets grep '^export') export TF_VAR_hcloudToken="$HCLOUD_TOKEN" export TF_VAR_vultrApiKey="$VULTR_API_KEY" unset VULTR_API_KEY HCLOUD_TOKEN ''; ;
buildInputs
are available in the provided shell.
The content of shellHook
is sourced when starting the shell. It sets up some
symbolic links to make the JavaScript environment built at an earlier step
available, as well as the generated CDKTF providers. It also exports all the
credentials.10
I am also using direnv with an .envrc
to
automatically load the development environment. This also enables the
environment to be available from inside Emacs, notably when using lsp-mode
to get TypeScript completions. Without direnv, nix develop .
can activate
the environment.
I use the following commands to deploy the infrastructure:11
$ cdktf synth $ cd cdktf.out/stacks/cdktf-take1 $ terraform plan --out plan $ terraform apply plan $ terraform output -json > ~-automation/nixops-take1/cdktf.json
"hardware": "hetzner", "ipv4Address": "5.161.44.145", "ipv6Address": "2a01:4ff:f0:b91::1", "name": "web05.luffy.cx", "tags": [ "web", "continent:NA", "continent:SA" ]
network.nix
, this list is imported and
transformed into an attribute set describing the servers. A simplified version
looks like this:
let lib = inputs.nixpkgs.lib; shortName = name: builtins.elemAt (lib.splitString "." name) 0; domainName = name: lib.concatStringsSep "." (builtins.tail (lib.splitString "." name)); server = hardware: name: imports: networking = hostName = shortName name; domain = domainName name; ; deployment.targetHost = name; imports = [ (./hardware/. + "/$ hardware .nix") ] ++ imports; ; cdktf-servers-json = (lib.importJSON ./cdktf.json).servers.value; cdktf-servers = map (s: let tags-maybe-import = map (t: ./. + "/$ t .nix") s.tags; tags-import = builtins.filter (t: builtins.pathExists t) tags-maybe-import; in name = shortName s.name; value = server s.hardware s.name tags-import; ) cdktf-servers-json; in // [ ] // builtins.listToAttrs cdktf-servers
web05
, this expands to:
web05 = networking = hostName = "web05"; domainName = "luffy.cx"; ; deployment.targetHost = "web05.luffy.cx"; imports = [ ./hardware/hetzner.nix ./web.nix ]; ;
flake.nix
file to set up a shell with
NixOps configured. Because NixOps do not support rollouts, I usually use the
following commands to deploy on a single server:12
$ nix flake update $ nixops deploy --include=web04 $ ./tests web04.luffy.cx
$ (set -e; for h in web 03..06 ; do nixops deploy --include=$h; done)
nixops deploy
rolls out all servers in parallel and therefore could cause a
short outage where all Nginx are down at the same time.
apply()
method on an output. It makes it easy to transform data that are not known
during the planning stage. Terraform has functions to
serve a similar purpose, but they are more limited.
/bin/bash
. I also submitted PR #56,
which was merged 4 months later and quickly reverted without
an explanation.
.
with github:vincentbernat/snimpy
,
like in the other commands, but having Snimpy dependencies without
Snimpy source code is less interesting.
cdktf
command can wrap the terraform
commands, but I
prefer to use them directly as they are more flexible.
Series: | Arcana Imperii #1 |
Publisher: | Gollancz |
Copyright: | June 2021 |
ISBN: | 1-4732-3262-7 |
Format: | Kindle |
Pages: | 483 |
Series: | The Scholomance #3 |
Publisher: | Del Rey |
Copyright: | 2022 |
ISBN: | 0-593-15836-9 |
Format: | Kindle |
Pages: | 408 |
man(1)
haven t required it in a long time, and both hardware and
software
improvements
mean that even some searches can be done by brute force without needing
prior indexing. However, the database is still needed for the whatis(1)
and apropos(1)
commands.
The database has a simple format - no relational structure here, it s just a
simple key-value database using old-fashioned DBM-like interfaces and
composing a few fields to form values - but there are a number of subtleties
involved. The issues tend to amount to this: what does a manual page name
mean? At first glance it might seem simple, because you have file names
that look something like /usr/share/man/man1/ls.1.gz
and that s obviously
ls(1)
. Some pages are symlinks to other pages (which we track separately
because it makes it easier to figure out which entries to update when the
contents of the file system change), and sometimes multiple pages are even
hard links to the same file.
The real complications come with whatis references . Pages can list a
bunch of names in their NAME
section, and the historical expectation is
that it should be possible to use those names as arguments to man(1)
even
if they don t also appear in the file system (although Debian policy has
deprecated relying on
this
for some time). Not only does that mean that man(1)
sometimes needs to
consult the database, but it also means that the database is inherently more
complicated, since a page might list something in its NAME
section that
conflicts with an actual file name in the file system, and now you need a
priority system to resolve ambiguities. There are some other possible
causes of ambiguity as well.
The people working on reproducible
builds in Debian branched out to the
related challenge of reproducible installations some time ago: can you take
a collection of packages, bootstrap a file system image from them, and
reproduce that exact same image somewhere else? This is useful for the same
sorts of reasons that reproducible builds are useful: it lets you verify
that an image is built from the components it s supposed to be built from,
and doesn t contain any other skulduggery by accident or design. One of the
people working on this noticed that
man-db s database files were an obstacle to that: in particular, the exact
contents of the database seemed to depend on the order in which files were
scanned when building it. The reporter proposed solving this by processing
files in sorted order, but I wasn t keen on that approach: firstly because
it would mean we could no longer process files in an order that makes it
more efficient to read them all from disk (still valuable on rotational
disks), but mostly because the differences seemed to point to other bugs.
Having understood this, there then followed several late nights of very
fiddly work on the details of how the database is maintained. None of this
was conceptually difficult: it mainly amounted to ensuring that we maintain
a consistent well-order for
different entries that we might want to insert for a given database key, and
that we consider the same names for insertion regardless of the order in
which we encounter files. As usual, the tricky bit is making sure that we
have the right data structures to support this. man-db is written in C
which is not very well-supplied with built-in data structures, and
originally much of the code was written in a style that tried to minimize
memory allocations; this came at the cost of ownership and lifetime often
being rather unclear, and it was often difficult to make changes without
causing leaks or double-frees. Over the years I ve been gradually
introducing better encapsulation to make things easier to follow, and I had
to do another round of that here. There were also some problems with
caching being done at slightly the wrong layer: we need to make use of a
trace of the chain of links followed to resolve a page to its ultimate
source file, but we were incorrectly caching that trace and reusing it for
any link to the same file, with incorrect results in many cases.
Oh, and after doing all that I found that the on-disk representation of a
GDBM database is insertion-order-dependent, so I ended up having to manually
reorganize the database at the end by reading it all in and writing it all
back out in sorted order, which feels really weird to me coming from
spending most of my time with PostgreSQL these days. Fortunately the
database is small so this takes negligible time.
None of this is particularly glamorous work, but it paid off:
# export SOURCE_DATE_EPOCH="$(date +%s)"
# mkdir emptydir disorder
# disorderfs --multi-user=yes --shuffle-dirents=yes --reverse-dirents=no emptydir disorder
# export TMPDIR="$(pwd)/disorder"
# mmdebstrap --variant=standard --hook-dir=/usr/share/mmdebstrap/hooks/merged-usr \
unstable out1.tar
# mmdebstrap --variant=standard --hook-dir=/usr/share/mmdebstrap/hooks/merged-usr \
unstable out2.tar
# cmp out1.tar out2.tar
# echo $?
0
math
command.
edward@x1c9 ~> math 2_000 + 22 2022 edward@x1c9 ~>
// A decimal integer literal with its digits grouped per thousand: 1_000_000_000_000 // A decimal literal with its digits grouped per thousand: 1_000_000.220_720 // A binary integer literal with its bits grouped per octet: 0b01010110_00111000 // A binary integer literal with its bits grouped per nibble: 0b0101_0110_0011_1000 // A hexadecimal integer literal with its digits grouped by byte: 0x40_76_38_6A_73 // A BigInt literal with its digits grouped per thousand: 4_642_473_943_484_686_707n
CONNECT 2400
. Now your computer was bridged to the other; anything going out your serial port was encoded as sound by your modem and decoded at the other end, and vice-versa.
But what, exactly, was the other end?
It might have been another person at their computer. Turn on local echo, and you can see what they did. Maybe you d send files to each other. But in my case, the answer was different: PC Magazine.
71510,1421
. CompuServe had forums, and files. Eventually I would use TapCIS to queue up things I wanted to do offline, to minimize phone usage online.
CompuServe eventually added a gateway to the Internet. For the sum of somewhere around $1 a message, you could send or receive an email from someone with an Internet email address! I remember the thrill of one time, as a kid of probably 11 years, sending a message to one of the editors of PC Magazine and getting a kind, if brief, reply back!
But inevitably I had
complete.org
, as well. At the time, the process was a bit lengthy and involved downloading a text file form, filling it out in a precise way, sending it to InterNIC, and probably mailing them a check. Well I did that, and in September of 1995, complete.org
became mine. I set up sendmail
on my local system, as well as INN
to handle the limited Usenet newsfeed I requested from the ISP. I even ran Majordomo to host some mailing lists, including some that were surprisingly high-traffic for a few-times-a-day long-distance modem UUCP link!
The modem client programs for FreeBSD were somewhat less advanced than for OS/2, but I believe I wound up using Minicom or Seyon to continue to dial out to BBSs and, I believe, continue to use Learning Link. So all the while I was setting up my local BBS, I continued to have access to the text Internet, consisting of chiefly Gopher for me.
Next.