{"title":"Stanley Solutions Blog - DevOps","link":[{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/","rel":"alternate"}},{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/feeds\/devops.atom.xml","rel":"self"}}],"id":"https:\/\/blog.stanleysolutionsnw.com\/","updated":"2022-10-24T16:25:00-07:00","subtitle":"engineering and creativity - all under one hat","entry":[{"title":"Starting Jenkins Right Away in Winders","link":{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/starting-jenkins-right-away-in-winders.html","rel":"alternate"}},"published":"2022-10-24T16:25:00-07:00","updated":"2022-10-24T16:25:00-07:00","author":{"name":"Joe Stanley"},"id":"tag:blog.stanleysolutionsnw.com,2022-10-24:\/starting-jenkins-right-away-in-winders.html","summary":"<p>Jenkins is a powerful, albeit confusing, tool. You can structure all manner of automated processes to build source code, distribute packages, and automate the boring stuff. It's great! But Jenkins and Windows (or... <em>Winders<\/em>) don't always play nicely. I learned this the hard way in my \"day-job\" and had to find a technique to resolve some of this bad-behavior. So hopefully you might find this helpful!<\/p>","content":"<blockquote>\n<p>Let me begin by describing the circumstances.<\/p>\n<\/blockquote>\n<p>As it turns out, in some applications, Jenkins must be run in a full UI-based environment to function properly with some tools. Notably, some of the tools I use in my day-to-day\nwork. A colleague and I were working on getting Jenkins running in build nodes to support automated package builds at work. Challenge is, we needed the full UI, and that's not\na \"standard\" configuration for Jenkins nodes on Windows. So we had to do some exploring. <\/p>\n<p>Most commonly, Jenkins agents will run as part of a \"scheduled task\" on a Windows host. However, this has some inherent limitations that we ran into. Specifically, some very\npeculiar (and specific) C# challenges. As it turns out, those issues were only really present if the Jenkins agent was running as a desktop-environment-less task. That said,\nthere's not a clean way (that I found, at least) to make a task run in a full desktop environment. This left us scratching our heads to find a way to make Jenkins run\nautomagically in a desktop.<\/p>\n<blockquote>\n<p>Hmmm...<\/p>\n<\/blockquote>\n<p>Eventually, I stumbled upon a potential solution! We could define a \"startup user\" whose account is opened by default when the Windows system starts. Almost like some kind of\n\"kiosk mode\" for windows, but specifically for our application. Now, this still took some exploration, and learning, but I finally found a way to make a default user\n\"automatically log in\" when the system starts, and then make a simple startup script to run the Jenkins command.<\/p>\n<h5>References<\/h5>\n<ul>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/18906753\/jenkins-windows-slave-service-does-not-interact-with-desktop\">getting Jenkins to interact with Windows desktop<\/a><\/li>\n<li><a href=\"https:\/\/serverfault.com\/questions\/269832\/windows-server-2008-automatic-user-logon-on-power-on\/606130#606130\">article on ServerFault<\/a><\/li>\n<\/ul>\n<h2>Instructions<\/h2>\n<h4>1) Create a batch file to start Jenkins agent<\/h4>\n<p>The Jenkins agent has to be run on the VM from the specified workspace directory (<code>C:\\_jenkins<\/code> in this case), and with the appropriate token information.\nSo create a batch file that you can store in the Windows startup folder for the specific user. Don't worry about it's location, now, we'll come back to that later.<\/p>\n<p>Create the file <code>jenkins_start.bat<\/code> with the following information (substituting information where needed from Jenkins' direction).<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"k\">cd<\/span> C:\\_jenkins\n\njava -jar agent.jar -jnlpUrl https:\/\/<span class=\"p\">&lt;<\/span> HOST <span class=\"p\">&gt;<\/span>\/computer\/<span class=\"p\">&lt;<\/span> AGENT-NAME <span class=\"p\">&gt;<\/span>\/jenkins-agent.jnlp -secret <span class=\"p\">&lt;<\/span> SECRET <span class=\"p\">&gt;<\/span> -workDir <span class=\"s2\">&quot;c:\\_jenkins&quot;<\/span>\n<\/code><\/pre><\/div>\n\n<h4>2) Move the startup script to the service-user's startup folder<\/h4>\n<p>To make the script run as the user would, we'll need to place it in the user's startup folder.<\/p>\n<ol>\n<li>As the service user, press Ctrl+r to open the \"Run\" launcher prompt. (or search for \"Run\" in the Windows start menu)<\/li>\n<li>Enter <code>shell:startup<\/code> in the prompt and press Enter\/click \"Run\"<\/li>\n<li>Copy\/Move the batch script you created previously into the startup folder which now appears on-screen<\/li>\n<\/ol>\n<p>If the above steps fail, you can manually browse to the start folder as follows:<\/p>\n<p><code>C:\\Users\\&lt; SERVICE-USERNAME &gt;\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup<\/code><\/p>\n<h4>OPTIONALLY:<\/h4>\n<p>It may be valuable to restart the machine and log in as the service-user to confirm that the startup script is working as expected and connects back to the Jenkins master\nwith a visible console window.<\/p>\n<h4>3) Modify the registry to make the service-user logon automatically after startup<\/h4>\n<p>As described in the <a href=\"https:\/\/serverfault.com\/questions\/269832\/windows-server-2008-automatic-user-logon-on-power-on\/606130#606130\">article on ServerFault<\/a>, generate a file called <code>AutoLogon.reg<\/code> somewhere on the virtual machine with the following content<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"na\">Windows Registry Editor Version 5.00<\/span>\n\n<span class=\"k\">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon]<\/span>\n<span class=\"na\">&quot;DefaultDomainName&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;SERVICE_ACCOUNT_DOMAIN&quot;<\/span>\n<span class=\"na\">&quot;DefaultUserName&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;SERVICE_ACCOUNT_USER&quot;<\/span>\n<span class=\"na\">&quot;DefaultPassword&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;SERVICE_ACCOUNT_PASSWORD&quot;<\/span>\n<span class=\"na\">&quot;ForceAutoLogon&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;1&quot;<\/span>\n<span class=\"na\">&quot;AutoAdminLogon&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;1&quot;<\/span>\n<span class=\"na\">&quot;LegalNoticeCaption&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;&quot;<\/span>\n<span class=\"na\">&quot;LegalNoticeText&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;&quot;<\/span>\n\n<span class=\"k\">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\AutoLogonChecked]<\/span>\n<span class=\"na\">@<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;1&quot;<\/span>\n\n<span class=\"k\">[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system]<\/span>\n<span class=\"na\">&quot;LegalNoticeCaption&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;&quot;<\/span>\n<span class=\"na\">&quot;LegalNoticeText&quot;<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;&quot;<\/span>\n<\/code><\/pre><\/div>\n\n<p>After saving the file, right-click on it in a file explorer and select \"Merge,\" you'll be prompted to confirm the operation; do so.<\/p>\n<h4>Restart the machine and confirm that it automatically connects to Jenkins<\/h4>\n<p>Restarting the machine should make use of the new registry edits and auto-login the service account user. In-so-doing will launch the startup batch-file script which will\nconnect to the Jenkins master through the console in a graphical session.<\/p>\n<hr>\n<h2>Additional Improvement Notes<\/h2>\n<p>I think one thing I should call out is that this mechanism doesn't \"restart\" if a failure occurs. That is, if Jenkins crashes, it doesn't restart. But I think it could\neasily be added by using some kind of <code>FOR<\/code>\/<code>WHILE<\/code> loop in the batch-file to script some kind of automatic retry. Nothing crazy, just worth noting!<\/p>\n<h5>Closing Thoughts<\/h5>\n<p>I know there's bound to be other ways of doing this. Let me know what you've done! Tell me about your Jenkins \"woes;\" I'd love to hear them! Hopefully my solution will\ngive you some inspiration.<\/p>","category":[{"@attributes":{"term":"DevOps"}},{"@attributes":{"term":"devops"}},{"@attributes":{"term":"jenkins"}},{"@attributes":{"term":"ci\/cd"}},{"@attributes":{"term":"continuous-integration"}},{"@attributes":{"term":"continuous-deployment"}},{"@attributes":{"term":"build-systems"}},{"@attributes":{"term":"automation"}},{"@attributes":{"term":"windows"}}]},{"title":"Why do I Self-Host?","link":{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/why-do-i-selfhost.html","rel":"alternate"}},"published":"2021-09-28T21:53:00-07:00","updated":"2021-09-28T21:53:00-07:00","author":{"name":"Joe Stanley"},"id":"tag:blog.stanleysolutionsnw.com,2021-09-28:\/why-do-i-selfhost.html","summary":"<p>I was recently asked \"why do you run your own servers, when there's perfectly good, cheap, cloud providers?\" Well... Here's why!<\/p>","content":"<p>I was recently having a conversation with a few techie friends about the ridiculous and nerdy things that I'm doing at home. And, yes,\nI realize I'm very nerdy. If that isn't clear already, go read some of my other articles.<\/p>\n<p>One of my friends was curious why, exactly, I've decided to self-host so many of my services when I could easily lob those things up on\nsome cloud-service like <a href=\"https:\/\/www.linode.com\/unplugged\">Linode<\/a>. It's a fair question! To my friend's point, those services are fast,\neasy, and require very little maintenance (comparatively, of course). To be clear, I mean that these services manage much of the storage,\nhardware constraints, and networking limitations that I'm working through regularly. There's still the regular work of updating operating\nsystems that needs to be managed whether the server is running locally or in the cloud.<\/p>\n<p>I won't discredit these features! They're quite attractive, but there's still reason for me to keep my servers plugged in.<\/p>\n<p><em>Let me explain...<\/em><\/p>\n<h3>Reduce, Reuse, Recycle<\/h3>\n<p>This point is perhaps the most important to me. I believe I've mentioned before that a lot... Let me emphasize that point...<\/p>\n<p><strong><em>A LOT<\/em><\/strong><\/p>\n<p>of the hardware I'm using is old. Many of the computers are what could be considered \"ancient\" desktop towers. They're old computers doing\nmodern things. In fact, at this point I think I have more 32-bit computers than I do 64-bit ones. Before you ask, yes, it's a bit painful;\nbut it's worthwhile. I mean, just think about it... I'm currently running seven computers that other people were ready to just throw in\nthe trash. That's 7 computers that didn't need to be recycled, 7 computers whose lifetime just got extended courtesy of yours truly.<\/p>\n<p>Admittedly, they're power-hungry, and they're not as powerful as more modern equivalents, but they're doing great things for me, and that's\nsomething that they wouldn't be able to do otherwise. Others would more than likely just chuck them, and I think it's far more valuable to\nmilk those old machines for everything I can. Perhaps it's just the naive part of my personality, but I'd like to think that these little\nchoices have an impact in some small way.<\/p>\n<h3>My Disks, My Data<\/h3>\n<p>As just about any self-hosting fiend would likely tell you: \"my data lives on <em>my<\/em> disks\". Point being, since I own the disks, I'm the\nproprietor of the data, too! That means I don't ever have to concern myself with whether or not I can revoke control over the data. Now,\nI'll grant, this certainly makes me sound a bit more like a conspiracy theorist or an \"old codger\". I guess I don't have any rebuttal\nagainst that. I'll just have to take it.<\/p>\n<h4>Data that's Important to Me, For My Eyes Only<\/h4>\n<p>To tack on to the previous point, since I own the data, I can use what I consider \"private\" or \"privileged\" data on my servers. Why?\nBecause I own them! I can <em>see<\/em> where the disks that store the data reside. Now, I know this may not seem like the greatest argument, but\nwhen it comes to the argument of security and sensitivity, isn't it really all about perception and comfort anyway?<\/p>\n<p>To put it another way, why do millions of homeowners install a home-security system? Is it because they think that the system will\nimmediately stop thieves in the act? Wouldn't better deadbolts and barred windows provide the same level of protection? Perhaps,\nbut then, maybe not. I'd expect that in more cases than not, homeowners want a balance. They want features, and they want function.\nThey want to <em>feel<\/em> secure, and they want to enjoy their home without barred windows and dozens of deadbolts.<\/p>\n<p>That's why having my \"private\" data on my local servers is important to me. I've been graciously granted numerous data-set samples to\ntest some of my other Python projects against, but that data is important to the people who gave it to me. It's the sort of data that I'm\nhonored to have been granted access to, and I don't really think it's appropriate to share with the rest of the world. So, I host it on\nservers that live in my basement. Somewhere that lives behind <em>my<\/em> firewalls.<\/p>\n<p>I don't think that my solution is right for everyone, and I don't think it's the \"be-all-end-all\" solution that I wish it was, but it\nworks for me, and makes me happy! After all, if it helps me sleep well at night, isn't that worth something?<\/p>\n<h3>Diversified Service Structure<\/h3>\n<p>You've heard of diversified investments, haven't you?<\/p>\n<p>Well, that's kinda what I'm doing with my diversified infrastructure. You see, I'm not <em>only<\/em> self-hosting. <gasp!> I'm also using cloud\nservices (namely Linode - thanks, Linode Team!) to help me with some services, and I'm planning to spin up some others in the (relatively)\nnear future. Sometimes speed is important, sometimes it's not. When speed <em>is<\/em> a concern, I try to host on Linode, since they're so\n<strong>SUPER-FAST<\/strong> and available, it makes sense for me. But in other cases, it doesn't make sense.<\/p>\n<p>That's all part of the whole \"multi-cloud\" paradigm anyway, though. Different providers for different applications, diversified to be more\nrobust. In fact, I <em>do<\/em> use Linode for some off-site backups. I'm still working out my backup strategy. It's not the greatest, at the\nmoment, but it's coming along, and some of that is thanks to Linode's services, and the peace-of-mind they offer. Mind you, the data I'm\nbacking up to Linode still goes through secure tunnels, and it's not the \"private\" data that I was mentioning earlier.<\/p>\n<h3>Hands-On Learning Opportunities<\/h3>\n<p>My last point for keeping these machines kicking around in my closets, basement, and elsewhere is because they all offer me some great\nopportunities to learn! After all, if I'm going to keep these things up and running, I've got to constantly be improving, adding, reworking\nand modifying to (stealing a bit from my 4-H background here) make the best better. Having these servers in my house affords me the ability\nto simply plug in a USB stick, or connect a monitor if I blow up SSH so badly I can't reconnect. It means that when I botch the install, I\njust start over, and when I need to copy the whole darn disk, I just pull it out and stick it in my external hard-drive bay.<\/p>\n<p>Believe me, I've learned a lot in the past year playing with these things and keeping them up. And there's still a lot more I want to learn.<\/p>\n<hr>\n<p>So that's my story, and I'm sticking to it.<\/p>\n<p>Like I mentioned earlier, I wouldn't recommend this to everyone; it's a solution that fits my needs, but that may be different than what\nothers are interested in. Still, I'm proud of the fact that I'm running so much out of my own home, and I'm excited to keep growing with\nthese old computers. I'm happy that I'm able to reuse machines that would otherwise litter some landfill, and keep things running for\nmyself and some of the university students that I support.<\/p>","category":[{"@attributes":{"term":"DevOps"}},{"@attributes":{"term":"self-hosting"}},{"@attributes":{"term":"servers"}},{"@attributes":{"term":"computing"}},{"@attributes":{"term":"hosting"}},{"@attributes":{"term":"web"}},{"@attributes":{"term":"services"}}]},{"title":"Servers in the Basement...","link":{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/jenkins-servers-in-the-basement.html","rel":"alternate"}},"published":"2021-02-14T19:23:00-08:00","updated":"2021-02-14T20:40:00-08:00","author":{"name":"Joe Stanley"},"id":"tag:blog.stanleysolutionsnw.com,2021-02-14:\/jenkins-servers-in-the-basement.html","summary":"<p class=\"first last\">Some people keep their creepy Christmas decorations in their basement. Others keep their continuous integration servers down there too...<\/p>\n","content":"<img alt=\"SEL Rugged Computers mounted and ready for work!\" src=\"https:\/\/blog.stanleysolutionsnw.com\/IMG_0851.jpg\" style=\"width: 600px;\" \/>\n<p>Whelp, I've gone and done it. I've mounted and installed one of my SEL computers\nand set it up for running Jenkins!<\/p>\n<p>This isn't going to be a very in-depth article, but I wanted to say that it's\ndone. The server is mounted with a brand new switch and surge protector (no UPS\nfor the moment, but perhaps to come in the <em>relatively<\/em> near future). They're\nnetworked back upstairs to my little IT closet, and Jenkins is waiting idly for\nme to push new code.<\/p>\n<p>I spent Saturday mounting the server, re-routing all the networking, and setting\nup my modem to provide access to the servers by way of a reverse proxy. Perhaps\nI'll document what that is and how it works, but that might be another article.<\/p>\n<p>Today I got to work standing up a few <cite>pytest<\/cite> projects for both <a class=\"reference external\" href=\"https:\/\/github.com\/engineerjoe440\/selprotopy\">selprotopy<\/a>\nand <a class=\"reference external\" href=\"https:\/\/github.com\/engineerjoe440\/pycev\">pycev<\/a>, what's exciting about this though, is the fact that they're set up\nnow so that they can access the private resources they need for testing, but\nthey can be kicked off by my commits and pushes to their repositories on GitHub.<\/p>\n<p>So... now I can really start cranking on that code, and Jenkins can do some of\nmy dirty work to start running the tests for me!<\/p>\n<img alt=\"Gotta love that SEL blue!\" src=\"https:\/\/blog.stanleysolutionsnw.com\/IMG_0852.jpg\" style=\"width: 600px;\" \/>\n<p>I want to restate that I'm very excited to be using some old SEL hardware and\ngiving it a second lease on life. These computers are rugged, industrial\nmachines; and I'm getting to put them to work making these projects solid. Not\nto mention that these projects are actually tailored to supporting SEL tech.<\/p>\n<p>Yep. It's nerdy.<\/p>\n<p>Yep. I'm still excited.<\/p>\n<p>Yep. You guessed it; I'll surely be giving more updates moving forward!<\/p>\n","category":[{"@attributes":{"term":"DevOps"}},{"@attributes":{"term":"sel"}},{"@attributes":{"term":"ci\/cd"}},{"@attributes":{"term":"jenkins"}},{"@attributes":{"term":"devops"}}]},{"title":"CI\/CD On Industrial Grade Hardware","link":{"@attributes":{"href":"https:\/\/blog.stanleysolutionsnw.com\/jenkins-on-sel-industrial-hardware.html","rel":"alternate"}},"published":"2021-02-07T16:19:00-08:00","updated":"2021-02-07T16:19:00-08:00","author":{"name":"Joe Stanley"},"id":"tag:blog.stanleysolutionsnw.com,2021-02-07:\/jenkins-on-sel-industrial-hardware.html","summary":"<p class=\"first last\">Run DevOps CI\/CD pipelines on industrial equipment with no moving parts? Ok! Sign me up!!!<\/p>\n","content":"<p>Yes... I already have too many computers. But with that said, what's a few more?<\/p>\n<p>I know it was only about a month-and-a-half ago that I was writing about Jenkins\nrunning on a Raspberry Pi, but I outgrew that pretty quickly. In reality, I\nreally just started with it, and basically gave up; but hey! I learned a lot in\nthat time. So now, I'm upgrading!<\/p>\n<div class=\"section\" id=\"the-new-hardware\">\n<h2>The new hardware<\/h2>\n<p>I am something of a hardware graveyard. Old machines come to me to live out the\nend of their lives and, eventually, give up the ghost. I managed to get my hands\non some second-hand industrial computers, to do some bidding for me. Namely, I\npicked up some old SEL (Schweitzer Engineering Laboratories) SEL-1102 rugged\ncomputers. They're based on an old Intel x686 processor, and don't have anything\nspecial in the memory arena... but they're super solid machines.<\/p>\n<img alt=\"SEL Rugged Computers to Run my DevOps Pipeline\" src=\"https:\/\/blog.stanleysolutionsnw.com\/IMG_0849.jpg\" style=\"width: 600px;\" \/>\n<p>My comment about being a &quot;computer graveyard&quot; might still apply to these\ncomputers too, but well, they've got a lot more life left in them. You see,\nthese are ruggedized computers designed for installation into some of the most\nextreme environments around the world. Rated for harsh operating conditions,\nbuilt with no moving parts (that's right, a computer without fans), and a whole\nslew of serial ports (16 DB9 ports alone). SEL maintains a 10 worldwide warranty\ntoo; but I'll grant that this warranty is void because these devices were sold\nto me secondhand. I bring up this point, however because it really exemplifies\nthe commitment to quality that SEL brings to the table.<\/p>\n<p>Now, for those of you who know me well, you'll also know that I <em>work<\/em> for SEL.\nSo yeah, I do have some bias there; but I've also gotten to see (first-hand) the\nquality that we at SEL put into our products, so I'm very proud to have a few of\nthese machines running at home, and I'm very excited to put them into production.<\/p>\n<\/div>\n<div class=\"section\" id=\"the-new-work\">\n<h2>The new work<\/h2>\n<p>With these new servers, I'm excited to set them up running Debian (because, yeah,\nthey will do that - and very well, I might add) to support a Jenkins server. I\nplan to use that, and expose it as my primary integration system. With Jenkins\nrunning on these new machines, I'm going to set up a Pi Cluster to offload the\nactual pipeline work.<\/p>\n<p>But why?<\/p>\n<p>Well, I want the main Jenkins server to be just that... the main server. I want\nother machines to do all the &quot;dirty work&quot; for me.<\/p>\n<p>So, before you get too carried away with your thoughts; yes, that does mean more\ncomputers. I've already put in an order for a Raspberry Pi cluster, which I'm\nvery excited about; but that's another article for the near future.<\/p>\n<p>Part of this excitement also stems from my need to integrate with some SEL relays\nserially for testing with my SELProtoPy project. With all of those serial ports\non these computers, I'll be able to tie in to those relays quite nicely to allow\nsome really solid automated testing. Better yet, with all of that integration,\nI'll be able to do some really nice pipelined builds for testing SELProtoPy and\nPyCEV.<\/p>\n<\/div>\n<div class=\"section\" id=\"what-s-next\">\n<h2>What's next?<\/h2>\n<p>Well, next on my plate is to get these machines up and running on my network so\nthat I can access them remotely and start integrating with GitHub actions to\nfire off the builds and testing.<\/p>\n<p>I'm very excited to be putting some SEL equipment to work in my own personal\ndevelopment practices, so I'm sure I'll have some more updates as I go along!<\/p>\n<img alt=\"Putting some SEL Hardware to Work\" src=\"https:\/\/blog.stanleysolutionsnw.com\/IMG_0850.jpg\" style=\"width: 600px;\" \/>\n<\/div>\n","category":[{"@attributes":{"term":"DevOps"}},{"@attributes":{"term":"sel"}},{"@attributes":{"term":"industrial"}},{"@attributes":{"term":"rugged computer"}},{"@attributes":{"term":"ci\/cd"}},{"@attributes":{"term":"development"}},{"@attributes":{"term":"server"}}]}]}